Add copy of .ttf font with .eot extension for testing
[wine-gecko.git] / widget / src / xpwidgets / nsXPLookAndFeel.cpp
blobbbe6b1450b19d3e35895c998c9a094a242d8bebd
1 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nscore.h"
40 #include "nsXPLookAndFeel.h"
41 #include "nsIServiceManager.h"
42 #include "nsIPrefBranch2.h"
43 #include "nsIPrefBranch.h"
44 #include "nsIPrefService.h"
45 #include "nsIObserver.h"
46 #include "nsCRT.h"
47 #include "nsFont.h"
49 #include "gfxPlatform.h"
50 #include "lcms.h"
52 #ifdef DEBUG
53 #include "nsSize.h"
54 #endif
56 NS_IMPL_ISUPPORTS2(nsXPLookAndFeel, nsILookAndFeel, nsIObserver)
58 nsLookAndFeelIntPref nsXPLookAndFeel::sIntPrefs[] =
60 { "ui.windowTitleHeight", eMetric_WindowTitleHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
61 { "ui.windowBorderWidth", eMetric_WindowBorderWidth, PR_FALSE, nsLookAndFeelTypeInt, 0 },
62 { "ui.windowBorderHeight", eMetric_WindowBorderHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
63 { "ui.widget3DBorder", eMetric_Widget3DBorder, PR_FALSE, nsLookAndFeelTypeInt, 0 },
64 { "ui.textFieldBorder", eMetric_TextFieldBorder, PR_FALSE, nsLookAndFeelTypeInt, 0 },
65 { "ui.textFieldHeight", eMetric_TextFieldHeight, PR_FALSE, nsLookAndFeelTypeInt, 0 },
66 { "ui.buttonHorizontalInsidePaddingNavQuirks",
67 eMetric_ButtonHorizontalInsidePaddingNavQuirks, PR_FALSE, nsLookAndFeelTypeInt, 0 },
68 { "ui.buttonHorizontalInsidePaddingOffsetNavQuirks",
69 eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks, PR_FALSE, nsLookAndFeelTypeInt, 0 },
70 { "ui.checkboxSize", eMetric_CheckboxSize, PR_FALSE, nsLookAndFeelTypeInt, 0 },
71 { "ui.radioboxSize", eMetric_RadioboxSize, PR_FALSE, nsLookAndFeelTypeInt, 0 },
72 { "ui.textHorizontalInsideMinimumPadding",
73 eMetric_TextHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
74 { "ui.textVerticalInsidePadding", eMetric_TextVerticalInsidePadding,
75 PR_FALSE, nsLookAndFeelTypeInt, 0 },
76 { "ui.textShouldUseVerticalInsidePadding",
77 eMetric_TextShouldUseVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
78 { "ui.textShouldUseHorizontalInsideMinimumPadding",
79 eMetric_TextShouldUseHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
80 { "ui.listShouldUseHorizontalInsideMinimumPadding",
81 eMetric_ListShouldUseHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
82 { "ui.listHorizontalInsideMinimumPadding",
83 eMetric_ListHorizontalInsideMinimumPadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
84 { "ui.listShouldUseVerticalInsidePadding",
85 eMetric_ListShouldUseVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeInt, 0 },
86 { "ui.listVerticalInsidePadding", eMetric_ListVerticalInsidePadding,
87 PR_FALSE, nsLookAndFeelTypeInt, 0 },
88 { "ui.caretBlinkTime", eMetric_CaretBlinkTime, PR_FALSE, nsLookAndFeelTypeInt, 0 },
89 { "ui.caretWidth", eMetric_CaretWidth, PR_FALSE, nsLookAndFeelTypeInt, 0 },
90 { "ui.caretVisibleWithSelection", eMetric_ShowCaretDuringSelection, PR_FALSE, nsLookAndFeelTypeInt, 0 },
91 { "ui.submenuDelay", eMetric_SubmenuDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
92 { "ui.dragFullWindow", eMetric_DragFullWindow, PR_FALSE, nsLookAndFeelTypeInt, 0 },
93 { "ui.dragThresholdX", eMetric_DragThresholdX, PR_FALSE, nsLookAndFeelTypeInt, 0 },
94 { "ui.dragThresholdY", eMetric_DragThresholdY, PR_FALSE, nsLookAndFeelTypeInt, 0 },
95 { "ui.useAccessibilityTheme", eMetric_UseAccessibilityTheme, PR_FALSE, nsLookAndFeelTypeInt, 0 },
96 { "ui.isScreenReaderActive", eMetric_IsScreenReaderActive, PR_FALSE, nsLookAndFeelTypeInt, 0 },
97 { "ui.menusCanOverlapOSBar", eMetric_MenusCanOverlapOSBar,
98 PR_FALSE, nsLookAndFeelTypeInt, 0 },
99 { "ui.skipNavigatingDisabledMenuItem", eMetric_SkipNavigatingDisabledMenuItem, PR_FALSE, nsLookAndFeelTypeInt, 0 },
100 { "ui.treeOpenDelay",
101 eMetric_TreeOpenDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
102 { "ui.treeCloseDelay",
103 eMetric_TreeCloseDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
104 { "ui.treeLazyScrollDelay",
105 eMetric_TreeLazyScrollDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
106 { "ui.treeScrollDelay",
107 eMetric_TreeScrollDelay, PR_FALSE, nsLookAndFeelTypeInt, 0 },
108 { "ui.treeScrollLinesMax",
109 eMetric_TreeScrollLinesMax, PR_FALSE, nsLookAndFeelTypeInt, 0 },
110 { "accessibility.tabfocus",
111 eMetric_TabFocusModel, PR_FALSE, nsLookAndFeelTypeInt, 0 },
112 { "ui.alertNotificationOrigin",
113 eMetric_AlertNotificationOrigin, PR_FALSE, nsLookAndFeelTypeInt, 0 },
114 { "ui.scrollToClick",
115 eMetric_ScrollToClick, PR_FALSE, nsLookAndFeelTypeInt, 0 },
116 { "ui.IMERawInputUnderlineStyle",
117 eMetric_IMERawInputUnderlineStyle, PR_FALSE, nsLookAndFeelTypeInt, 0 },
118 { "ui.IMESelectedRawTextUnderlineStyle",
119 eMetric_IMESelectedRawTextUnderlineStyle, PR_FALSE, nsLookAndFeelTypeInt, 0 },
120 { "ui.IMEConvertedTextUnderlineStyle",
121 eMetric_IMEConvertedTextUnderlineStyle, PR_FALSE, nsLookAndFeelTypeInt, 0 },
122 { "ui.IMESelectedConvertedTextUnderlineStyle",
123 eMetric_IMESelectedConvertedTextUnderline, PR_FALSE, nsLookAndFeelTypeInt, 0 },
126 nsLookAndFeelFloatPref nsXPLookAndFeel::sFloatPrefs[] =
128 { "ui.textFieldVerticalInsidePadding",
129 eMetricFloat_TextFieldVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
130 { "ui.textFieldHorizontalInsidePadding",
131 eMetricFloat_TextFieldHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
132 { "ui.textAreaVerticalInsidePadding", eMetricFloat_TextAreaVerticalInsidePadding,
133 PR_FALSE, nsLookAndFeelTypeFloat, 0 },
134 { "ui.textAreaHorizontalInsidePadding",
135 eMetricFloat_TextAreaHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
136 { "ui.listVerticalInsidePadding",
137 eMetricFloat_ListVerticalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
138 { "ui.listHorizontalInsidePadding",
139 eMetricFloat_ListHorizontalInsidePadding, PR_FALSE, nsLookAndFeelTypeFloat, 0 },
140 { "ui.buttonVerticalInsidePadding", eMetricFloat_ButtonVerticalInsidePadding,
141 PR_FALSE, nsLookAndFeelTypeFloat, 0 },
142 { "ui.buttonHorizontalInsidePadding", eMetricFloat_ButtonHorizontalInsidePadding,
143 PR_FALSE, nsLookAndFeelTypeFloat, 0 },
144 { "ui.IMEUnderlineRelativeSize", eMetricFloat_IMEUnderlineRelativeSize,
145 PR_FALSE, nsLookAndFeelTypeFloat, 0 },
146 { "ui.caretAspectRatio", eMetricFloat_CaretAspectRatio, PR_FALSE,
147 nsLookAndFeelTypeFloat, 0 },
151 // This array MUST be kept in the same order as the color list in nsILookAndFeel.h.
152 /* XXX If you add any strings longer than
153 * "ui.IMESelectedConvertedTextBackground"
154 * to the following array then you MUST update the
155 * sizes of the sColorPrefs array in nsXPLookAndFeel.h
157 const char nsXPLookAndFeel::sColorPrefs[][38] =
159 "ui.windowBackground",
160 "ui.windowForeground",
161 "ui.widgetBackground",
162 "ui.widgetForeground",
163 "ui.widgetSelectBackground",
164 "ui.widgetSelectForeground",
165 "ui.widget3DHighlight",
166 "ui.widget3DShadow",
167 "ui.textBackground",
168 "ui.textForeground",
169 "ui.textSelectBackground",
170 "ui.textSelectForeground",
171 "ui.textSelectBackgroundDisabled",
172 "ui.textSelectBackgroundAttention",
173 "ui.textHighlightBackground",
174 "ui.textHighlightForeground",
175 "ui.IMERawInputBackground",
176 "ui.IMERawInputForeground",
177 "ui.IMERawInputUnderline",
178 "ui.IMESelectedRawTextBackground",
179 "ui.IMESelectedRawTextForeground",
180 "ui.IMESelectedRawTextUnderline",
181 "ui.IMEConvertedTextBackground",
182 "ui.IMEConvertedTextForeground",
183 "ui.IMEConvertedTextUnderline",
184 "ui.IMESelectedConvertedTextBackground",
185 "ui.IMESelectedConvertedTextForeground",
186 "ui.IMESelectedConvertedTextUnderline",
187 "ui.activeborder",
188 "ui.activecaption",
189 "ui.appworkspace",
190 "ui.background",
191 "ui.buttonface",
192 "ui.buttonhighlight",
193 "ui.buttonshadow",
194 "ui.buttontext",
195 "ui.captiontext",
196 "ui.graytext",
197 "ui.highlight",
198 "ui.highlighttext",
199 "ui.inactiveborder",
200 "ui.inactivecaption",
201 "ui.inactivecaptiontext",
202 "ui.infobackground",
203 "ui.infotext",
204 "ui.menu",
205 "ui.menutext",
206 "ui.scrollbar",
207 "ui.threeddarkshadow",
208 "ui.threedface",
209 "ui.threedhighlight",
210 "ui.threedlightshadow",
211 "ui.threedshadow",
212 "ui.window",
213 "ui.windowframe",
214 "ui.windowtext",
215 "ui.-moz-buttondefault",
216 "ui.-moz-field",
217 "ui.-moz-fieldtext",
218 "ui.-moz-dialog",
219 "ui.-moz-dialogtext",
220 "ui.-moz-dragtargetzone",
221 "ui.-moz-cellhighlight",
222 "ui.-moz_cellhighlighttext",
223 "ui.-moz-html-cellhighlight",
224 "ui.-moz-html-cellhighlighttext",
225 "ui.-moz-buttonhoverface",
226 "ui.-moz_buttonhovertext",
227 "ui.-moz_menuhover",
228 "ui.-moz_menuhovertext",
229 "ui.-moz_menubarhovertext",
230 "ui.-moz_eventreerow",
231 "ui.-moz_oddtreerow",
232 "ui.-moz-mac-focusring",
233 "ui.-moz-mac-menuselect",
234 "ui.-moz-mac-menushadow",
235 "ui.-moz-mac-menutextdisable",
236 "ui.-moz-mac-menutextselect",
237 "ui.-moz-mac-accentlightesthighlight",
238 "ui.-moz-mac-accentregularhighlight",
239 "ui.-moz-mac-accentface",
240 "ui.-moz-mac-accentlightshadow",
241 "ui.-moz-mac-accentregularshadow",
242 "ui.-moz-mac-accentdarkshadow",
243 "ui.-moz-mac-accentdarkestshadow",
244 "ui.-moz-mac-alternateprimaryhighlight",
245 "ui.-moz-mac-secondaryhighlight",
246 "ui.-moz-win-mediatext",
247 "ui.-moz-win-communicationstext",
248 "ui.-moz-nativehyperlinktext"
251 PRInt32 nsXPLookAndFeel::sCachedColors[nsILookAndFeel::eColor_LAST_COLOR] = {0};
252 PRInt32 nsXPLookAndFeel::sCachedColorBits[COLOR_CACHE_SIZE] = {0};
254 PRBool nsXPLookAndFeel::sInitialized = PR_FALSE;
256 nsXPLookAndFeel::nsXPLookAndFeel() : nsILookAndFeel()
260 void
261 nsXPLookAndFeel::IntPrefChanged (nsLookAndFeelIntPref *data)
263 if (data)
265 nsCOMPtr<nsIPrefBranch> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID));
266 if (prefService)
268 PRInt32 intpref;
269 nsresult rv = prefService->GetIntPref(data->name, &intpref);
270 if (NS_SUCCEEDED(rv))
272 data->intVar = intpref;
273 data->isSet = PR_TRUE;
274 #ifdef DEBUG_akkana
275 printf("====== Changed int pref %s to %d\n", data->name, data->intVar);
276 #endif
282 void
283 nsXPLookAndFeel::FloatPrefChanged (nsLookAndFeelFloatPref *data)
285 if (data)
287 nsCOMPtr<nsIPrefBranch> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID));
288 if (prefService)
290 PRInt32 intpref;
291 nsresult rv = prefService->GetIntPref(data->name, &intpref);
292 if (NS_SUCCEEDED(rv))
294 data->floatVar = (float)intpref / 100.;
295 data->isSet = PR_TRUE;
296 #ifdef DEBUG_akkana
297 printf("====== Changed float pref %s to %f\n", data->name, data->floatVar);
298 #endif
304 void
305 nsXPLookAndFeel::ColorPrefChanged (unsigned int index, const char *prefName)
307 nsCOMPtr<nsIPrefBranch> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID));
308 if (prefService) {
309 nsXPIDLCString colorStr;
310 nsresult rv = prefService->GetCharPref(prefName, getter_Copies(colorStr));
311 if (NS_SUCCEEDED(rv) && !colorStr.IsEmpty()) {
312 nscolor thecolor;
313 if (colorStr[0] == '#') {
314 if (NS_SUCCEEDED(NS_HexToRGB(NS_ConvertASCIItoUTF16(Substring(colorStr, 1, colorStr.Length() - 1)),
315 &thecolor))) {
316 PRInt32 id = NS_PTR_TO_INT32(index);
317 CACHE_COLOR(id, thecolor);
320 else if (NS_SUCCEEDED(NS_ColorNameToRGB(NS_ConvertASCIItoUTF16(colorStr),
321 &thecolor))) {
322 PRInt32 id = NS_PTR_TO_INT32(index);
323 CACHE_COLOR(id, thecolor);
324 #ifdef DEBUG_akkana
325 printf("====== Changed color pref %s to 0x%lx\n",
326 prefName, thecolor);
327 #endif
329 } else if (colorStr.IsEmpty()) {
330 // Reset to the default color, by clearing the cache
331 // to force lookup when the color is next used
332 PRInt32 id = NS_PTR_TO_INT32(index);
333 CLEAR_COLOR_CACHE(id);
338 void
339 nsXPLookAndFeel::InitFromPref(nsLookAndFeelIntPref* aPref, nsIPrefBranch* aPrefBranch)
341 PRInt32 intpref;
342 nsresult rv = aPrefBranch->GetIntPref(aPref->name, &intpref);
343 if (NS_SUCCEEDED(rv))
345 aPref->isSet = PR_TRUE;
346 aPref->intVar = intpref;
350 void
351 nsXPLookAndFeel::InitFromPref(nsLookAndFeelFloatPref* aPref, nsIPrefBranch* aPrefBranch)
353 PRInt32 intpref;
354 nsresult rv = aPrefBranch->GetIntPref(aPref->name, &intpref);
355 if (NS_SUCCEEDED(rv))
357 aPref->isSet = PR_TRUE;
358 aPref->floatVar = (float)intpref / 100.;
362 void
363 nsXPLookAndFeel::InitColorFromPref(PRInt32 i, nsIPrefBranch* aPrefBranch)
365 nsXPIDLCString colorStr;
366 nsresult rv = aPrefBranch->GetCharPref(sColorPrefs[i], getter_Copies(colorStr));
367 if (NS_SUCCEEDED(rv) && !colorStr.IsEmpty())
369 nsAutoString colorNSStr; colorNSStr.AssignWithConversion(colorStr);
370 nscolor thecolor;
371 if (colorNSStr[0] == '#') {
372 nsAutoString hexString;
373 colorNSStr.Right(hexString, colorNSStr.Length() - 1);
374 if (NS_SUCCEEDED(NS_HexToRGB(hexString, &thecolor))) {
375 CACHE_COLOR(i, thecolor);
378 else if (NS_SUCCEEDED(NS_ColorNameToRGB(colorNSStr, &thecolor)))
380 CACHE_COLOR(i, thecolor);
385 NS_IMETHODIMP
386 nsXPLookAndFeel::Observe(nsISupports* aSubject,
387 const char* aTopic,
388 const PRUnichar* aData)
391 // looping in the same order as in ::Init
393 unsigned int i;
394 for (i = 0; i < NS_ARRAY_LENGTH(sIntPrefs); ++i) {
395 if (nsDependentString(aData).EqualsASCII(sIntPrefs[i].name)) {
396 IntPrefChanged(&sIntPrefs[i]);
397 return NS_OK;
401 for (i = 0; i < NS_ARRAY_LENGTH(sFloatPrefs); ++i) {
402 if (nsDependentString(aData).EqualsASCII(sFloatPrefs[i].name)) {
403 FloatPrefChanged(&sFloatPrefs[i]);
404 return NS_OK;
408 for (i = 0; i < NS_ARRAY_LENGTH(sColorPrefs); ++i) {
409 if (nsDependentString(aData).EqualsASCII(sColorPrefs[i])) {
410 ColorPrefChanged(i, sColorPrefs[i]);
411 return NS_OK;
415 return NS_OK;
419 // Read values from the user's preferences.
420 // This is done once at startup, but since the user's preferences
421 // haven't actually been read yet at that time, we also have to
422 // set a callback to inform us of changes to each pref.
424 void
425 nsXPLookAndFeel::Init()
427 // Say we're already initialized, and take the chance that it might fail;
428 // protects against some other process writing to our static variables.
429 sInitialized = PR_TRUE;
431 nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
432 if (!prefs)
433 return;
434 nsCOMPtr<nsIPrefBranch2> prefBranchInternal(do_QueryInterface(prefs));
435 if (!prefBranchInternal)
436 return;
438 unsigned int i;
439 for (i = 0; i < NS_ARRAY_LENGTH(sIntPrefs); ++i) {
440 InitFromPref(&sIntPrefs[i], prefs);
441 prefBranchInternal->AddObserver(sIntPrefs[i].name, this, PR_FALSE);
444 for (i = 0; i < NS_ARRAY_LENGTH(sFloatPrefs); ++i) {
445 InitFromPref(&sFloatPrefs[i], prefs);
446 prefBranchInternal->AddObserver(sFloatPrefs[i].name, this, PR_FALSE);
449 for (i = 0; i < NS_ARRAY_LENGTH(sColorPrefs); ++i) {
450 InitColorFromPref(i, prefs);
451 prefBranchInternal->AddObserver(sColorPrefs[i], this, PR_FALSE);
455 nsXPLookAndFeel::~nsXPLookAndFeel()
459 PRBool
460 nsXPLookAndFeel::IsSpecialColor(const nsColorID aID, nscolor &aColor)
462 switch (aID) {
463 case eColor_TextSelectForeground:
464 return (aColor == NS_DONT_CHANGE_COLOR);
465 case eColor_IMESelectedRawTextBackground:
466 case eColor_IMESelectedConvertedTextBackground:
467 case eColor_IMERawInputBackground:
468 case eColor_IMEConvertedTextBackground:
469 case eColor_IMESelectedRawTextForeground:
470 case eColor_IMESelectedConvertedTextForeground:
471 case eColor_IMERawInputForeground:
472 case eColor_IMEConvertedTextForeground:
473 case eColor_IMERawInputUnderline:
474 case eColor_IMEConvertedTextUnderline:
475 case eColor_IMESelectedRawTextUnderline:
476 case eColor_IMESelectedConvertedTextUnderline:
477 return NS_IS_IME_SPECIAL_COLOR(aColor);
478 default:
480 * In GetColor(), every color that is not a special color is color
481 * corrected. Use PR_FALSE to make other colors color corrected.
483 return PR_FALSE;
485 return PR_FALSE;
489 // All these routines will return NS_OK if they have a value,
490 // in which case the nsLookAndFeel should use that value;
491 // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
492 // platform-specific nsLookAndFeel should use its own values instead.
494 NS_IMETHODIMP
495 nsXPLookAndFeel::GetColor(const nsColorID aID, nscolor &aColor)
497 if (!sInitialized)
498 Init();
500 // define DEBUG_SYSTEM_COLOR_USE if you want to debug system color
501 // use in a skin that uses them. When set, it will make all system
502 // color pairs that are appropriate for foreground/background
503 // pairing the same. This means if the skin is using system colors
504 // correctly you will not be able to see *any* text.
505 #undef DEBUG_SYSTEM_COLOR_USE
507 #ifdef DEBUG_SYSTEM_COLOR_USE
509 nsresult rv = NS_OK;
510 switch (aID) {
511 // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
512 case eColor_activecaption:
513 // active window caption background
514 case eColor_captiontext:
515 // text in active window caption
516 aColor = NS_RGB(0xff, 0x00, 0x00);
517 break;
519 case eColor_highlight:
520 // background of selected item
521 case eColor_highlighttext:
522 // text of selected item
523 aColor = NS_RGB(0xff, 0xff, 0x00);
524 break;
526 case eColor_inactivecaption:
527 // inactive window caption
528 case eColor_inactivecaptiontext:
529 // text in inactive window caption
530 aColor = NS_RGB(0x66, 0x66, 0x00);
531 break;
533 case eColor_infobackground:
534 // tooltip background color
535 case eColor_infotext:
536 // tooltip text color
537 aColor = NS_RGB(0x00, 0xff, 0x00);
538 break;
540 case eColor_menu:
541 // menu background
542 case eColor_menutext:
543 // menu text
544 aColor = NS_RGB(0x00, 0xff, 0xff);
545 break;
547 case eColor_threedface:
548 case eColor_buttonface:
549 // 3-D face color
550 case eColor_buttontext:
551 // text on push buttons
552 aColor = NS_RGB(0x00, 0x66, 0x66);
553 break;
555 case eColor_window:
556 case eColor_windowtext:
557 aColor = NS_RGB(0x00, 0x00, 0xff);
558 break;
560 // from the CSS3 working draft (not yet finalized)
561 // http://www.w3.org/tr/2000/wd-css3-userint-20000216.html#color
563 case eColor__moz_field:
564 case eColor__moz_fieldtext:
565 aColor = NS_RGB(0xff, 0x00, 0xff);
566 break;
568 case eColor__moz_dialog:
569 case eColor__moz_dialogtext:
570 aColor = NS_RGB(0x66, 0x00, 0x66);
571 break;
573 default:
574 rv = NS_ERROR_NOT_AVAILABLE;
576 if (NS_SUCCEEDED(rv))
577 return rv;
579 #endif // DEBUG_SYSTEM_COLOR_USE
581 if (IS_COLOR_CACHED(aID)) {
582 aColor = sCachedColors[aID];
583 return NS_OK;
586 // There are no system color settings for these, so set them manually
587 if (aID == eColor_TextSelectBackgroundDisabled) {
588 // This is used to gray out the selection when it's not focused
589 // Used with nsISelectionController::SELECTION_DISABLED
590 aColor = NS_RGB(0xb0, 0xb0, 0xb0);
591 return NS_OK;
594 if (aID == eColor_TextSelectBackgroundAttention) {
595 // This makes the selection stand out when typeaheadfind is on
596 // Used with nsISelectionController::SELECTION_ATTENTION
597 aColor = NS_RGB(0x38, 0xd8, 0x78);
598 return NS_OK;
601 if (aID == eColor_TextHighlightBackground) {
602 // This makes the matched text stand out when findbar highlighting is on
603 // Used with nsISelectionController::SELECTION_FIND
604 aColor = NS_RGB(0xef, 0x0f, 0xff);
605 return NS_OK;
608 if (aID == eColor_TextHighlightForeground) {
609 // The foreground color for the matched text in findbar highlighting
610 // Used with nsISelectionController::SELECTION_FIND
611 aColor = NS_RGB(0xff, 0xff, 0xff);
612 return NS_OK;
615 if (NS_SUCCEEDED(NativeGetColor(aID, aColor))) {
616 if ((gfxPlatform::GetCMSMode() == eCMSMode_All) && !IsSpecialColor(aID, aColor)) {
617 cmsHTRANSFORM transform = gfxPlatform::GetCMSInverseRGBTransform();
618 if (transform) {
619 PRUint8 color[3];
620 color[0] = NS_GET_R(aColor);
621 color[1] = NS_GET_G(aColor);
622 color[2] = NS_GET_B(aColor);
623 cmsDoTransform(transform, color, color, 1);
624 aColor = NS_RGB(color[0], color[1], color[2]);
628 CACHE_COLOR(aID, aColor);
629 return NS_OK;
632 return NS_ERROR_NOT_AVAILABLE;
635 NS_IMETHODIMP
636 nsXPLookAndFeel::GetMetric(const nsMetricID aID, PRInt32& aMetric)
638 if (!sInitialized)
639 Init();
641 // Set the default values for these prefs. but allow different platforms
642 // to override them in their nsLookAndFeel if desired.
643 switch (aID) {
644 case eMetric_ScrollButtonLeftMouseButtonAction:
645 aMetric = 0;
646 return NS_OK;
647 case eMetric_ScrollButtonMiddleMouseButtonAction:
648 aMetric = 3;
649 return NS_OK;
650 case eMetric_ScrollButtonRightMouseButtonAction:
651 aMetric = 3;
652 return NS_OK;
653 default:
655 * The metrics above are hardcoded platform defaults. All the other
656 * metrics are stored in sIntPrefs and can be changed at runtime.
658 break;
661 for (unsigned int i = 0; i < ((sizeof (sIntPrefs) / sizeof (*sIntPrefs))); ++i)
662 if (sIntPrefs[i].isSet && (sIntPrefs[i].id == aID))
664 aMetric = sIntPrefs[i].intVar;
665 return NS_OK;
668 return NS_ERROR_NOT_AVAILABLE;
671 NS_IMETHODIMP
672 nsXPLookAndFeel::GetMetric(const nsMetricFloatID aID, float& aMetric)
674 if (!sInitialized)
675 Init();
677 for (unsigned int i = 0; i < ((sizeof (sFloatPrefs) / sizeof (*sFloatPrefs))); ++i)
678 if (sFloatPrefs[i].isSet && sFloatPrefs[i].id == aID)
680 aMetric = sFloatPrefs[i].floatVar;
681 return NS_OK;
684 return NS_ERROR_NOT_AVAILABLE;
687 NS_IMETHODIMP
688 nsXPLookAndFeel::LookAndFeelChanged()
690 // Wipe out our color cache.
691 PRUint32 i;
692 for (i = 0; i < nsILookAndFeel::eColor_LAST_COLOR; i++)
693 sCachedColors[i] = 0;
694 for (i = 0; i < COLOR_CACHE_SIZE; i++)
695 sCachedColorBits[i] = 0;
696 return NS_OK;
700 #ifdef DEBUG
701 // This method returns the actual (or nearest estimate)
702 // of the Navigator size for a given form control for a given font
703 // and font size. This is used in NavQuirks mode to see how closely
704 // we match its size
705 NS_IMETHODIMP
706 nsXPLookAndFeel::GetNavSize(const nsMetricNavWidgetID aWidgetID,
707 const nsMetricNavFontID aFontID,
708 const PRInt32 aFontSize,
709 nsSize &aSize)
711 aSize.width = 0;
712 aSize.height = 0;
713 return NS_ERROR_NOT_IMPLEMENTED;
715 #endif