widget/windows/nsLookAndFeel.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/widget/windows/nsLookAndFeel.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,678 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsLookAndFeel.h"
    1.10 +#include <windows.h>
    1.11 +#include <shellapi.h>
    1.12 +#include "nsStyleConsts.h"
    1.13 +#include "nsUXThemeData.h"
    1.14 +#include "nsUXThemeConstants.h"
    1.15 +#include "gfxFont.h"
    1.16 +#include "gfxWindowsPlatform.h"
    1.17 +#include "mozilla/Telemetry.h"
    1.18 +#include "mozilla/WindowsVersion.h"
    1.19 +#include "gfxFontConstants.h"
    1.20 +
    1.21 +using namespace mozilla;
    1.22 +using namespace mozilla::widget;
    1.23 +
    1.24 +//static
    1.25 +LookAndFeel::OperatingSystemVersion
    1.26 +nsLookAndFeel::GetOperatingSystemVersion()
    1.27 +{
    1.28 +  static OperatingSystemVersion version = eOperatingSystemVersion_Unknown;
    1.29 +
    1.30 +  if (version != eOperatingSystemVersion_Unknown) {
    1.31 +    return version;
    1.32 +  }
    1.33 +
    1.34 +  if (IsWin8OrLater()) {
    1.35 +    version = eOperatingSystemVersion_Windows8;
    1.36 +  } else if (IsWin7OrLater()) {
    1.37 +    version = eOperatingSystemVersion_Windows7;
    1.38 +  } else if (IsVistaOrLater()) {
    1.39 +    version = eOperatingSystemVersion_WindowsVista;
    1.40 +  } else {
    1.41 +    version = eOperatingSystemVersion_WindowsXP;
    1.42 +  }
    1.43 +
    1.44 +  return version;
    1.45 +}
    1.46 +
    1.47 +static nsresult GetColorFromTheme(nsUXThemeClass cls,
    1.48 +                           int32_t aPart,
    1.49 +                           int32_t aState,
    1.50 +                           int32_t aPropId,
    1.51 +                           nscolor &aColor)
    1.52 +{
    1.53 +  COLORREF color;
    1.54 +  HRESULT hr = GetThemeColor(nsUXThemeData::GetTheme(cls), aPart, aState, aPropId, &color);
    1.55 +  if (hr == S_OK)
    1.56 +  {
    1.57 +    aColor = COLOREF_2_NSRGB(color);
    1.58 +    return NS_OK;
    1.59 +  }
    1.60 +  return NS_ERROR_FAILURE;
    1.61 +}
    1.62 +
    1.63 +static int32_t GetSystemParam(long flag, int32_t def)
    1.64 +{
    1.65 +    DWORD value; 
    1.66 +    return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
    1.67 +}
    1.68 +
    1.69 +namespace mozilla {
    1.70 +namespace widget {
    1.71 +// This is in use here and in dom/events/TouchEvent.cpp
    1.72 +int32_t IsTouchDeviceSupportPresent()
    1.73 +{
    1.74 +  int32_t touchCapabilities;
    1.75 +  touchCapabilities = ::GetSystemMetrics(SM_DIGITIZER);
    1.76 +  return ((touchCapabilities & NID_READY) && 
    1.77 +          (touchCapabilities & (NID_EXTERNAL_TOUCH | NID_INTEGRATED_TOUCH)));
    1.78 +}
    1.79 +} }
    1.80 +
    1.81 +nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel()
    1.82 +{
    1.83 +  mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE,
    1.84 +                                 IsTouchDeviceSupportPresent());
    1.85 +}
    1.86 +
    1.87 +nsLookAndFeel::~nsLookAndFeel()
    1.88 +{
    1.89 +}
    1.90 +
    1.91 +nsresult
    1.92 +nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor)
    1.93 +{
    1.94 +  nsresult res = NS_OK;
    1.95 +
    1.96 +  int idx;
    1.97 +  switch (aID) {
    1.98 +    case eColorID_WindowBackground:
    1.99 +        idx = COLOR_WINDOW;
   1.100 +        break;
   1.101 +    case eColorID_WindowForeground:
   1.102 +        idx = COLOR_WINDOWTEXT;
   1.103 +        break;
   1.104 +    case eColorID_WidgetBackground:
   1.105 +        idx = COLOR_BTNFACE;
   1.106 +        break;
   1.107 +    case eColorID_WidgetForeground:
   1.108 +        idx = COLOR_BTNTEXT;
   1.109 +        break;
   1.110 +    case eColorID_WidgetSelectBackground:
   1.111 +        idx = COLOR_HIGHLIGHT;
   1.112 +        break;
   1.113 +    case eColorID_WidgetSelectForeground:
   1.114 +        idx = COLOR_HIGHLIGHTTEXT;
   1.115 +        break;
   1.116 +    case eColorID_Widget3DHighlight:
   1.117 +        idx = COLOR_BTNHIGHLIGHT;
   1.118 +        break;
   1.119 +    case eColorID_Widget3DShadow:
   1.120 +        idx = COLOR_BTNSHADOW;
   1.121 +        break;
   1.122 +    case eColorID_TextBackground:
   1.123 +        idx = COLOR_WINDOW;
   1.124 +        break;
   1.125 +    case eColorID_TextForeground:
   1.126 +        idx = COLOR_WINDOWTEXT;
   1.127 +        break;
   1.128 +    case eColorID_TextSelectBackground:
   1.129 +    case eColorID_IMESelectedRawTextBackground:
   1.130 +    case eColorID_IMESelectedConvertedTextBackground:
   1.131 +        idx = COLOR_HIGHLIGHT;
   1.132 +        break;
   1.133 +    case eColorID_TextSelectForeground:
   1.134 +    case eColorID_IMESelectedRawTextForeground:
   1.135 +    case eColorID_IMESelectedConvertedTextForeground:
   1.136 +        idx = COLOR_HIGHLIGHTTEXT;
   1.137 +        break;
   1.138 +    case eColorID_IMERawInputBackground:
   1.139 +    case eColorID_IMEConvertedTextBackground:
   1.140 +        aColor = NS_TRANSPARENT;
   1.141 +        return NS_OK;
   1.142 +    case eColorID_IMERawInputForeground:
   1.143 +    case eColorID_IMEConvertedTextForeground:
   1.144 +        aColor = NS_SAME_AS_FOREGROUND_COLOR;
   1.145 +        return NS_OK;
   1.146 +    case eColorID_IMERawInputUnderline:
   1.147 +    case eColorID_IMEConvertedTextUnderline:
   1.148 +        aColor = NS_SAME_AS_FOREGROUND_COLOR;
   1.149 +        return NS_OK;
   1.150 +    case eColorID_IMESelectedRawTextUnderline:
   1.151 +    case eColorID_IMESelectedConvertedTextUnderline:
   1.152 +        aColor = NS_TRANSPARENT;
   1.153 +        return NS_OK;
   1.154 +    case eColorID_SpellCheckerUnderline:
   1.155 +        aColor = NS_RGB(0xff, 0, 0);
   1.156 +        return NS_OK;
   1.157 +
   1.158 +    // New CSS 2 Color definitions
   1.159 +    case eColorID_activeborder:
   1.160 +      idx = COLOR_ACTIVEBORDER;
   1.161 +      break;
   1.162 +    case eColorID_activecaption:
   1.163 +      idx = COLOR_ACTIVECAPTION;
   1.164 +      break;
   1.165 +    case eColorID_appworkspace:
   1.166 +      idx = COLOR_APPWORKSPACE;
   1.167 +      break;
   1.168 +    case eColorID_background:
   1.169 +      idx = COLOR_BACKGROUND;
   1.170 +      break;
   1.171 +    case eColorID_buttonface:
   1.172 +    case eColorID__moz_buttonhoverface:
   1.173 +      idx = COLOR_BTNFACE;
   1.174 +      break;
   1.175 +    case eColorID_buttonhighlight:
   1.176 +      idx = COLOR_BTNHIGHLIGHT;
   1.177 +      break;
   1.178 +    case eColorID_buttonshadow:
   1.179 +      idx = COLOR_BTNSHADOW;
   1.180 +      break;
   1.181 +    case eColorID_buttontext:
   1.182 +    case eColorID__moz_buttonhovertext:
   1.183 +      idx = COLOR_BTNTEXT;
   1.184 +      break;
   1.185 +    case eColorID_captiontext:
   1.186 +      idx = COLOR_CAPTIONTEXT;
   1.187 +      break;
   1.188 +    case eColorID_graytext:
   1.189 +      idx = COLOR_GRAYTEXT;
   1.190 +      break;
   1.191 +    case eColorID_highlight:
   1.192 +    case eColorID__moz_html_cellhighlight:
   1.193 +    case eColorID__moz_menuhover:
   1.194 +      idx = COLOR_HIGHLIGHT;
   1.195 +      break;
   1.196 +    case eColorID__moz_menubarhovertext:
   1.197 +      if (!IsVistaOrLater() || !IsAppThemed())
   1.198 +      {
   1.199 +        idx = nsUXThemeData::sFlatMenus ?
   1.200 +                COLOR_HIGHLIGHTTEXT :
   1.201 +                COLOR_MENUTEXT;
   1.202 +        break;
   1.203 +      }
   1.204 +      // Fall through
   1.205 +    case eColorID__moz_menuhovertext:
   1.206 +      if (IsVistaOrLater() && IsAppThemed())
   1.207 +      {
   1.208 +        res = ::GetColorFromTheme(eUXMenu,
   1.209 +                                  MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor);
   1.210 +        if (NS_SUCCEEDED(res))
   1.211 +          return res;
   1.212 +        // fall through to highlight case
   1.213 +      }
   1.214 +    case eColorID_highlighttext:
   1.215 +    case eColorID__moz_html_cellhighlighttext:
   1.216 +      idx = COLOR_HIGHLIGHTTEXT;
   1.217 +      break;
   1.218 +    case eColorID_inactiveborder:
   1.219 +      idx = COLOR_INACTIVEBORDER;
   1.220 +      break;
   1.221 +    case eColorID_inactivecaption:
   1.222 +      idx = COLOR_INACTIVECAPTION;
   1.223 +      break;
   1.224 +    case eColorID_inactivecaptiontext:
   1.225 +      idx = COLOR_INACTIVECAPTIONTEXT;
   1.226 +      break;
   1.227 +    case eColorID_infobackground:
   1.228 +      idx = COLOR_INFOBK;
   1.229 +      break;
   1.230 +    case eColorID_infotext:
   1.231 +      idx = COLOR_INFOTEXT;
   1.232 +      break;
   1.233 +    case eColorID_menu:
   1.234 +      idx = COLOR_MENU;
   1.235 +      break;
   1.236 +    case eColorID_menutext:
   1.237 +    case eColorID__moz_menubartext:
   1.238 +      idx = COLOR_MENUTEXT;
   1.239 +      break;
   1.240 +    case eColorID_scrollbar:
   1.241 +      idx = COLOR_SCROLLBAR;
   1.242 +      break;
   1.243 +    case eColorID_threeddarkshadow:
   1.244 +      idx = COLOR_3DDKSHADOW;
   1.245 +      break;
   1.246 +    case eColorID_threedface:
   1.247 +      idx = COLOR_3DFACE;
   1.248 +      break;
   1.249 +    case eColorID_threedhighlight:
   1.250 +      idx = COLOR_3DHIGHLIGHT;
   1.251 +      break;
   1.252 +    case eColorID_threedlightshadow:
   1.253 +      idx = COLOR_3DLIGHT;
   1.254 +      break;
   1.255 +    case eColorID_threedshadow:
   1.256 +      idx = COLOR_3DSHADOW;
   1.257 +      break;
   1.258 +    case eColorID_window:
   1.259 +      idx = COLOR_WINDOW;
   1.260 +      break;
   1.261 +    case eColorID_windowframe:
   1.262 +      idx = COLOR_WINDOWFRAME;
   1.263 +      break;
   1.264 +    case eColorID_windowtext:
   1.265 +      idx = COLOR_WINDOWTEXT;
   1.266 +      break;
   1.267 +    case eColorID__moz_eventreerow:
   1.268 +    case eColorID__moz_oddtreerow:
   1.269 +    case eColorID__moz_field:
   1.270 +    case eColorID__moz_combobox:
   1.271 +      idx = COLOR_WINDOW;
   1.272 +      break;
   1.273 +    case eColorID__moz_fieldtext:
   1.274 +    case eColorID__moz_comboboxtext:
   1.275 +      idx = COLOR_WINDOWTEXT;
   1.276 +      break;
   1.277 +    case eColorID__moz_dialog:
   1.278 +    case eColorID__moz_cellhighlight:
   1.279 +      idx = COLOR_3DFACE;
   1.280 +      break;
   1.281 +    case eColorID__moz_win_mediatext:
   1.282 +      if (IsVistaOrLater() && IsAppThemed()) {
   1.283 +        res = ::GetColorFromTheme(eUXMediaToolbar,
   1.284 +                                  TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
   1.285 +        if (NS_SUCCEEDED(res))
   1.286 +          return res;
   1.287 +      }
   1.288 +      // if we've gotten here just return -moz-dialogtext instead
   1.289 +      idx = COLOR_WINDOWTEXT;
   1.290 +      break;
   1.291 +    case eColorID__moz_win_communicationstext:
   1.292 +      if (IsVistaOrLater() && IsAppThemed())
   1.293 +      {
   1.294 +        res = ::GetColorFromTheme(eUXCommunicationsToolbar,
   1.295 +                                  TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor);
   1.296 +        if (NS_SUCCEEDED(res))
   1.297 +          return res;
   1.298 +      }
   1.299 +      // if we've gotten here just return -moz-dialogtext instead
   1.300 +      idx = COLOR_WINDOWTEXT;
   1.301 +      break;
   1.302 +    case eColorID__moz_dialogtext:
   1.303 +    case eColorID__moz_cellhighlighttext:
   1.304 +      idx = COLOR_WINDOWTEXT;
   1.305 +      break;
   1.306 +    case eColorID__moz_dragtargetzone:
   1.307 +      idx = COLOR_HIGHLIGHTTEXT;
   1.308 +      break;
   1.309 +    case eColorID__moz_buttondefault:
   1.310 +      idx = COLOR_3DDKSHADOW;
   1.311 +      break;
   1.312 +    case eColorID__moz_nativehyperlinktext:
   1.313 +      idx = COLOR_HOTLIGHT;
   1.314 +      break;
   1.315 +    default:
   1.316 +      idx = COLOR_WINDOW;
   1.317 +      break;
   1.318 +    }
   1.319 +
   1.320 +  DWORD color = ::GetSysColor(idx);
   1.321 +  aColor = COLOREF_2_NSRGB(color);
   1.322 +
   1.323 +  return res;
   1.324 +}
   1.325 +
   1.326 +nsresult
   1.327 +nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
   1.328 +{
   1.329 +  nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
   1.330 +  if (NS_SUCCEEDED(res))
   1.331 +    return res;
   1.332 +  res = NS_OK;
   1.333 +
   1.334 +  switch (aID) {
   1.335 +    case eIntID_CaretBlinkTime:
   1.336 +        aResult = (int32_t)::GetCaretBlinkTime();
   1.337 +        break;
   1.338 +    case eIntID_CaretWidth:
   1.339 +        aResult = 1;
   1.340 +        break;
   1.341 +    case eIntID_ShowCaretDuringSelection:
   1.342 +        aResult = 0;
   1.343 +        break;
   1.344 +    case eIntID_SelectTextfieldsOnKeyFocus:
   1.345 +        // Select textfield content when focused by kbd
   1.346 +        // used by EventStateManager::sTextfieldSelectModel
   1.347 +        aResult = 1;
   1.348 +        break;
   1.349 +    case eIntID_SubmenuDelay:
   1.350 +        // This will default to the Windows' default
   1.351 +        // (400ms) on error.
   1.352 +        aResult = GetSystemParam(SPI_GETMENUSHOWDELAY, 400);
   1.353 +        break;
   1.354 +    case eIntID_TooltipDelay:
   1.355 +        aResult = 500;
   1.356 +        break;
   1.357 +    case eIntID_MenusCanOverlapOSBar:
   1.358 +        // we want XUL popups to be able to overlap the task bar.
   1.359 +        aResult = 1;
   1.360 +        break;
   1.361 +    case eIntID_DragThresholdX:
   1.362 +        // The system metric is the number of pixels at which a drag should
   1.363 +        // start.  Our look and feel metric is the number of pixels you can
   1.364 +        // move before starting a drag, so subtract 1.
   1.365 +
   1.366 +        aResult = ::GetSystemMetrics(SM_CXDRAG) - 1;
   1.367 +        break;
   1.368 +    case eIntID_DragThresholdY:
   1.369 +        aResult = ::GetSystemMetrics(SM_CYDRAG) - 1;
   1.370 +        break;
   1.371 +    case eIntID_UseAccessibilityTheme:
   1.372 +        // High contrast is a misnomer under Win32 -- any theme can be used with it, 
   1.373 +        // e.g. normal contrast with large fonts, low contrast, etc.
   1.374 +        // The high contrast flag really means -- use this theme and don't override it.
   1.375 +        aResult = nsUXThemeData::IsHighContrastOn();
   1.376 +        break;
   1.377 +    case eIntID_ScrollArrowStyle:
   1.378 +        aResult = eScrollArrowStyle_Single;
   1.379 +        break;
   1.380 +    case eIntID_ScrollSliderStyle:
   1.381 +        aResult = eScrollThumbStyle_Proportional;
   1.382 +        break;
   1.383 +    case eIntID_TreeOpenDelay:
   1.384 +        aResult = 1000;
   1.385 +        break;
   1.386 +    case eIntID_TreeCloseDelay:
   1.387 +        aResult = 0;
   1.388 +        break;
   1.389 +    case eIntID_TreeLazyScrollDelay:
   1.390 +        aResult = 150;
   1.391 +        break;
   1.392 +    case eIntID_TreeScrollDelay:
   1.393 +        aResult = 100;
   1.394 +        break;
   1.395 +    case eIntID_TreeScrollLinesMax:
   1.396 +        aResult = 3;
   1.397 +        break;
   1.398 +    case eIntID_WindowsClassic:
   1.399 +        aResult = !IsAppThemed();
   1.400 +        break;
   1.401 +    case eIntID_TouchEnabled:
   1.402 +        aResult = IsTouchDeviceSupportPresent();
   1.403 +        break;
   1.404 +    case eIntID_WindowsDefaultTheme:
   1.405 +        aResult = nsUXThemeData::IsDefaultWindowTheme();
   1.406 +        break;
   1.407 +    case eIntID_WindowsThemeIdentifier:
   1.408 +        aResult = nsUXThemeData::GetNativeThemeId();
   1.409 +        break;
   1.410 +
   1.411 +    case eIntID_OperatingSystemVersionIdentifier:
   1.412 +    {
   1.413 +        aResult = GetOperatingSystemVersion();
   1.414 +        break;
   1.415 +    }
   1.416 +
   1.417 +    case eIntID_MacGraphiteTheme:
   1.418 +    case eIntID_MacLionTheme:
   1.419 +        aResult = 0;
   1.420 +        res = NS_ERROR_NOT_IMPLEMENTED;
   1.421 +        break;
   1.422 +    case eIntID_DWMCompositor:
   1.423 +        aResult = nsUXThemeData::CheckForCompositor();
   1.424 +        break;
   1.425 +    case eIntID_WindowsGlass:
   1.426 +        // Aero Glass is only available prior to Windows 8 when DWM is used.
   1.427 +        aResult = (nsUXThemeData::CheckForCompositor() && !IsWin8OrLater());
   1.428 +        break;
   1.429 +    case eIntID_AlertNotificationOrigin:
   1.430 +        aResult = 0;
   1.431 +        {
   1.432 +          // Get task bar window handle
   1.433 +          HWND shellWindow = FindWindowW(L"Shell_TrayWnd", nullptr);
   1.434 +
   1.435 +          if (shellWindow != nullptr)
   1.436 +          {
   1.437 +            // Determine position
   1.438 +            APPBARDATA appBarData;
   1.439 +            appBarData.hWnd = shellWindow;
   1.440 +            appBarData.cbSize = sizeof(appBarData);
   1.441 +            if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData))
   1.442 +            {
   1.443 +              // Set alert origin as a bit field - see LookAndFeel.h
   1.444 +              // 0 represents bottom right, sliding vertically.
   1.445 +              switch(appBarData.uEdge)
   1.446 +              {
   1.447 +                case ABE_LEFT:
   1.448 +                  aResult = NS_ALERT_HORIZONTAL | NS_ALERT_LEFT;
   1.449 +                  break;
   1.450 +                case ABE_RIGHT:
   1.451 +                  aResult = NS_ALERT_HORIZONTAL;
   1.452 +                  break;
   1.453 +                case ABE_TOP:
   1.454 +                  aResult = NS_ALERT_TOP;
   1.455 +                  // fall through for the right-to-left handling.
   1.456 +                case ABE_BOTTOM:
   1.457 +                  // If the task bar is right-to-left,
   1.458 +                  // move the origin to the left
   1.459 +                  if (::GetWindowLong(shellWindow, GWL_EXSTYLE) &
   1.460 +                        WS_EX_LAYOUTRTL)
   1.461 +                    aResult |= NS_ALERT_LEFT;
   1.462 +                  break;
   1.463 +              }
   1.464 +            }
   1.465 +          }
   1.466 +        }
   1.467 +        break;
   1.468 +    case eIntID_IMERawInputUnderlineStyle:
   1.469 +    case eIntID_IMEConvertedTextUnderlineStyle:
   1.470 +        aResult = NS_STYLE_TEXT_DECORATION_STYLE_DASHED;
   1.471 +        break;
   1.472 +    case eIntID_IMESelectedRawTextUnderlineStyle:
   1.473 +    case eIntID_IMESelectedConvertedTextUnderline:
   1.474 +        aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE;
   1.475 +        break;
   1.476 +    case eIntID_SpellCheckerUnderlineStyle:
   1.477 +        aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
   1.478 +        break;
   1.479 +    case eIntID_ScrollbarButtonAutoRepeatBehavior:
   1.480 +        aResult = 0;
   1.481 +        break;
   1.482 +    case eIntID_SwipeAnimationEnabled:
   1.483 +        aResult = 0;
   1.484 +        break;
   1.485 +    case eIntID_ColorPickerAvailable:
   1.486 +        // We don't have a color picker implemented on Metro yet (bug 895464)
   1.487 +        aResult = (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro);
   1.488 +        break;
   1.489 +    case eIntID_UseOverlayScrollbars:
   1.490 +        aResult = (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro);
   1.491 +        break;
   1.492 +    case eIntID_AllowOverlayScrollbarsOverlap:
   1.493 +        aResult = 0;
   1.494 +        break;
   1.495 +    case eIntID_ScrollbarDisplayOnMouseMove:
   1.496 +        aResult = 1;
   1.497 +        break;
   1.498 +    case eIntID_ScrollbarFadeBeginDelay:
   1.499 +        aResult = 2500;
   1.500 +        break;
   1.501 +    case eIntID_ScrollbarFadeDuration:
   1.502 +        aResult = 350;
   1.503 +        break;
   1.504 +    default:
   1.505 +        aResult = 0;
   1.506 +        res = NS_ERROR_FAILURE;
   1.507 +    }
   1.508 +  return res;
   1.509 +}
   1.510 +
   1.511 +nsresult
   1.512 +nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
   1.513 +{
   1.514 +  nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
   1.515 +  if (NS_SUCCEEDED(res))
   1.516 +    return res;
   1.517 +  res = NS_OK;
   1.518 +
   1.519 +  switch (aID) {
   1.520 +    case eFloatID_IMEUnderlineRelativeSize:
   1.521 +        aResult = 1.0f;
   1.522 +        break;
   1.523 +    case eFloatID_SpellCheckerUnderlineRelativeSize:
   1.524 +        aResult = 1.0f;
   1.525 +        break;
   1.526 +    default:
   1.527 +        aResult = -1.0;
   1.528 +        res = NS_ERROR_FAILURE;
   1.529 +    }
   1.530 +  return res;
   1.531 +}
   1.532 +
   1.533 +static bool
   1.534 +GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
   1.535 +               nsString &aFontName,
   1.536 +               gfxFontStyle &aFontStyle)
   1.537 +{
   1.538 +  LOGFONTW* ptrLogFont = nullptr;
   1.539 +  LOGFONTW logFont;
   1.540 +  NONCLIENTMETRICSW ncm;
   1.541 +  HGDIOBJ hGDI;
   1.542 +  char16_t name[LF_FACESIZE];
   1.543 +
   1.544 +  // Depending on which stock font we want, there are three different
   1.545 +  // places we might have to look it up.
   1.546 +  switch (anID) {
   1.547 +  case LookAndFeel::eFont_Icon:
   1.548 +    if (!::SystemParametersInfoW(SPI_GETICONTITLELOGFONT,
   1.549 +                                 sizeof(logFont), (PVOID)&logFont, 0))
   1.550 +      return false;
   1.551 +
   1.552 +    ptrLogFont = &logFont;
   1.553 +    break;
   1.554 +
   1.555 +  case LookAndFeel::eFont_Menu:
   1.556 +  case LookAndFeel::eFont_MessageBox:
   1.557 +  case LookAndFeel::eFont_SmallCaption:
   1.558 +  case LookAndFeel::eFont_StatusBar:
   1.559 +  case LookAndFeel::eFont_Tooltips:
   1.560 +    ncm.cbSize = sizeof(NONCLIENTMETRICSW);
   1.561 +    if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
   1.562 +                                 sizeof(ncm), (PVOID)&ncm, 0))
   1.563 +      return false;
   1.564 +
   1.565 +    switch (anID) {
   1.566 +    case LookAndFeel::eFont_Menu:
   1.567 +      ptrLogFont = &ncm.lfMenuFont;
   1.568 +      break;
   1.569 +    case LookAndFeel::eFont_MessageBox:
   1.570 +      ptrLogFont = &ncm.lfMessageFont;
   1.571 +      break;
   1.572 +    case LookAndFeel::eFont_SmallCaption:
   1.573 +      ptrLogFont = &ncm.lfSmCaptionFont;
   1.574 +      break;
   1.575 +    case LookAndFeel::eFont_StatusBar:
   1.576 +    case LookAndFeel::eFont_Tooltips:
   1.577 +      ptrLogFont = &ncm.lfStatusFont;
   1.578 +      break;
   1.579 +    }
   1.580 +    break;
   1.581 +
   1.582 +  case LookAndFeel::eFont_Widget:
   1.583 +  case LookAndFeel::eFont_Window:      // css3
   1.584 +  case LookAndFeel::eFont_Document:
   1.585 +  case LookAndFeel::eFont_Workspace:
   1.586 +  case LookAndFeel::eFont_Desktop:
   1.587 +  case LookAndFeel::eFont_Info:
   1.588 +  case LookAndFeel::eFont_Dialog:
   1.589 +  case LookAndFeel::eFont_Button:
   1.590 +  case LookAndFeel::eFont_PullDownMenu:
   1.591 +  case LookAndFeel::eFont_List:
   1.592 +  case LookAndFeel::eFont_Field:
   1.593 +  case LookAndFeel::eFont_Caption:
   1.594 +    hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
   1.595 +    if (!hGDI)
   1.596 +      return false;
   1.597 +
   1.598 +    if (::GetObjectW(hGDI, sizeof(logFont), &logFont) <= 0)
   1.599 +      return false;
   1.600 +
   1.601 +    ptrLogFont = &logFont;
   1.602 +    break;
   1.603 +  }
   1.604 +
   1.605 +  // Get scaling factor from physical to logical pixels
   1.606 +  float pixelScale = 1.0f / gfxWindowsPlatform::GetPlatform()->GetDPIScale();
   1.607 +
   1.608 +  // The lfHeight is in pixels, and it needs to be adjusted for the
   1.609 +  // device it will be displayed on.
   1.610 +  // Screens and Printers will differ in DPI
   1.611 +  //
   1.612 +  // So this accounts for the difference in the DeviceContexts
   1.613 +  // The pixelScale will typically be 1.0 for the screen
   1.614 +  // (though larger for hi-dpi screens where the Windows resolution
   1.615 +  // scale factor is 125% or 150% or even more), and could be
   1.616 +  // any value when going to a printer, for example pixelScale is
   1.617 +  // 6.25 when going to a 600dpi printer.
   1.618 +  float pixelHeight = -ptrLogFont->lfHeight;
   1.619 +  if (pixelHeight < 0) {
   1.620 +    HFONT hFont = ::CreateFontIndirectW(ptrLogFont);
   1.621 +    if (!hFont)
   1.622 +      return false;
   1.623 +    HGDIOBJ hObject = ::SelectObject(aHDC, hFont);
   1.624 +    TEXTMETRIC tm;
   1.625 +    ::GetTextMetrics(aHDC, &tm);
   1.626 +    ::SelectObject(aHDC, hObject);
   1.627 +    ::DeleteObject(hFont);
   1.628 +    pixelHeight = tm.tmAscent;
   1.629 +  }
   1.630 +  pixelHeight *= pixelScale;
   1.631 +
   1.632 +  // we have problem on Simplified Chinese system because the system
   1.633 +  // report the default font size is 8 points. but if we use 8, the text
   1.634 +  // display very ugly. force it to be at 9 points (12 pixels) on that
   1.635 +  // system (cp936), but leave other sizes alone.
   1.636 +  if (pixelHeight < 12 && ::GetACP() == 936)
   1.637 +    pixelHeight = 12;
   1.638 +
   1.639 +  aFontStyle.size = pixelHeight;
   1.640 +
   1.641 +  // FIXME: What about oblique?
   1.642 +  aFontStyle.style =
   1.643 +    (ptrLogFont->lfItalic) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL;
   1.644 +
   1.645 +  // FIXME: Other weights?
   1.646 +  aFontStyle.weight =
   1.647 +    (ptrLogFont->lfWeight == FW_BOLD ?
   1.648 +        NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL);
   1.649 +
   1.650 +  // FIXME: Set aFontStyle->stretch correctly!
   1.651 +  aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
   1.652 +
   1.653 +  aFontStyle.systemFont = true;
   1.654 +
   1.655 +  name[0] = 0;
   1.656 +  memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t));
   1.657 +  aFontName = name;
   1.658 +
   1.659 +  return true;
   1.660 +}
   1.661 +
   1.662 +bool
   1.663 +nsLookAndFeel::GetFontImpl(FontID anID, nsString &aFontName,
   1.664 +                           gfxFontStyle &aFontStyle,
   1.665 +                           float aDevPixPerCSSPixel)
   1.666 +{
   1.667 +  HDC tdc = GetDC(nullptr);
   1.668 +  bool status = GetSysFontInfo(tdc, anID, aFontName, aFontStyle);
   1.669 +  ReleaseDC(nullptr, tdc);
   1.670 +  // now convert the logical font size from GetSysFontInfo into device pixels for layout
   1.671 +  aFontStyle.size *= aDevPixPerCSSPixel;
   1.672 +  return status;
   1.673 +}
   1.674 +
   1.675 +/* virtual */
   1.676 +char16_t
   1.677 +nsLookAndFeel::GetPasswordCharacterImpl()
   1.678 +{
   1.679 +#define UNICODE_BLACK_CIRCLE_CHAR 0x25cf
   1.680 +  return UNICODE_BLACK_CIRCLE_CHAR;
   1.681 +}

mercurial