|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsLookAndFeel.h" |
|
7 #include <windows.h> |
|
8 #include <shellapi.h> |
|
9 #include "nsStyleConsts.h" |
|
10 #include "nsUXThemeData.h" |
|
11 #include "nsUXThemeConstants.h" |
|
12 #include "gfxFont.h" |
|
13 #include "gfxWindowsPlatform.h" |
|
14 #include "mozilla/Telemetry.h" |
|
15 #include "mozilla/WindowsVersion.h" |
|
16 #include "gfxFontConstants.h" |
|
17 |
|
18 using namespace mozilla; |
|
19 using namespace mozilla::widget; |
|
20 |
|
21 //static |
|
22 LookAndFeel::OperatingSystemVersion |
|
23 nsLookAndFeel::GetOperatingSystemVersion() |
|
24 { |
|
25 static OperatingSystemVersion version = eOperatingSystemVersion_Unknown; |
|
26 |
|
27 if (version != eOperatingSystemVersion_Unknown) { |
|
28 return version; |
|
29 } |
|
30 |
|
31 if (IsWin8OrLater()) { |
|
32 version = eOperatingSystemVersion_Windows8; |
|
33 } else if (IsWin7OrLater()) { |
|
34 version = eOperatingSystemVersion_Windows7; |
|
35 } else if (IsVistaOrLater()) { |
|
36 version = eOperatingSystemVersion_WindowsVista; |
|
37 } else { |
|
38 version = eOperatingSystemVersion_WindowsXP; |
|
39 } |
|
40 |
|
41 return version; |
|
42 } |
|
43 |
|
44 static nsresult GetColorFromTheme(nsUXThemeClass cls, |
|
45 int32_t aPart, |
|
46 int32_t aState, |
|
47 int32_t aPropId, |
|
48 nscolor &aColor) |
|
49 { |
|
50 COLORREF color; |
|
51 HRESULT hr = GetThemeColor(nsUXThemeData::GetTheme(cls), aPart, aState, aPropId, &color); |
|
52 if (hr == S_OK) |
|
53 { |
|
54 aColor = COLOREF_2_NSRGB(color); |
|
55 return NS_OK; |
|
56 } |
|
57 return NS_ERROR_FAILURE; |
|
58 } |
|
59 |
|
60 static int32_t GetSystemParam(long flag, int32_t def) |
|
61 { |
|
62 DWORD value; |
|
63 return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def; |
|
64 } |
|
65 |
|
66 namespace mozilla { |
|
67 namespace widget { |
|
68 // This is in use here and in dom/events/TouchEvent.cpp |
|
69 int32_t IsTouchDeviceSupportPresent() |
|
70 { |
|
71 int32_t touchCapabilities; |
|
72 touchCapabilities = ::GetSystemMetrics(SM_DIGITIZER); |
|
73 return ((touchCapabilities & NID_READY) && |
|
74 (touchCapabilities & (NID_EXTERNAL_TOUCH | NID_INTEGRATED_TOUCH))); |
|
75 } |
|
76 } } |
|
77 |
|
78 nsLookAndFeel::nsLookAndFeel() : nsXPLookAndFeel() |
|
79 { |
|
80 mozilla::Telemetry::Accumulate(mozilla::Telemetry::TOUCH_ENABLED_DEVICE, |
|
81 IsTouchDeviceSupportPresent()); |
|
82 } |
|
83 |
|
84 nsLookAndFeel::~nsLookAndFeel() |
|
85 { |
|
86 } |
|
87 |
|
88 nsresult |
|
89 nsLookAndFeel::NativeGetColor(ColorID aID, nscolor &aColor) |
|
90 { |
|
91 nsresult res = NS_OK; |
|
92 |
|
93 int idx; |
|
94 switch (aID) { |
|
95 case eColorID_WindowBackground: |
|
96 idx = COLOR_WINDOW; |
|
97 break; |
|
98 case eColorID_WindowForeground: |
|
99 idx = COLOR_WINDOWTEXT; |
|
100 break; |
|
101 case eColorID_WidgetBackground: |
|
102 idx = COLOR_BTNFACE; |
|
103 break; |
|
104 case eColorID_WidgetForeground: |
|
105 idx = COLOR_BTNTEXT; |
|
106 break; |
|
107 case eColorID_WidgetSelectBackground: |
|
108 idx = COLOR_HIGHLIGHT; |
|
109 break; |
|
110 case eColorID_WidgetSelectForeground: |
|
111 idx = COLOR_HIGHLIGHTTEXT; |
|
112 break; |
|
113 case eColorID_Widget3DHighlight: |
|
114 idx = COLOR_BTNHIGHLIGHT; |
|
115 break; |
|
116 case eColorID_Widget3DShadow: |
|
117 idx = COLOR_BTNSHADOW; |
|
118 break; |
|
119 case eColorID_TextBackground: |
|
120 idx = COLOR_WINDOW; |
|
121 break; |
|
122 case eColorID_TextForeground: |
|
123 idx = COLOR_WINDOWTEXT; |
|
124 break; |
|
125 case eColorID_TextSelectBackground: |
|
126 case eColorID_IMESelectedRawTextBackground: |
|
127 case eColorID_IMESelectedConvertedTextBackground: |
|
128 idx = COLOR_HIGHLIGHT; |
|
129 break; |
|
130 case eColorID_TextSelectForeground: |
|
131 case eColorID_IMESelectedRawTextForeground: |
|
132 case eColorID_IMESelectedConvertedTextForeground: |
|
133 idx = COLOR_HIGHLIGHTTEXT; |
|
134 break; |
|
135 case eColorID_IMERawInputBackground: |
|
136 case eColorID_IMEConvertedTextBackground: |
|
137 aColor = NS_TRANSPARENT; |
|
138 return NS_OK; |
|
139 case eColorID_IMERawInputForeground: |
|
140 case eColorID_IMEConvertedTextForeground: |
|
141 aColor = NS_SAME_AS_FOREGROUND_COLOR; |
|
142 return NS_OK; |
|
143 case eColorID_IMERawInputUnderline: |
|
144 case eColorID_IMEConvertedTextUnderline: |
|
145 aColor = NS_SAME_AS_FOREGROUND_COLOR; |
|
146 return NS_OK; |
|
147 case eColorID_IMESelectedRawTextUnderline: |
|
148 case eColorID_IMESelectedConvertedTextUnderline: |
|
149 aColor = NS_TRANSPARENT; |
|
150 return NS_OK; |
|
151 case eColorID_SpellCheckerUnderline: |
|
152 aColor = NS_RGB(0xff, 0, 0); |
|
153 return NS_OK; |
|
154 |
|
155 // New CSS 2 Color definitions |
|
156 case eColorID_activeborder: |
|
157 idx = COLOR_ACTIVEBORDER; |
|
158 break; |
|
159 case eColorID_activecaption: |
|
160 idx = COLOR_ACTIVECAPTION; |
|
161 break; |
|
162 case eColorID_appworkspace: |
|
163 idx = COLOR_APPWORKSPACE; |
|
164 break; |
|
165 case eColorID_background: |
|
166 idx = COLOR_BACKGROUND; |
|
167 break; |
|
168 case eColorID_buttonface: |
|
169 case eColorID__moz_buttonhoverface: |
|
170 idx = COLOR_BTNFACE; |
|
171 break; |
|
172 case eColorID_buttonhighlight: |
|
173 idx = COLOR_BTNHIGHLIGHT; |
|
174 break; |
|
175 case eColorID_buttonshadow: |
|
176 idx = COLOR_BTNSHADOW; |
|
177 break; |
|
178 case eColorID_buttontext: |
|
179 case eColorID__moz_buttonhovertext: |
|
180 idx = COLOR_BTNTEXT; |
|
181 break; |
|
182 case eColorID_captiontext: |
|
183 idx = COLOR_CAPTIONTEXT; |
|
184 break; |
|
185 case eColorID_graytext: |
|
186 idx = COLOR_GRAYTEXT; |
|
187 break; |
|
188 case eColorID_highlight: |
|
189 case eColorID__moz_html_cellhighlight: |
|
190 case eColorID__moz_menuhover: |
|
191 idx = COLOR_HIGHLIGHT; |
|
192 break; |
|
193 case eColorID__moz_menubarhovertext: |
|
194 if (!IsVistaOrLater() || !IsAppThemed()) |
|
195 { |
|
196 idx = nsUXThemeData::sFlatMenus ? |
|
197 COLOR_HIGHLIGHTTEXT : |
|
198 COLOR_MENUTEXT; |
|
199 break; |
|
200 } |
|
201 // Fall through |
|
202 case eColorID__moz_menuhovertext: |
|
203 if (IsVistaOrLater() && IsAppThemed()) |
|
204 { |
|
205 res = ::GetColorFromTheme(eUXMenu, |
|
206 MENU_POPUPITEM, MPI_HOT, TMT_TEXTCOLOR, aColor); |
|
207 if (NS_SUCCEEDED(res)) |
|
208 return res; |
|
209 // fall through to highlight case |
|
210 } |
|
211 case eColorID_highlighttext: |
|
212 case eColorID__moz_html_cellhighlighttext: |
|
213 idx = COLOR_HIGHLIGHTTEXT; |
|
214 break; |
|
215 case eColorID_inactiveborder: |
|
216 idx = COLOR_INACTIVEBORDER; |
|
217 break; |
|
218 case eColorID_inactivecaption: |
|
219 idx = COLOR_INACTIVECAPTION; |
|
220 break; |
|
221 case eColorID_inactivecaptiontext: |
|
222 idx = COLOR_INACTIVECAPTIONTEXT; |
|
223 break; |
|
224 case eColorID_infobackground: |
|
225 idx = COLOR_INFOBK; |
|
226 break; |
|
227 case eColorID_infotext: |
|
228 idx = COLOR_INFOTEXT; |
|
229 break; |
|
230 case eColorID_menu: |
|
231 idx = COLOR_MENU; |
|
232 break; |
|
233 case eColorID_menutext: |
|
234 case eColorID__moz_menubartext: |
|
235 idx = COLOR_MENUTEXT; |
|
236 break; |
|
237 case eColorID_scrollbar: |
|
238 idx = COLOR_SCROLLBAR; |
|
239 break; |
|
240 case eColorID_threeddarkshadow: |
|
241 idx = COLOR_3DDKSHADOW; |
|
242 break; |
|
243 case eColorID_threedface: |
|
244 idx = COLOR_3DFACE; |
|
245 break; |
|
246 case eColorID_threedhighlight: |
|
247 idx = COLOR_3DHIGHLIGHT; |
|
248 break; |
|
249 case eColorID_threedlightshadow: |
|
250 idx = COLOR_3DLIGHT; |
|
251 break; |
|
252 case eColorID_threedshadow: |
|
253 idx = COLOR_3DSHADOW; |
|
254 break; |
|
255 case eColorID_window: |
|
256 idx = COLOR_WINDOW; |
|
257 break; |
|
258 case eColorID_windowframe: |
|
259 idx = COLOR_WINDOWFRAME; |
|
260 break; |
|
261 case eColorID_windowtext: |
|
262 idx = COLOR_WINDOWTEXT; |
|
263 break; |
|
264 case eColorID__moz_eventreerow: |
|
265 case eColorID__moz_oddtreerow: |
|
266 case eColorID__moz_field: |
|
267 case eColorID__moz_combobox: |
|
268 idx = COLOR_WINDOW; |
|
269 break; |
|
270 case eColorID__moz_fieldtext: |
|
271 case eColorID__moz_comboboxtext: |
|
272 idx = COLOR_WINDOWTEXT; |
|
273 break; |
|
274 case eColorID__moz_dialog: |
|
275 case eColorID__moz_cellhighlight: |
|
276 idx = COLOR_3DFACE; |
|
277 break; |
|
278 case eColorID__moz_win_mediatext: |
|
279 if (IsVistaOrLater() && IsAppThemed()) { |
|
280 res = ::GetColorFromTheme(eUXMediaToolbar, |
|
281 TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor); |
|
282 if (NS_SUCCEEDED(res)) |
|
283 return res; |
|
284 } |
|
285 // if we've gotten here just return -moz-dialogtext instead |
|
286 idx = COLOR_WINDOWTEXT; |
|
287 break; |
|
288 case eColorID__moz_win_communicationstext: |
|
289 if (IsVistaOrLater() && IsAppThemed()) |
|
290 { |
|
291 res = ::GetColorFromTheme(eUXCommunicationsToolbar, |
|
292 TP_BUTTON, TS_NORMAL, TMT_TEXTCOLOR, aColor); |
|
293 if (NS_SUCCEEDED(res)) |
|
294 return res; |
|
295 } |
|
296 // if we've gotten here just return -moz-dialogtext instead |
|
297 idx = COLOR_WINDOWTEXT; |
|
298 break; |
|
299 case eColorID__moz_dialogtext: |
|
300 case eColorID__moz_cellhighlighttext: |
|
301 idx = COLOR_WINDOWTEXT; |
|
302 break; |
|
303 case eColorID__moz_dragtargetzone: |
|
304 idx = COLOR_HIGHLIGHTTEXT; |
|
305 break; |
|
306 case eColorID__moz_buttondefault: |
|
307 idx = COLOR_3DDKSHADOW; |
|
308 break; |
|
309 case eColorID__moz_nativehyperlinktext: |
|
310 idx = COLOR_HOTLIGHT; |
|
311 break; |
|
312 default: |
|
313 idx = COLOR_WINDOW; |
|
314 break; |
|
315 } |
|
316 |
|
317 DWORD color = ::GetSysColor(idx); |
|
318 aColor = COLOREF_2_NSRGB(color); |
|
319 |
|
320 return res; |
|
321 } |
|
322 |
|
323 nsresult |
|
324 nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult) |
|
325 { |
|
326 nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult); |
|
327 if (NS_SUCCEEDED(res)) |
|
328 return res; |
|
329 res = NS_OK; |
|
330 |
|
331 switch (aID) { |
|
332 case eIntID_CaretBlinkTime: |
|
333 aResult = (int32_t)::GetCaretBlinkTime(); |
|
334 break; |
|
335 case eIntID_CaretWidth: |
|
336 aResult = 1; |
|
337 break; |
|
338 case eIntID_ShowCaretDuringSelection: |
|
339 aResult = 0; |
|
340 break; |
|
341 case eIntID_SelectTextfieldsOnKeyFocus: |
|
342 // Select textfield content when focused by kbd |
|
343 // used by EventStateManager::sTextfieldSelectModel |
|
344 aResult = 1; |
|
345 break; |
|
346 case eIntID_SubmenuDelay: |
|
347 // This will default to the Windows' default |
|
348 // (400ms) on error. |
|
349 aResult = GetSystemParam(SPI_GETMENUSHOWDELAY, 400); |
|
350 break; |
|
351 case eIntID_TooltipDelay: |
|
352 aResult = 500; |
|
353 break; |
|
354 case eIntID_MenusCanOverlapOSBar: |
|
355 // we want XUL popups to be able to overlap the task bar. |
|
356 aResult = 1; |
|
357 break; |
|
358 case eIntID_DragThresholdX: |
|
359 // The system metric is the number of pixels at which a drag should |
|
360 // start. Our look and feel metric is the number of pixels you can |
|
361 // move before starting a drag, so subtract 1. |
|
362 |
|
363 aResult = ::GetSystemMetrics(SM_CXDRAG) - 1; |
|
364 break; |
|
365 case eIntID_DragThresholdY: |
|
366 aResult = ::GetSystemMetrics(SM_CYDRAG) - 1; |
|
367 break; |
|
368 case eIntID_UseAccessibilityTheme: |
|
369 // High contrast is a misnomer under Win32 -- any theme can be used with it, |
|
370 // e.g. normal contrast with large fonts, low contrast, etc. |
|
371 // The high contrast flag really means -- use this theme and don't override it. |
|
372 aResult = nsUXThemeData::IsHighContrastOn(); |
|
373 break; |
|
374 case eIntID_ScrollArrowStyle: |
|
375 aResult = eScrollArrowStyle_Single; |
|
376 break; |
|
377 case eIntID_ScrollSliderStyle: |
|
378 aResult = eScrollThumbStyle_Proportional; |
|
379 break; |
|
380 case eIntID_TreeOpenDelay: |
|
381 aResult = 1000; |
|
382 break; |
|
383 case eIntID_TreeCloseDelay: |
|
384 aResult = 0; |
|
385 break; |
|
386 case eIntID_TreeLazyScrollDelay: |
|
387 aResult = 150; |
|
388 break; |
|
389 case eIntID_TreeScrollDelay: |
|
390 aResult = 100; |
|
391 break; |
|
392 case eIntID_TreeScrollLinesMax: |
|
393 aResult = 3; |
|
394 break; |
|
395 case eIntID_WindowsClassic: |
|
396 aResult = !IsAppThemed(); |
|
397 break; |
|
398 case eIntID_TouchEnabled: |
|
399 aResult = IsTouchDeviceSupportPresent(); |
|
400 break; |
|
401 case eIntID_WindowsDefaultTheme: |
|
402 aResult = nsUXThemeData::IsDefaultWindowTheme(); |
|
403 break; |
|
404 case eIntID_WindowsThemeIdentifier: |
|
405 aResult = nsUXThemeData::GetNativeThemeId(); |
|
406 break; |
|
407 |
|
408 case eIntID_OperatingSystemVersionIdentifier: |
|
409 { |
|
410 aResult = GetOperatingSystemVersion(); |
|
411 break; |
|
412 } |
|
413 |
|
414 case eIntID_MacGraphiteTheme: |
|
415 case eIntID_MacLionTheme: |
|
416 aResult = 0; |
|
417 res = NS_ERROR_NOT_IMPLEMENTED; |
|
418 break; |
|
419 case eIntID_DWMCompositor: |
|
420 aResult = nsUXThemeData::CheckForCompositor(); |
|
421 break; |
|
422 case eIntID_WindowsGlass: |
|
423 // Aero Glass is only available prior to Windows 8 when DWM is used. |
|
424 aResult = (nsUXThemeData::CheckForCompositor() && !IsWin8OrLater()); |
|
425 break; |
|
426 case eIntID_AlertNotificationOrigin: |
|
427 aResult = 0; |
|
428 { |
|
429 // Get task bar window handle |
|
430 HWND shellWindow = FindWindowW(L"Shell_TrayWnd", nullptr); |
|
431 |
|
432 if (shellWindow != nullptr) |
|
433 { |
|
434 // Determine position |
|
435 APPBARDATA appBarData; |
|
436 appBarData.hWnd = shellWindow; |
|
437 appBarData.cbSize = sizeof(appBarData); |
|
438 if (SHAppBarMessage(ABM_GETTASKBARPOS, &appBarData)) |
|
439 { |
|
440 // Set alert origin as a bit field - see LookAndFeel.h |
|
441 // 0 represents bottom right, sliding vertically. |
|
442 switch(appBarData.uEdge) |
|
443 { |
|
444 case ABE_LEFT: |
|
445 aResult = NS_ALERT_HORIZONTAL | NS_ALERT_LEFT; |
|
446 break; |
|
447 case ABE_RIGHT: |
|
448 aResult = NS_ALERT_HORIZONTAL; |
|
449 break; |
|
450 case ABE_TOP: |
|
451 aResult = NS_ALERT_TOP; |
|
452 // fall through for the right-to-left handling. |
|
453 case ABE_BOTTOM: |
|
454 // If the task bar is right-to-left, |
|
455 // move the origin to the left |
|
456 if (::GetWindowLong(shellWindow, GWL_EXSTYLE) & |
|
457 WS_EX_LAYOUTRTL) |
|
458 aResult |= NS_ALERT_LEFT; |
|
459 break; |
|
460 } |
|
461 } |
|
462 } |
|
463 } |
|
464 break; |
|
465 case eIntID_IMERawInputUnderlineStyle: |
|
466 case eIntID_IMEConvertedTextUnderlineStyle: |
|
467 aResult = NS_STYLE_TEXT_DECORATION_STYLE_DASHED; |
|
468 break; |
|
469 case eIntID_IMESelectedRawTextUnderlineStyle: |
|
470 case eIntID_IMESelectedConvertedTextUnderline: |
|
471 aResult = NS_STYLE_TEXT_DECORATION_STYLE_NONE; |
|
472 break; |
|
473 case eIntID_SpellCheckerUnderlineStyle: |
|
474 aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY; |
|
475 break; |
|
476 case eIntID_ScrollbarButtonAutoRepeatBehavior: |
|
477 aResult = 0; |
|
478 break; |
|
479 case eIntID_SwipeAnimationEnabled: |
|
480 aResult = 0; |
|
481 break; |
|
482 case eIntID_ColorPickerAvailable: |
|
483 // We don't have a color picker implemented on Metro yet (bug 895464) |
|
484 aResult = (XRE_GetWindowsEnvironment() != WindowsEnvironmentType_Metro); |
|
485 break; |
|
486 case eIntID_UseOverlayScrollbars: |
|
487 aResult = (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro); |
|
488 break; |
|
489 case eIntID_AllowOverlayScrollbarsOverlap: |
|
490 aResult = 0; |
|
491 break; |
|
492 case eIntID_ScrollbarDisplayOnMouseMove: |
|
493 aResult = 1; |
|
494 break; |
|
495 case eIntID_ScrollbarFadeBeginDelay: |
|
496 aResult = 2500; |
|
497 break; |
|
498 case eIntID_ScrollbarFadeDuration: |
|
499 aResult = 350; |
|
500 break; |
|
501 default: |
|
502 aResult = 0; |
|
503 res = NS_ERROR_FAILURE; |
|
504 } |
|
505 return res; |
|
506 } |
|
507 |
|
508 nsresult |
|
509 nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult) |
|
510 { |
|
511 nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult); |
|
512 if (NS_SUCCEEDED(res)) |
|
513 return res; |
|
514 res = NS_OK; |
|
515 |
|
516 switch (aID) { |
|
517 case eFloatID_IMEUnderlineRelativeSize: |
|
518 aResult = 1.0f; |
|
519 break; |
|
520 case eFloatID_SpellCheckerUnderlineRelativeSize: |
|
521 aResult = 1.0f; |
|
522 break; |
|
523 default: |
|
524 aResult = -1.0; |
|
525 res = NS_ERROR_FAILURE; |
|
526 } |
|
527 return res; |
|
528 } |
|
529 |
|
530 static bool |
|
531 GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID, |
|
532 nsString &aFontName, |
|
533 gfxFontStyle &aFontStyle) |
|
534 { |
|
535 LOGFONTW* ptrLogFont = nullptr; |
|
536 LOGFONTW logFont; |
|
537 NONCLIENTMETRICSW ncm; |
|
538 HGDIOBJ hGDI; |
|
539 char16_t name[LF_FACESIZE]; |
|
540 |
|
541 // Depending on which stock font we want, there are three different |
|
542 // places we might have to look it up. |
|
543 switch (anID) { |
|
544 case LookAndFeel::eFont_Icon: |
|
545 if (!::SystemParametersInfoW(SPI_GETICONTITLELOGFONT, |
|
546 sizeof(logFont), (PVOID)&logFont, 0)) |
|
547 return false; |
|
548 |
|
549 ptrLogFont = &logFont; |
|
550 break; |
|
551 |
|
552 case LookAndFeel::eFont_Menu: |
|
553 case LookAndFeel::eFont_MessageBox: |
|
554 case LookAndFeel::eFont_SmallCaption: |
|
555 case LookAndFeel::eFont_StatusBar: |
|
556 case LookAndFeel::eFont_Tooltips: |
|
557 ncm.cbSize = sizeof(NONCLIENTMETRICSW); |
|
558 if (!::SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, |
|
559 sizeof(ncm), (PVOID)&ncm, 0)) |
|
560 return false; |
|
561 |
|
562 switch (anID) { |
|
563 case LookAndFeel::eFont_Menu: |
|
564 ptrLogFont = &ncm.lfMenuFont; |
|
565 break; |
|
566 case LookAndFeel::eFont_MessageBox: |
|
567 ptrLogFont = &ncm.lfMessageFont; |
|
568 break; |
|
569 case LookAndFeel::eFont_SmallCaption: |
|
570 ptrLogFont = &ncm.lfSmCaptionFont; |
|
571 break; |
|
572 case LookAndFeel::eFont_StatusBar: |
|
573 case LookAndFeel::eFont_Tooltips: |
|
574 ptrLogFont = &ncm.lfStatusFont; |
|
575 break; |
|
576 } |
|
577 break; |
|
578 |
|
579 case LookAndFeel::eFont_Widget: |
|
580 case LookAndFeel::eFont_Window: // css3 |
|
581 case LookAndFeel::eFont_Document: |
|
582 case LookAndFeel::eFont_Workspace: |
|
583 case LookAndFeel::eFont_Desktop: |
|
584 case LookAndFeel::eFont_Info: |
|
585 case LookAndFeel::eFont_Dialog: |
|
586 case LookAndFeel::eFont_Button: |
|
587 case LookAndFeel::eFont_PullDownMenu: |
|
588 case LookAndFeel::eFont_List: |
|
589 case LookAndFeel::eFont_Field: |
|
590 case LookAndFeel::eFont_Caption: |
|
591 hGDI = ::GetStockObject(DEFAULT_GUI_FONT); |
|
592 if (!hGDI) |
|
593 return false; |
|
594 |
|
595 if (::GetObjectW(hGDI, sizeof(logFont), &logFont) <= 0) |
|
596 return false; |
|
597 |
|
598 ptrLogFont = &logFont; |
|
599 break; |
|
600 } |
|
601 |
|
602 // Get scaling factor from physical to logical pixels |
|
603 float pixelScale = 1.0f / gfxWindowsPlatform::GetPlatform()->GetDPIScale(); |
|
604 |
|
605 // The lfHeight is in pixels, and it needs to be adjusted for the |
|
606 // device it will be displayed on. |
|
607 // Screens and Printers will differ in DPI |
|
608 // |
|
609 // So this accounts for the difference in the DeviceContexts |
|
610 // The pixelScale will typically be 1.0 for the screen |
|
611 // (though larger for hi-dpi screens where the Windows resolution |
|
612 // scale factor is 125% or 150% or even more), and could be |
|
613 // any value when going to a printer, for example pixelScale is |
|
614 // 6.25 when going to a 600dpi printer. |
|
615 float pixelHeight = -ptrLogFont->lfHeight; |
|
616 if (pixelHeight < 0) { |
|
617 HFONT hFont = ::CreateFontIndirectW(ptrLogFont); |
|
618 if (!hFont) |
|
619 return false; |
|
620 HGDIOBJ hObject = ::SelectObject(aHDC, hFont); |
|
621 TEXTMETRIC tm; |
|
622 ::GetTextMetrics(aHDC, &tm); |
|
623 ::SelectObject(aHDC, hObject); |
|
624 ::DeleteObject(hFont); |
|
625 pixelHeight = tm.tmAscent; |
|
626 } |
|
627 pixelHeight *= pixelScale; |
|
628 |
|
629 // we have problem on Simplified Chinese system because the system |
|
630 // report the default font size is 8 points. but if we use 8, the text |
|
631 // display very ugly. force it to be at 9 points (12 pixels) on that |
|
632 // system (cp936), but leave other sizes alone. |
|
633 if (pixelHeight < 12 && ::GetACP() == 936) |
|
634 pixelHeight = 12; |
|
635 |
|
636 aFontStyle.size = pixelHeight; |
|
637 |
|
638 // FIXME: What about oblique? |
|
639 aFontStyle.style = |
|
640 (ptrLogFont->lfItalic) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL; |
|
641 |
|
642 // FIXME: Other weights? |
|
643 aFontStyle.weight = |
|
644 (ptrLogFont->lfWeight == FW_BOLD ? |
|
645 NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL); |
|
646 |
|
647 // FIXME: Set aFontStyle->stretch correctly! |
|
648 aFontStyle.stretch = NS_FONT_STRETCH_NORMAL; |
|
649 |
|
650 aFontStyle.systemFont = true; |
|
651 |
|
652 name[0] = 0; |
|
653 memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t)); |
|
654 aFontName = name; |
|
655 |
|
656 return true; |
|
657 } |
|
658 |
|
659 bool |
|
660 nsLookAndFeel::GetFontImpl(FontID anID, nsString &aFontName, |
|
661 gfxFontStyle &aFontStyle, |
|
662 float aDevPixPerCSSPixel) |
|
663 { |
|
664 HDC tdc = GetDC(nullptr); |
|
665 bool status = GetSysFontInfo(tdc, anID, aFontName, aFontStyle); |
|
666 ReleaseDC(nullptr, tdc); |
|
667 // now convert the logical font size from GetSysFontInfo into device pixels for layout |
|
668 aFontStyle.size *= aDevPixPerCSSPixel; |
|
669 return status; |
|
670 } |
|
671 |
|
672 /* virtual */ |
|
673 char16_t |
|
674 nsLookAndFeel::GetPasswordCharacterImpl() |
|
675 { |
|
676 #define UNICODE_BLACK_CIRCLE_CHAR 0x25cf |
|
677 return UNICODE_BLACK_CIRCLE_CHAR; |
|
678 } |