OLD | NEW |
1 /* | 1 /* |
2 * This file is part of the WebKit project. | 2 * This file is part of the WebKit project. |
3 * | 3 * |
4 * Copyright (C) 2006 Apple Computer, Inc. | 4 * Copyright (C) 2006 Apple Computer, Inc. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "FontUtilsWin.h" | 34 #include "FontUtilsWin.h" |
35 #include "GraphicsContext.h" | 35 #include "GraphicsContext.h" |
36 #include "ScrollbarTheme.h" | 36 #include "ScrollbarTheme.h" |
37 #include "SkiaUtils.h" | 37 #include "SkiaUtils.h" |
38 #include "ThemeHelperWin.h" | 38 #include "ThemeHelperWin.h" |
39 | 39 |
40 #include "base/gfx/native_theme.h" | 40 #include "base/gfx/native_theme.h" |
41 #include "base/gfx/skia_utils.h" | 41 #include "base/gfx/skia_utils.h" |
42 #include "base/win_util.h" | 42 #include "base/win_util.h" |
43 | 43 |
| 44 namespace { |
| 45 |
44 // These enums correspond to similarly named values defined by SafariTheme.h | 46 // These enums correspond to similarly named values defined by SafariTheme.h |
45 enum ControlSize { | 47 enum ControlSize { |
46 RegularControlSize, | 48 RegularControlSize, |
47 SmallControlSize, | 49 SmallControlSize, |
48 MiniControlSize | 50 MiniControlSize |
49 }; | 51 }; |
50 | 52 |
51 enum PaddingType { | 53 enum PaddingType { |
52 TopPadding, | 54 TopPadding, |
53 RightPadding, | 55 RightPadding, |
54 BottomPadding, | 56 BottomPadding, |
55 LeftPadding | 57 LeftPadding |
56 }; | 58 }; |
57 | 59 |
58 namespace { | 60 const int kDefaultButtonPadding = 2; |
59 const int kDefaultButtonPadding = 2; | |
60 | 61 |
61 // These magic numbers come from Apple's version of RenderThemeWin.cpp. | 62 // These magic numbers come from Apple's version of RenderThemeWin.cpp. |
62 const int kMenuListPadding[4] = { 1, 2, 1, 2 }; | 63 const int kMenuListPadding[4] = { 1, 2, 1, 2 }; |
63 | 64 |
64 // The kLayoutTest* constants are metrics used only in layout test mode, | 65 // The kLayoutTest* constants are metrics used only in layout test mode, |
65 // so as to match RenderThemeMac.mm and to remain consistent despite any | 66 // so as to match RenderThemeMac.mm and to remain consistent despite any |
66 // theme or font changes. | 67 // theme or font changes. |
67 const int kLayoutTestControlHeight[3] = { 21, 18, 15 }; | 68 const int kLayoutTestControlHeight[3] = { 21, 18, 15 }; |
68 const int kLayoutTestButtonPadding[4] = { 0, 8, 0, 8 }; | 69 const int kLayoutTestButtonPadding[4] = { 0, 8, 0, 8 }; |
69 const int kLayoutTestStyledMenuListInternalPadding[4] = { 1, 0, 2, 8 }; | 70 const int kLayoutTestStyledMenuListInternalPadding[4] = { 1, 0, 2, 8 }; |
70 const int kLayoutTestMenuListInternalPadding[3][4] = | 71 const int kLayoutTestMenuListInternalPadding[3][4] = |
71 { | 72 { |
72 { 2, 26, 3, 8 }, | 73 { 2, 26, 3, 8 }, |
73 { 2, 23, 3, 8 }, | 74 { 2, 23, 3, 8 }, |
74 { 2, 22, 3, 10 } | 75 { 2, 22, 3, 10 } |
75 }; | 76 }; |
76 const int kLayoutTestMenuListMinimumWidth[3] = { 9, 5, 0 }; | 77 const int kLayoutTestMenuListMinimumWidth[3] = { 9, 5, 0 }; |
77 const float kLayoutTestBaseFontSize = 11.0f; | 78 const float kLayoutTestBaseFontSize = 11.0f; |
78 const float kLayoutTestStatusBarFontSize = 10.0f; | 79 const float kLayoutTestStatusBarFontSize = 10.0f; |
79 const float kLayoutTestSystemFontSize = 13.0f; | 80 const float kLayoutTestSystemFontSize = 13.0f; |
80 | 81 |
81 const int kLayoutTestSliderThumbWidth = 15; | 82 const int kLayoutTestSliderThumbWidth = 15; |
82 const int kLayoutTestSliderThumbHeight = 15; | 83 const int kLayoutTestSliderThumbHeight = 15; |
83 | 84 |
84 const int kLayoutTestMenuListButtonWidth = 15; | 85 const int kLayoutTestMenuListButtonWidth = 15; |
85 const int kLayoutTestButtonMinHeight = 15; | 86 const int kLayoutTestButtonMinHeight = 15; |
86 | 87 |
87 const int kLayoutTestSearchFieldHeight[3] = { 22, 19, 17 }; | 88 const int kLayoutTestSearchFieldHeight[3] = { 22, 19, 17 }; |
88 const int kLayoutTestEmptyResultsOffset = 9; | 89 const int kLayoutTestEmptyResultsOffset = 9; |
89 const int kLayoutTestResultsArrowWidth = 5; | 90 const int kLayoutTestResultsArrowWidth = 5; |
90 | 91 |
91 const short kLayoutTestSearchFieldBorderWidth = 2; | 92 const short kLayoutTestSearchFieldBorderWidth = 2; |
92 const int kLayoutTestSearchFieldPadding = 1; | 93 const int kLayoutTestSearchFieldPadding = 1; |
93 | 94 |
| 95 // Constants that are used in non-layout-test mode. |
| 96 const int kStyledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; |
94 | 97 |
| 98 // The default variable-width font size. We use this as the default font |
| 99 // size for the "system font", and as a base size (which we then shrink) for |
| 100 // form control fonts. |
| 101 float DefaultFontSize = 16.0; |
95 | 102 |
96 // Constants that are used in non-layout-test mode. | 103 WebCore::FontDescription smallSystemFont; |
97 const int kStyledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; | 104 WebCore::FontDescription menuFont; |
| 105 WebCore::FontDescription labelFont; |
98 | 106 |
99 // The default variable-width font size. We use this as the default font | 107 } // namespace |
100 // size for the "system font", and as a base size (which we then shrink) for | |
101 // form control fonts. | |
102 float DefaultFontSize = 16.0; | |
103 | 108 |
104 WebCore::FontDescription smallSystemFont; | 109 namespace WebCore { |
105 WebCore::FontDescription menuFont; | 110 |
106 WebCore::FontDescription labelFont; | 111 // Internal static helper functions. We don't put them in an anonymous |
| 112 // namespace so they have easier access to the WebCore namespace. |
| 113 |
| 114 static bool supportsFocus(ControlPart appearance) |
| 115 { |
| 116 switch (appearance) { |
| 117 case PushButtonPart: |
| 118 case ButtonPart: |
| 119 case DefaultButtonPart: |
| 120 case TextFieldPart: |
| 121 case TextAreaPart: |
| 122 return true; |
| 123 default: |
| 124 return false; |
| 125 } |
| 126 |
| 127 return false; |
107 } | 128 } |
108 | 129 |
109 namespace WebCore { | |
110 | |
111 static void setFixedPadding(RenderStyle* style, const int padding[4]) | 130 static void setFixedPadding(RenderStyle* style, const int padding[4]) |
112 { | 131 { |
113 style->setPaddingLeft(Length(padding[LeftPadding], Fixed)); | 132 style->setPaddingLeft(Length(padding[LeftPadding], Fixed)); |
114 style->setPaddingRight(Length(padding[RightPadding], Fixed)); | 133 style->setPaddingRight(Length(padding[RightPadding], Fixed)); |
115 style->setPaddingTop(Length(padding[TopPadding], Fixed)); | 134 style->setPaddingTop(Length(padding[TopPadding], Fixed)); |
116 style->setPaddingBottom(Length(padding[BottomPadding], Fixed)); | 135 style->setPaddingBottom(Length(padding[BottomPadding], Fixed)); |
117 } | 136 } |
118 | 137 |
119 // This is logic from RenderThemeMac.mm, and is used by layout test mode. | 138 // This is logic from RenderThemeMac.mm, and is used by layout test mode. |
120 static ControlSize controlSizeForFont(RenderStyle* style) | 139 static ControlSize controlSizeForFont(RenderStyle* style) |
121 { | 140 { |
122 if (style->fontSize() >= 16) { | 141 if (style->fontSize() >= 16) { |
123 return RegularControlSize; | 142 return RegularControlSize; |
124 } else if (style->fontSize() >= 11) { | 143 } else if (style->fontSize() >= 11) { |
125 return SmallControlSize; | 144 return SmallControlSize; |
126 } | 145 } |
127 return MiniControlSize; | 146 return MiniControlSize; |
128 } | 147 } |
129 | 148 |
130 RenderTheme* theme() | |
131 { | |
132 static RenderThemeWin winTheme; | |
133 return &winTheme; | |
134 } | |
135 | |
136 RenderThemeWin::RenderThemeWin() | |
137 { | |
138 } | |
139 | |
140 RenderThemeWin::~RenderThemeWin() | |
141 { | |
142 } | |
143 | |
144 Color RenderThemeWin::platformActiveSelectionBackgroundColor() const | |
145 { | |
146 if (ChromiumBridge::layoutTestMode()) | |
147 return Color("#0000FF"); // Royal blue | |
148 COLORREF color = GetSysColor(COLOR_HIGHLIGHT); | |
149 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
150 } | |
151 | |
152 Color RenderThemeWin::platformInactiveSelectionBackgroundColor() const | |
153 { | |
154 if (ChromiumBridge::layoutTestMode()) | |
155 return Color("#999999"); // Medium grey | |
156 COLORREF color = GetSysColor(COLOR_GRAYTEXT); | |
157 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
158 } | |
159 | |
160 Color RenderThemeWin::platformActiveSelectionForegroundColor() const | |
161 { | |
162 if (ChromiumBridge::layoutTestMode()) | |
163 return Color("#FFFFCC"); // Pale yellow | |
164 COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT); | |
165 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); | |
166 } | |
167 | |
168 Color RenderThemeWin::platformInactiveSelectionForegroundColor() const | |
169 { | |
170 return Color::white; | |
171 } | |
172 | |
173 static float systemFontSizeForControlSize(ControlSize controlSize) | 149 static float systemFontSizeForControlSize(ControlSize controlSize) |
174 { | 150 { |
175 static float sizes[] = { 13.0f, 11.0f, 9.0f }; | 151 static float sizes[] = { 13.0f, 11.0f, 9.0f }; |
176 | 152 |
177 return sizes[controlSize]; | 153 return sizes[controlSize]; |
178 } | 154 } |
179 | 155 |
180 // This is basically RenderThemeMac::setFontFromControlSize | 156 // This is basically RenderThemeMac::setFontFromControlSize |
181 static int layoutTestSetFontFromControlSize(CSSStyleSelector* selector, RenderSt
yle* style) | 157 static int layoutTestSetFontFromControlSize(CSSStyleSelector* selector, RenderSt
yle* style) |
182 { | 158 { |
183 FontDescription fontDescription; | 159 FontDescription fontDescription; |
184 fontDescription.setIsAbsoluteSize(true); | 160 fontDescription.setIsAbsoluteSize(true); |
185 fontDescription.setGenericFamily(FontDescription::SerifFamily); | 161 fontDescription.setGenericFamily(FontDescription::SerifFamily); |
186 | 162 |
187 float fontSize = systemFontSizeForControlSize(controlSizeForFont(style)); | 163 float fontSize = systemFontSizeForControlSize(controlSizeForFont(style)); |
188 fontDescription.firstFamily().setFamily("Lucida Grande"); | 164 fontDescription.firstFamily().setFamily("Lucida Grande"); |
189 | 165 |
190 fontDescription.setComputedSize(fontSize); | 166 fontDescription.setComputedSize(fontSize); |
191 fontDescription.setSpecifiedSize(fontSize); | 167 fontDescription.setSpecifiedSize(fontSize); |
192 | 168 |
193 // Reset line height | 169 // Reset line height |
194 style->setLineHeight(RenderStyle::initialLineHeight()); | 170 style->setLineHeight(RenderStyle::initialLineHeight()); |
195 | 171 |
196 style->setFontDescription(fontDescription); | 172 style->setFontDescription(fontDescription); |
197 style->font().update(0); | 173 style->font().update(0); |
198 | 174 |
199 return 0; | 175 return 0; |
200 } | 176 } |
201 | 177 |
202 // Return the height of system font |font| in pixels. We use this size by | 178 // Return the height of system font |font| in pixels. We use this size by |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 // once GetFontFamilyForScript is enhanced to support GenericFamilyType for | 226 // once GetFontFamilyForScript is enhanced to support GenericFamilyType for |
251 // real. For now, we make sure that we use Arial to match IE for those | 227 // real. For now, we make sure that we use Arial to match IE for those |
252 // scripts. | 228 // scripts. |
253 if (dominantScript != USCRIPT_LATIN && | 229 if (dominantScript != USCRIPT_LATIN && |
254 dominantScript != USCRIPT_CYRILLIC && | 230 dominantScript != USCRIPT_CYRILLIC && |
255 dominantScript != USCRIPT_GREEK && | 231 dominantScript != USCRIPT_GREEK && |
256 dominantScript != USCRIPT_INVALID_CODE) { | 232 dominantScript != USCRIPT_INVALID_CODE) { |
257 family = GetFontFamilyForScript(dominantScript, GENERIC_FAMILY_NONE); | 233 family = GetFontFamilyForScript(dominantScript, GENERIC_FAMILY_NONE); |
258 if (family) | 234 if (family) |
259 return const_cast<wchar_t*>(family); | 235 return const_cast<wchar_t*>(family); |
260 } | 236 } |
261 return L"Arial"; | 237 return L"Arial"; |
262 } | 238 } |
263 | 239 |
264 // Converts |points| to pixels. One point is 1/72 of an inch. | 240 // Converts |points| to pixels. One point is 1/72 of an inch. |
265 static float pointsToPixels(float points) | 241 static float pointsToPixels(float points) |
266 { | 242 { |
267 static float pixelsPerInch = 0.0f; | 243 static float pixelsPerInch = 0.0f; |
268 if (!pixelsPerInch) { | 244 if (!pixelsPerInch) { |
269 HDC hdc = GetDC(0); // What about printing? Is this the right DC? | 245 HDC hdc = GetDC(0); // What about printing? Is this the right DC? |
270 if (hdc) { // Can this ever actually be NULL? | 246 if (hdc) { // Can this ever actually be NULL? |
271 pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY); | 247 pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY); |
272 ReleaseDC(0, hdc); | 248 ReleaseDC(0, hdc); |
273 } else { | 249 } else { |
274 pixelsPerInch = 96.0f; | 250 pixelsPerInch = 96.0f; |
275 } | 251 } |
276 } | 252 } |
277 | 253 |
278 static const float POINTS_PER_INCH = 72.0f; | 254 static const float POINTS_PER_INCH = 72.0f; |
279 return points / POINTS_PER_INCH * pixelsPerInch; | 255 return points / POINTS_PER_INCH * pixelsPerInch; |
280 } | 256 } |
281 | 257 |
| 258 static void setSizeIfAuto(RenderStyle* style, const IntSize& size) |
| 259 { |
| 260 if (style->width().isIntrinsicOrAuto()) |
| 261 style->setWidth(Length(size.width(), Fixed)); |
| 262 if (style->height().isAuto()) |
| 263 style->setHeight(Length(size.height(), Fixed)); |
| 264 } |
| 265 |
| 266 static IntSize layoutTestCheckboxSize(RenderStyle* style) |
| 267 { |
| 268 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(
10, 10) }; |
| 269 return sizes[controlSizeForFont(style)]; |
| 270 } |
| 271 |
| 272 static IntSize layoutTestRadioboxSize(RenderStyle* style) |
| 273 { |
| 274 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(
10, 10) }; |
| 275 return sizes[controlSizeForFont(style)]; |
| 276 } |
| 277 |
| 278 // Hacks for using Mac menu list metrics when in layout test mode. |
| 279 static int layoutTestMenuListInternalPadding(RenderStyle* style, int paddingType
) |
| 280 { |
| 281 if (style->appearance() == MenulistPart) { |
| 282 return kLayoutTestMenuListInternalPadding[controlSizeForFont(style)][pad
dingType]; |
| 283 } |
| 284 if (style->appearance() == MenulistButtonPart) { |
| 285 if (paddingType == RightPadding) { |
| 286 const float baseArrowWidth = 5.0f; |
| 287 float fontScale = style->fontSize() / kLayoutTestBaseFontSize; |
| 288 float arrowWidth = ceilf(baseArrowWidth * fontScale); |
| 289 |
| 290 int arrowPaddingLeft = 6; |
| 291 int arrowPaddingRight = 6; |
| 292 int paddingBeforeSeparator = 4; |
| 293 // Add 2 for separator space, seems to match RenderThemeMac::paintMe
nuListButton. |
| 294 return static_cast<int>(arrowWidth + arrowPaddingLeft + arrowPadding
Right + |
| 295 paddingBeforeSeparator); |
| 296 } else { |
| 297 return kLayoutTestStyledMenuListInternalPadding[paddingType]; |
| 298 } |
| 299 } |
| 300 return 0; |
| 301 } |
| 302 |
| 303 static const IntSize* layoutTestCancelButtonSizes() |
| 304 { |
| 305 static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(
13, 9) }; |
| 306 return sizes; |
| 307 } |
| 308 |
| 309 static const IntSize* layoutTestResultsButtonSizes() |
| 310 { |
| 311 static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(
17, 9) }; |
| 312 return sizes; |
| 313 } |
| 314 |
| 315 // Implement WebCore::theme() for getting the global RenderTheme. |
| 316 RenderTheme* theme() |
| 317 { |
| 318 static RenderThemeWin winTheme; |
| 319 return &winTheme; |
| 320 } |
| 321 |
| 322 bool RenderThemeWin::supportsFocusRing(const RenderStyle* style) const |
| 323 { |
| 324 // Let webkit draw one of its halo rings around any focused element, |
| 325 // except push buttons. For buttons we use the windows PBS_DEFAULTED |
| 326 // styling to give it a blue border. |
| 327 return style->appearance() == ButtonPart || |
| 328 style->appearance() == PushButtonPart; |
| 329 } |
| 330 |
| 331 Color RenderThemeWin::platformActiveSelectionBackgroundColor() const |
| 332 { |
| 333 if (ChromiumBridge::layoutTestMode()) |
| 334 return Color("#0000FF"); // Royal blue |
| 335 COLORREF color = GetSysColor(COLOR_HIGHLIGHT); |
| 336 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); |
| 337 } |
| 338 |
| 339 Color RenderThemeWin::platformInactiveSelectionBackgroundColor() const |
| 340 { |
| 341 if (ChromiumBridge::layoutTestMode()) |
| 342 return Color("#999999"); // Medium grey |
| 343 COLORREF color = GetSysColor(COLOR_GRAYTEXT); |
| 344 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); |
| 345 } |
| 346 |
| 347 Color RenderThemeWin::platformActiveSelectionForegroundColor() const |
| 348 { |
| 349 if (ChromiumBridge::layoutTestMode()) |
| 350 return Color("#FFFFCC"); // Pale yellow |
| 351 COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT); |
| 352 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); |
| 353 } |
| 354 |
| 355 Color RenderThemeWin::platformInactiveSelectionForegroundColor() const |
| 356 { |
| 357 return Color::white; |
| 358 } |
| 359 |
282 double RenderThemeWin::caretBlinkFrequency() const | 360 double RenderThemeWin::caretBlinkFrequency() const |
283 { | 361 { |
284 // Disable the blinking caret in layout test mode, as it introduces | 362 // Disable the blinking caret in layout test mode, as it introduces |
285 // a race condition for the pixel tests. http://b/1198440 | 363 // a race condition for the pixel tests. http://b/1198440 |
286 if (ChromiumBridge::layoutTestMode()) | 364 if (ChromiumBridge::layoutTestMode()) |
287 return 0; | 365 return 0; |
288 | 366 |
289 // TODO(ericroman): this should be using the platform's blink frequency. | 367 // TODO(ericroman): this should be using the platform's blink frequency. |
290 return RenderTheme::caretBlinkFrequency(); | 368 return RenderTheme::caretBlinkFrequency(); |
291 } | 369 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 } | 462 } |
385 cachedDesc->setIsAbsoluteSize(true); | 463 cachedDesc->setIsAbsoluteSize(true); |
386 cachedDesc->setGenericFamily(FontDescription::NoFamily); | 464 cachedDesc->setGenericFamily(FontDescription::NoFamily); |
387 cachedDesc->setSpecifiedSize(fontSize); | 465 cachedDesc->setSpecifiedSize(fontSize); |
388 cachedDesc->setWeight(FontWeightNormal); | 466 cachedDesc->setWeight(FontWeightNormal); |
389 cachedDesc->setItalic(false); | 467 cachedDesc->setItalic(false); |
390 } | 468 } |
391 fontDescription = *cachedDesc; | 469 fontDescription = *cachedDesc; |
392 } | 470 } |
393 | 471 |
394 static bool supportsFocus(ControlPart appearance) | |
395 { | |
396 switch (appearance) { | |
397 case PushButtonPart: | |
398 case ButtonPart: | |
399 case DefaultButtonPart: | |
400 case TextFieldPart: | |
401 case TextAreaPart: | |
402 return true; | |
403 default: | |
404 return false; | |
405 } | |
406 | |
407 return false; | |
408 } | |
409 | |
410 bool RenderThemeWin::supportsFocusRing(const RenderStyle* style) const | |
411 { | |
412 // Let webkit draw one of its halo rings around any focused element, | |
413 // except push buttons. For buttons we use the windows PBS_DEFAULTED | |
414 // styling to give it a blue border. | |
415 return style->appearance() == ButtonPart || | |
416 style->appearance() == PushButtonPart; | |
417 } | |
418 | |
419 unsigned RenderThemeWin::determineState(RenderObject* o) | |
420 { | |
421 unsigned result = TS_NORMAL; | |
422 ControlPart appearance = o->style()->appearance(); | |
423 if (!isEnabled(o)) | |
424 result = TS_DISABLED; | |
425 else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPar
t == appearance)) | |
426 result = ETS_READONLY; // Readonly is supported on textfields. | |
427 else if (isPressed(o)) // Active overrides hover and focused. | |
428 result = TS_PRESSED; | |
429 else if (supportsFocus(appearance) && isFocused(o)) | |
430 result = ETS_FOCUSED; | |
431 else if (isHovered(o)) | |
432 result = TS_HOT; | |
433 if (isChecked(o)) | |
434 result += 4; // 4 unchecked states, 4 checked states. | |
435 return result; | |
436 } | |
437 | |
438 unsigned RenderThemeWin::determineClassicState(RenderObject* o) | |
439 { | |
440 unsigned result = 0; | |
441 if (!isEnabled(o)) | |
442 result = DFCS_INACTIVE; | |
443 else if (isPressed(o)) // Active supersedes hover | |
444 result = DFCS_PUSHED; | |
445 else if (isHovered(o)) | |
446 result = DFCS_HOT; | |
447 if (isChecked(o)) | |
448 result |= DFCS_CHECKED; | |
449 return result; | |
450 } | |
451 | |
452 ThemeData RenderThemeWin::getThemeData(RenderObject* o) | |
453 { | |
454 ThemeData result; | |
455 switch (o->style()->appearance()) { | |
456 case PushButtonPart: | |
457 case ButtonPart: | |
458 result.m_part = BP_PUSHBUTTON; | |
459 result.m_classicState = DFCS_BUTTONPUSH; | |
460 break; | |
461 case CheckboxPart: | |
462 result.m_part = BP_CHECKBOX; | |
463 result.m_classicState = DFCS_BUTTONCHECK; | |
464 break; | |
465 case RadioPart: | |
466 result.m_part = BP_RADIOBUTTON; | |
467 result.m_classicState = DFCS_BUTTONRADIO; | |
468 break; | |
469 case ListboxPart: | |
470 case MenulistPart: | |
471 case TextFieldPart: | |
472 case TextAreaPart: | |
473 result.m_part = ETS_NORMAL; | |
474 break; | |
475 } | |
476 | |
477 result.m_state = determineState(o); | |
478 result.m_classicState |= determineClassicState(o); | |
479 | |
480 return result; | |
481 } | |
482 | |
483 bool RenderThemeWin::paintButton(RenderObject* o, | |
484 const RenderObject::PaintInfo& i, | |
485 const IntRect& r) | |
486 { | |
487 const ThemeData& themeData = getThemeData(o); | |
488 | |
489 WebCore::ThemeHelperWin helper(i.context, r); | |
490 gfx::PlatformCanvas* canvas = helper.context()->platformContext()->canvas(); | |
491 | |
492 HDC hdc = canvas->beginPlatformPaint(); | |
493 int state = themeData.m_state; | |
494 RECT renderRect = helper.rect(); | |
495 | |
496 gfx::NativeTheme::instance()->PaintButton(hdc, | |
497 themeData.m_part, | |
498 state, | |
499 themeData.m_classicState, | |
500 &renderRect); | |
501 canvas->endPlatformPaint(); | |
502 return false; | |
503 } | |
504 | |
505 static void setSizeIfAuto(RenderStyle* style, const IntSize& size) | |
506 { | |
507 if (style->width().isIntrinsicOrAuto()) | |
508 style->setWidth(Length(size.width(), Fixed)); | |
509 if (style->height().isAuto()) | |
510 style->setHeight(Length(size.height(), Fixed)); | |
511 } | |
512 | |
513 int RenderThemeWin::minimumMenuListSize(RenderStyle* style) const | 472 int RenderThemeWin::minimumMenuListSize(RenderStyle* style) const |
514 { | 473 { |
515 if (ChromiumBridge::layoutTestMode()) { | 474 if (ChromiumBridge::layoutTestMode()) { |
516 return kLayoutTestMenuListMinimumWidth[controlSizeForFont(style)]; | 475 return kLayoutTestMenuListMinimumWidth[controlSizeForFont(style)]; |
517 } else { | 476 } else { |
518 return 0; | 477 return 0; |
519 } | 478 } |
520 } | 479 } |
521 | 480 |
522 static IntSize layoutTestCheckboxSize(RenderStyle* style) | |
523 { | |
524 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(
10, 10) }; | |
525 return sizes[controlSizeForFont(style)]; | |
526 } | |
527 | |
528 static IntSize layoutTestRadioboxSize(RenderStyle* style) | |
529 { | |
530 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(
10, 10) }; | |
531 return sizes[controlSizeForFont(style)]; | |
532 } | |
533 | |
534 void RenderThemeWin::setCheckboxSize(RenderStyle* style) const | 481 void RenderThemeWin::setCheckboxSize(RenderStyle* style) const |
535 { | 482 { |
536 // If the width and height are both specified, then we have nothing to do. | 483 // If the width and height are both specified, then we have nothing to do. |
537 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) | 484 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) |
538 return; | 485 return; |
539 | 486 |
540 // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for
now. It matches Firefox. | 487 // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for
now. It matches Firefox. |
541 // At different DPI settings on Windows, querying the theme gives you a larg
er size that accounts for | 488 // At different DPI settings on Windows, querying the theme gives you a larg
er size that accounts for |
542 // the higher DPI. Until our entire engine honors a DPI setting other than
96, we can't rely on the theme's | 489 // the higher DPI. Until our entire engine honors a DPI setting other than
96, we can't rely on the theme's |
543 // metrics. | 490 // metrics. |
544 const IntSize size = ChromiumBridge::layoutTestMode() ? | 491 const IntSize size = ChromiumBridge::layoutTestMode() ? |
545 layoutTestCheckboxSize(style) : IntSize(13, 13); | 492 layoutTestCheckboxSize(style) : IntSize(13, 13); |
546 setSizeIfAuto(style, size); | 493 setSizeIfAuto(style, size); |
547 } | 494 } |
548 | 495 |
549 void RenderThemeWin::setRadioSize(RenderStyle* style) const | 496 void RenderThemeWin::setRadioSize(RenderStyle* style) const |
550 { | 497 { |
551 if (ChromiumBridge::layoutTestMode()) { | 498 if (ChromiumBridge::layoutTestMode()) { |
552 setSizeIfAuto(style, layoutTestRadioboxSize(style)); | 499 setSizeIfAuto(style, layoutTestRadioboxSize(style)); |
553 } else { | 500 } else { |
554 // Use same sizing for radio box as checkbox. | 501 // Use same sizing for radio box as checkbox. |
555 setCheckboxSize(style); | 502 setCheckboxSize(style); |
556 } | 503 } |
557 } | 504 } |
558 | 505 |
| 506 bool RenderThemeWin::paintButton(RenderObject* o, |
| 507 const RenderObject::PaintInfo& i, |
| 508 const IntRect& r) |
| 509 { |
| 510 const ThemeData& themeData = getThemeData(o); |
| 511 |
| 512 WebCore::ThemeHelperWin helper(i.context, r); |
| 513 gfx::PlatformCanvas* canvas = helper.context()->platformContext()->canvas(); |
| 514 |
| 515 HDC hdc = canvas->beginPlatformPaint(); |
| 516 int state = themeData.m_state; |
| 517 RECT renderRect = helper.rect(); |
| 518 |
| 519 gfx::NativeTheme::instance()->PaintButton(hdc, |
| 520 themeData.m_part, |
| 521 state, |
| 522 themeData.m_classicState, |
| 523 &renderRect); |
| 524 canvas->endPlatformPaint(); |
| 525 return false; |
| 526 } |
| 527 |
559 bool RenderThemeWin::paintTextField(RenderObject* o, const RenderObject::PaintIn
fo& i, const IntRect& r) | 528 bool RenderThemeWin::paintTextField(RenderObject* o, const RenderObject::PaintIn
fo& i, const IntRect& r) |
560 { | 529 { |
561 return paintTextFieldInternal(o, i, r, true); | 530 return paintTextFieldInternal(o, i, r, true); |
562 } | 531 } |
563 | 532 |
564 bool RenderThemeWin::paintTextFieldInternal(RenderObject* o, | |
565 const RenderObject::PaintInfo& i, | |
566 const IntRect& r, | |
567 bool drawEdges) | |
568 { | |
569 // Nasty hack to make us not paint the border on text fields with a | |
570 // border-radius. Webkit paints elements with border-radius for us. | |
571 // TODO(ojan): Get rid of this if-check once we can properly clip rounded | |
572 // borders: http://b/1112604 and http://b/1108635 | |
573 // TODO(ojan): make sure we do the right thing if css background-clip is | |
574 // set. | |
575 if (o->style()->hasBorderRadius()) | |
576 return false; | |
577 | |
578 const ThemeData& themeData = getThemeData(o); | |
579 | |
580 WebCore::ThemeHelperWin helper(i.context, r); | |
581 gfx::PlatformCanvas* canvas = helper.context()->platformContext()->canvas(); | |
582 | |
583 HDC hdc = canvas->beginPlatformPaint(); | |
584 COLORREF clr = gfx::SkColorToCOLORREF(o->style()->backgroundColor().rgb()); | |
585 RECT renderRect = helper.rect(); | |
586 | |
587 gfx::NativeTheme::instance()->PaintTextField(hdc, | |
588 themeData.m_part, | |
589 themeData.m_state, | |
590 themeData.m_classicState, | |
591 &renderRect, | |
592 clr, | |
593 true, | |
594 drawEdges); | |
595 canvas->endPlatformPaint(); | |
596 return false; | |
597 } | |
598 | |
599 bool RenderThemeWin::paintSearchField(RenderObject* o, const RenderObject::Paint
Info& i, const IntRect& r) | 533 bool RenderThemeWin::paintSearchField(RenderObject* o, const RenderObject::Paint
Info& i, const IntRect& r) |
600 { | 534 { |
601 return paintTextField(o, i, r); | 535 return paintTextField(o, i, r); |
602 } | 536 } |
603 | 537 |
604 void RenderThemeWin::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle
* style, Element* e) const | 538 void RenderThemeWin::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle
* style, Element* e) const |
605 { | 539 { |
606 // Height is locked to auto on all browsers. | 540 // Height is locked to auto on all browsers. |
607 style->setLineHeight(RenderStyle::initialLineHeight()); | 541 style->setLineHeight(RenderStyle::initialLineHeight()); |
608 | 542 |
609 if (ChromiumBridge::layoutTestMode()) { | 543 if (ChromiumBridge::layoutTestMode()) { |
610 style->resetBorder(); | 544 style->resetBorder(); |
611 style->setHeight(Length(Auto)); | 545 style->setHeight(Length(Auto)); |
612 // Select one of the 3 fixed heights for controls | 546 // Select one of the 3 fixed heights for controls |
613 style->resetPadding(); | 547 style->resetPadding(); |
614 if (style->height().isAuto()) { | 548 if (style->height().isAuto()) { |
615 // RenderThemeMac locks the size to 3 distinct values (NSControlSize
). | 549 // RenderThemeMac locks the size to 3 distinct values (NSControlSize
). |
616 // We on the other hand, base the height off the font. | 550 // We on the other hand, base the height off the font. |
617 int fixedHeight = kLayoutTestControlHeight[controlSizeForFont(style)
]; | 551 int fixedHeight = kLayoutTestControlHeight[controlSizeForFont(style)
]; |
618 style->setHeight(Length(fixedHeight, Fixed)); | 552 style->setHeight(Length(fixedHeight, Fixed)); |
619 } | 553 } |
620 layoutTestSetFontFromControlSize(selector, style); | 554 layoutTestSetFontFromControlSize(selector, style); |
621 } | 555 } |
622 } | 556 } |
623 | 557 |
624 void RenderThemeWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, Rende
rStyle* style, Element* e) const | |
625 { | |
626 adjustMenuListStyle(selector, style, e); | |
627 } | |
628 | |
629 // Used to paint unstyled menulists (i.e. with the default border) | 558 // Used to paint unstyled menulists (i.e. with the default border) |
630 bool RenderThemeWin::paintMenuList(RenderObject* o, const RenderObject::PaintInf
o& i, const IntRect& r) | 559 bool RenderThemeWin::paintMenuList(RenderObject* o, const RenderObject::PaintInf
o& i, const IntRect& r) |
631 { | 560 { |
632 int borderRight = o->borderRight(); | 561 int borderRight = o->borderRight(); |
633 int borderLeft = o->borderLeft(); | 562 int borderLeft = o->borderLeft(); |
634 int borderTop = o->borderTop(); | 563 int borderTop = o->borderTop(); |
635 int borderBottom = o->borderBottom(); | 564 int borderBottom = o->borderBottom(); |
636 | 565 |
637 // If all the borders are 0, then tell skia not to paint the border on the t
extfield. | 566 // If all the borders are 0, then tell skia not to paint the border on the t
extfield. |
638 // TODO(ojan): http://b/1210017 Figure out how to get Windows to not draw in
dividual | 567 // TODO(ojan): http://b/1210017 Figure out how to get Windows to not draw in
dividual |
639 // borders and then pass that to skia so we can avoid drawing any borders th
at are | 568 // borders and then pass that to skia so we can avoid drawing any borders th
at are |
640 // set to 0. For non-zero borders, we draw the border, but webkit just draws | 569 // set to 0. For non-zero borders, we draw the border, but webkit just draws |
641 // over it. | 570 // over it. |
642 // TODO(ojan): layout-test-mode removes borders, so we end up never drawing | 571 // TODO(ojan): layout-test-mode removes borders, so we end up never drawing |
643 // edges in layout-test-mode. See adjustMenuListStyle, style->resetBorder(). | 572 // edges in layout-test-mode. See adjustMenuListStyle, style->resetBorder(). |
644 // We really need to remove the layout-test-mode only hacks. | 573 // We really need to remove the layout-test-mode only hacks. |
645 bool drawEdges = !(borderRight == 0 && borderLeft == 0 && borderTop == 0 &&
borderBottom == 0); | 574 bool drawEdges = !(borderRight == 0 && borderLeft == 0 && borderTop == 0 &&
borderBottom == 0); |
646 | 575 |
647 paintTextFieldInternal(o, i, r, drawEdges); | 576 paintTextFieldInternal(o, i, r, drawEdges); |
648 | 577 |
649 // Take padding and border into account. | 578 // Take padding and border into account. |
650 // If the MenuList is smaller than the size of a button, make sure to | 579 // If the MenuList is smaller than the size of a button, make sure to |
651 // shrink it appropriately and not put its x position to the left of | 580 // shrink it appropriately and not put its x position to the left of |
652 // the menulist. | 581 // the menulist. |
653 const int buttonWidth = ChromiumBridge::layoutTestMode() ? | 582 const int buttonWidth = ChromiumBridge::layoutTestMode() ? |
654 kLayoutTestMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL); | 583 kLayoutTestMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL); |
655 int spacingLeft = borderLeft + o->paddingLeft(); | 584 int spacingLeft = borderLeft + o->paddingLeft(); |
656 int spacingRight = borderRight + o->paddingRight(); | 585 int spacingRight = borderRight + o->paddingRight(); |
657 int spacingTop = borderTop + o->paddingTop(); | 586 int spacingTop = borderTop + o->paddingTop(); |
658 int spacingBottom = borderBottom + o->paddingBottom(); | 587 int spacingBottom = borderBottom + o->paddingBottom(); |
659 | 588 |
660 int buttonX; | 589 int buttonX; |
661 if (r.right() - r.x() < buttonWidth) { | 590 if (r.right() - r.x() < buttonWidth) { |
(...skipping 15 matching lines...) Expand all Loading... |
677 RECT renderRect = helper.rect(); | 606 RECT renderRect = helper.rect(); |
678 gfx::NativeTheme::instance()->PaintMenuList(hdc, | 607 gfx::NativeTheme::instance()->PaintMenuList(hdc, |
679 CP_DROPDOWNBUTTON, | 608 CP_DROPDOWNBUTTON, |
680 determineState(o), | 609 determineState(o), |
681 determineClassicState(o), | 610 determineClassicState(o), |
682 &renderRect); | 611 &renderRect); |
683 canvas->endPlatformPaint(); | 612 canvas->endPlatformPaint(); |
684 return false; | 613 return false; |
685 } | 614 } |
686 | 615 |
| 616 void RenderThemeWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, Rende
rStyle* style, Element* e) const |
| 617 { |
| 618 adjustMenuListStyle(selector, style, e); |
| 619 } |
| 620 |
687 // Used to paint styled menulists (i.e. with a non-default border) | 621 // Used to paint styled menulists (i.e. with a non-default border) |
688 bool RenderThemeWin::paintMenuListButton(RenderObject* o, const RenderObject::Pa
intInfo& i, const IntRect& r) | 622 bool RenderThemeWin::paintMenuListButton(RenderObject* o, const RenderObject::Pa
intInfo& i, const IntRect& r) |
689 { | 623 { |
690 return paintMenuList(o, i, r); | 624 return paintMenuList(o, i, r); |
691 } | 625 } |
692 | 626 |
693 int RenderThemeWin::popupInternalPaddingLeft(RenderStyle* style) const | 627 int RenderThemeWin::popupInternalPaddingLeft(RenderStyle* style) const |
694 { | 628 { |
695 return menuListInternalPadding(style, LeftPadding); | 629 return menuListInternalPadding(style, LeftPadding); |
696 } | 630 } |
697 | 631 |
698 int RenderThemeWin::popupInternalPaddingRight(RenderStyle* style) const | 632 int RenderThemeWin::popupInternalPaddingRight(RenderStyle* style) const |
699 { | 633 { |
700 return menuListInternalPadding(style, RightPadding); | 634 return menuListInternalPadding(style, RightPadding); |
701 } | 635 } |
702 | 636 |
703 int RenderThemeWin::popupInternalPaddingTop(RenderStyle* style) const | 637 int RenderThemeWin::popupInternalPaddingTop(RenderStyle* style) const |
704 { | 638 { |
705 return menuListInternalPadding(style, TopPadding); | 639 return menuListInternalPadding(style, TopPadding); |
706 } | 640 } |
707 | 641 |
708 int RenderThemeWin::popupInternalPaddingBottom(RenderStyle* style) const | 642 int RenderThemeWin::popupInternalPaddingBottom(RenderStyle* style) const |
709 { | 643 { |
710 return menuListInternalPadding(style, BottomPadding); | 644 return menuListInternalPadding(style, BottomPadding); |
711 } | 645 } |
712 | 646 |
713 // Hacks for using Mac menu list metrics when in layout test mode. | 647 void RenderThemeWin::adjustButtonInnerStyle(RenderStyle* style) const |
714 static int layoutTestMenuListInternalPadding(RenderStyle* style, int paddingType
) | |
715 { | 648 { |
716 if (style->appearance() == MenulistPart) { | |
717 return kLayoutTestMenuListInternalPadding[controlSizeForFont(style)][pad
dingType]; | |
718 } | |
719 if (style->appearance() == MenulistButtonPart) { | |
720 if (paddingType == RightPadding) { | |
721 const float baseArrowWidth = 5.0f; | |
722 float fontScale = style->fontSize() / kLayoutTestBaseFontSize; | |
723 float arrowWidth = ceilf(baseArrowWidth * fontScale); | |
724 | |
725 int arrowPaddingLeft = 6; | |
726 int arrowPaddingRight = 6; | |
727 int paddingBeforeSeparator = 4; | |
728 // Add 2 for separator space, seems to match RenderThemeMac::paintMe
nuListButton. | |
729 return static_cast<int>(arrowWidth + arrowPaddingLeft + arrowPadding
Right + | |
730 paddingBeforeSeparator); | |
731 } else { | |
732 return kLayoutTestStyledMenuListInternalPadding[paddingType]; | |
733 } | |
734 } | |
735 return 0; | |
736 } | |
737 | |
738 int RenderThemeWin::menuListInternalPadding(RenderStyle* style, int paddingType)
const | |
739 { | |
740 if (ChromiumBridge::layoutTestMode()) { | |
741 return layoutTestMenuListInternalPadding(style, paddingType); | |
742 } | |
743 | |
744 // This internal padding is in addition to the user-supplied padding. | |
745 // Matches the FF behavior. | |
746 int padding = kStyledMenuListInternalPadding[paddingType]; | |
747 | |
748 // Reserve the space for right arrow here. The rest of the padding is | |
749 // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from | |
750 // RenderMenuList to lay out the individual items in the popup. | |
751 // If the MenuList actually has appearance "NoAppearance", then that means | |
752 // we don't draw a button, so don't reserve space for it. | |
753 const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding; | |
754 if (paddingType == bar_type && style->appearance() != NoPart) | |
755 padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); | |
756 | |
757 return padding; | |
758 } | |
759 | |
760 void RenderThemeWin::adjustButtonInnerStyle(RenderStyle* style) const | |
761 { | |
762 // This inner padding matches Firefox. | 649 // This inner padding matches Firefox. |
763 style->setPaddingTop(Length(1, Fixed)); | 650 style->setPaddingTop(Length(1, Fixed)); |
764 style->setPaddingRight(Length(3, Fixed)); | 651 style->setPaddingRight(Length(3, Fixed)); |
765 style->setPaddingBottom(Length(1, Fixed)); | 652 style->setPaddingBottom(Length(1, Fixed)); |
766 style->setPaddingLeft(Length(3, Fixed)); | 653 style->setPaddingLeft(Length(3, Fixed)); |
767 } | 654 } |
768 | 655 |
769 void RenderThemeWin::setButtonPadding(RenderStyle* style) const | |
770 { | |
771 if (ChromiumBridge::layoutTestMode()) { | |
772 setFixedPadding(style, kLayoutTestButtonPadding); | |
773 | |
774 } else if (!style->width().isAuto()) { | |
775 // We need to set the minimum padding for the buttons, or else they | |
776 // render too small and clip the button face text. The right way to do | |
777 // this is to ask window's theme manager to give us the minimum | |
778 // (TS_MIN) size for the part. As a failsafe we set at least | |
779 // kDefaultButtonPadding because zero just looks bad. | |
780 Length minXPadding(kDefaultButtonPadding, Fixed); | |
781 Length minYPadding(kDefaultButtonPadding, Fixed); | |
782 // Find minimum padding. | |
783 getMinimalButtonPadding(&minXPadding); | |
784 | |
785 // Set the minimum padding. | |
786 if (style->paddingLeft().value() < minXPadding.value()) { | |
787 style->setPaddingLeft(minXPadding); | |
788 } | |
789 if (style->paddingRight().value() < minXPadding.value()) { | |
790 style->setPaddingRight(minXPadding); | |
791 } | |
792 if (style->paddingBottom().value() < minYPadding.value()) { | |
793 style->setPaddingBottom(minYPadding); | |
794 } | |
795 if (style->paddingTop().value() < minYPadding.value()) { | |
796 style->setPaddingTop(minYPadding); | |
797 } | |
798 } | |
799 } | |
800 | |
801 void RenderThemeWin::adjustSliderThumbSize(RenderObject* o) const | 656 void RenderThemeWin::adjustSliderThumbSize(RenderObject* o) const |
802 { | 657 { |
803 if (ChromiumBridge::layoutTestMode()) { | 658 if (ChromiumBridge::layoutTestMode()) { |
804 if (o->style()->appearance() == SliderThumbHorizontalPart || | 659 if (o->style()->appearance() == SliderThumbHorizontalPart || |
805 o->style()->appearance() == SliderThumbVerticalPart) { | 660 o->style()->appearance() == SliderThumbVerticalPart) { |
806 o->style()->setWidth(Length(kLayoutTestSliderThumbWidth, Fixed)); | 661 o->style()->setWidth(Length(kLayoutTestSliderThumbWidth, Fixed)); |
807 o->style()->setHeight(Length(kLayoutTestSliderThumbHeight, Fixed)); | 662 o->style()->setHeight(Length(kLayoutTestSliderThumbHeight, Fixed)); |
808 } | 663 } |
809 } | 664 } |
810 } | 665 } |
(...skipping 20 matching lines...) Expand all Loading... |
831 // Override padding size to match AppKit text positioning. | 686 // Override padding size to match AppKit text positioning. |
832 style->setPaddingLeft(Length(kLayoutTestSearchFieldPadding, Fixed)); | 687 style->setPaddingLeft(Length(kLayoutTestSearchFieldPadding, Fixed)); |
833 style->setPaddingRight(Length(kLayoutTestSearchFieldPadding, Fixed)); | 688 style->setPaddingRight(Length(kLayoutTestSearchFieldPadding, Fixed)); |
834 style->setPaddingTop(Length(kLayoutTestSearchFieldPadding, Fixed)); | 689 style->setPaddingTop(Length(kLayoutTestSearchFieldPadding, Fixed)); |
835 style->setPaddingBottom(Length(kLayoutTestSearchFieldPadding, Fixed)); | 690 style->setPaddingBottom(Length(kLayoutTestSearchFieldPadding, Fixed)); |
836 | 691 |
837 style->setBoxShadow(0); | 692 style->setBoxShadow(0); |
838 } | 693 } |
839 } | 694 } |
840 | 695 |
841 static const IntSize* layoutTestCancelButtonSizes() | |
842 { | |
843 static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(
13, 9) }; | |
844 return sizes; | |
845 } | |
846 | |
847 static const IntSize* layoutTestResultsButtonSizes() | |
848 { | |
849 static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(
17, 9) }; | |
850 return sizes; | |
851 } | |
852 | |
853 void RenderThemeWin::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select
or, RenderStyle* style, Element* e) const | 696 void RenderThemeWin::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select
or, RenderStyle* style, Element* e) const |
854 { | 697 { |
855 if (ChromiumBridge::layoutTestMode()) { | 698 if (ChromiumBridge::layoutTestMode()) { |
856 IntSize size = layoutTestCancelButtonSizes()[controlSizeForFont(style)]; | 699 IntSize size = layoutTestCancelButtonSizes()[controlSizeForFont(style)]; |
857 style->setWidth(Length(size.width(), Fixed)); | 700 style->setWidth(Length(size.width(), Fixed)); |
858 style->setHeight(Length(size.height(), Fixed)); | 701 style->setHeight(Length(size.height(), Fixed)); |
859 style->setBoxShadow(0); | 702 style->setBoxShadow(0); |
860 } | 703 } |
861 } | 704 } |
862 | 705 |
(...skipping 20 matching lines...) Expand all Loading... |
883 void RenderThemeWin::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec
tor, RenderStyle* style, Element* e) const | 726 void RenderThemeWin::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec
tor, RenderStyle* style, Element* e) const |
884 { | 727 { |
885 if (ChromiumBridge::layoutTestMode()) { | 728 if (ChromiumBridge::layoutTestMode()) { |
886 IntSize size = layoutTestResultsButtonSizes()[controlSizeForFont(style)]
; | 729 IntSize size = layoutTestResultsButtonSizes()[controlSizeForFont(style)]
; |
887 style->setWidth(Length(size.width() + kLayoutTestResultsArrowWidth, Fixe
d)); | 730 style->setWidth(Length(size.width() + kLayoutTestResultsArrowWidth, Fixe
d)); |
888 style->setHeight(Length(size.height(), Fixed)); | 731 style->setHeight(Length(size.height(), Fixed)); |
889 style->setBoxShadow(0); | 732 style->setBoxShadow(0); |
890 } | 733 } |
891 } | 734 } |
892 | 735 |
| 736 // static |
| 737 void RenderThemeWin::setDefaultFontSize(int fontSize) { |
| 738 DefaultFontSize = static_cast<float>(fontSize); |
| 739 |
| 740 // Reset cached fonts. |
| 741 smallSystemFont = menuFont = labelFont = FontDescription(); |
| 742 } |
| 743 |
| 744 unsigned RenderThemeWin::determineState(RenderObject* o) |
| 745 { |
| 746 unsigned result = TS_NORMAL; |
| 747 ControlPart appearance = o->style()->appearance(); |
| 748 if (!isEnabled(o)) |
| 749 result = TS_DISABLED; |
| 750 else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPar
t == appearance)) |
| 751 result = ETS_READONLY; // Readonly is supported on textfields. |
| 752 else if (isPressed(o)) // Active overrides hover and focused. |
| 753 result = TS_PRESSED; |
| 754 else if (supportsFocus(appearance) && isFocused(o)) |
| 755 result = ETS_FOCUSED; |
| 756 else if (isHovered(o)) |
| 757 result = TS_HOT; |
| 758 if (isChecked(o)) |
| 759 result += 4; // 4 unchecked states, 4 checked states. |
| 760 return result; |
| 761 } |
| 762 |
| 763 unsigned RenderThemeWin::determineClassicState(RenderObject* o) |
| 764 { |
| 765 unsigned result = 0; |
| 766 if (!isEnabled(o)) |
| 767 result = DFCS_INACTIVE; |
| 768 else if (isPressed(o)) // Active supersedes hover |
| 769 result = DFCS_PUSHED; |
| 770 else if (isHovered(o)) |
| 771 result = DFCS_HOT; |
| 772 if (isChecked(o)) |
| 773 result |= DFCS_CHECKED; |
| 774 return result; |
| 775 } |
| 776 |
| 777 ThemeData RenderThemeWin::getThemeData(RenderObject* o) |
| 778 { |
| 779 ThemeData result; |
| 780 switch (o->style()->appearance()) { |
| 781 case PushButtonPart: |
| 782 case ButtonPart: |
| 783 result.m_part = BP_PUSHBUTTON; |
| 784 result.m_classicState = DFCS_BUTTONPUSH; |
| 785 break; |
| 786 case CheckboxPart: |
| 787 result.m_part = BP_CHECKBOX; |
| 788 result.m_classicState = DFCS_BUTTONCHECK; |
| 789 break; |
| 790 case RadioPart: |
| 791 result.m_part = BP_RADIOBUTTON; |
| 792 result.m_classicState = DFCS_BUTTONRADIO; |
| 793 break; |
| 794 case ListboxPart: |
| 795 case MenulistPart: |
| 796 case TextFieldPart: |
| 797 case TextAreaPart: |
| 798 result.m_part = ETS_NORMAL; |
| 799 break; |
| 800 } |
| 801 |
| 802 result.m_state = determineState(o); |
| 803 result.m_classicState |= determineClassicState(o); |
| 804 |
| 805 return result; |
| 806 } |
| 807 |
| 808 bool RenderThemeWin::paintTextFieldInternal(RenderObject* o, |
| 809 const RenderObject::PaintInfo& i, |
| 810 const IntRect& r, |
| 811 bool drawEdges) |
| 812 { |
| 813 // Nasty hack to make us not paint the border on text fields with a |
| 814 // border-radius. Webkit paints elements with border-radius for us. |
| 815 // TODO(ojan): Get rid of this if-check once we can properly clip rounded |
| 816 // borders: http://b/1112604 and http://b/1108635 |
| 817 // TODO(ojan): make sure we do the right thing if css background-clip is |
| 818 // set. |
| 819 if (o->style()->hasBorderRadius()) |
| 820 return false; |
| 821 |
| 822 const ThemeData& themeData = getThemeData(o); |
| 823 |
| 824 WebCore::ThemeHelperWin helper(i.context, r); |
| 825 gfx::PlatformCanvas* canvas = helper.context()->platformContext()->canvas(); |
| 826 |
| 827 HDC hdc = canvas->beginPlatformPaint(); |
| 828 COLORREF clr = gfx::SkColorToCOLORREF(o->style()->backgroundColor().rgb()); |
| 829 RECT renderRect = helper.rect(); |
| 830 |
| 831 gfx::NativeTheme::instance()->PaintTextField(hdc, |
| 832 themeData.m_part, |
| 833 themeData.m_state, |
| 834 themeData.m_classicState, |
| 835 &renderRect, |
| 836 clr, |
| 837 true, |
| 838 drawEdges); |
| 839 canvas->endPlatformPaint(); |
| 840 return false; |
| 841 } |
| 842 |
| 843 void RenderThemeWin::setButtonPadding(RenderStyle* style) const |
| 844 { |
| 845 if (ChromiumBridge::layoutTestMode()) { |
| 846 setFixedPadding(style, kLayoutTestButtonPadding); |
| 847 |
| 848 } else if (!style->width().isAuto()) { |
| 849 // We need to set the minimum padding for the buttons, or else they |
| 850 // render too small and clip the button face text. The right way to do |
| 851 // this is to ask window's theme manager to give us the minimum |
| 852 // (TS_MIN) size for the part. As a failsafe we set at least |
| 853 // kDefaultButtonPadding because zero just looks bad. |
| 854 Length minXPadding(kDefaultButtonPadding, Fixed); |
| 855 Length minYPadding(kDefaultButtonPadding, Fixed); |
| 856 // Find minimum padding. |
| 857 getMinimalButtonPadding(&minXPadding); |
| 858 |
| 859 // Set the minimum padding. |
| 860 if (style->paddingLeft().value() < minXPadding.value()) { |
| 861 style->setPaddingLeft(minXPadding); |
| 862 } |
| 863 if (style->paddingRight().value() < minXPadding.value()) { |
| 864 style->setPaddingRight(minXPadding); |
| 865 } |
| 866 if (style->paddingBottom().value() < minYPadding.value()) { |
| 867 style->setPaddingBottom(minYPadding); |
| 868 } |
| 869 if (style->paddingTop().value() < minYPadding.value()) { |
| 870 style->setPaddingTop(minYPadding); |
| 871 } |
| 872 } |
| 873 } |
| 874 |
893 void RenderThemeWin::getMinimalButtonPadding(Length* minXPadding) const { | 875 void RenderThemeWin::getMinimalButtonPadding(Length* minXPadding) const { |
894 // TODO(maruel): This get messy if 1. the theme change; 2. we are serializin
g. | 876 // TODO(maruel): This get messy if 1. the theme change; 2. we are serializin
g. |
895 SIZE size; | 877 SIZE size; |
896 if (SUCCEEDED(gfx::NativeTheme::instance()->GetThemePartSize( | 878 if (SUCCEEDED(gfx::NativeTheme::instance()->GetThemePartSize( |
897 gfx::NativeTheme::BUTTON, 0, BP_PUSHBUTTON, PBS_NORMAL, 0, TS_MIN, | 879 gfx::NativeTheme::BUTTON, 0, BP_PUSHBUTTON, PBS_NORMAL, 0, TS_MIN, |
898 &size))) { | 880 &size))) { |
899 *minXPadding = Length(size.cx, Fixed); | 881 *minXPadding = Length(size.cx, Fixed); |
900 } | 882 } |
901 } | 883 } |
902 | 884 |
903 // static | 885 int RenderThemeWin::menuListInternalPadding(RenderStyle* style, int paddingType)
const |
904 void RenderThemeWin::setDefaultFontSize(int fontSize) { | 886 { |
905 DefaultFontSize = static_cast<float>(fontSize); | 887 if (ChromiumBridge::layoutTestMode()) { |
| 888 return layoutTestMenuListInternalPadding(style, paddingType); |
| 889 } |
906 | 890 |
907 // Reset cached fonts. | 891 // This internal padding is in addition to the user-supplied padding. |
908 smallSystemFont = menuFont = labelFont = FontDescription(); | 892 // Matches the FF behavior. |
| 893 int padding = kStyledMenuListInternalPadding[paddingType]; |
| 894 |
| 895 // Reserve the space for right arrow here. The rest of the padding is |
| 896 // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from |
| 897 // RenderMenuList to lay out the individual items in the popup. |
| 898 // If the MenuList actually has appearance "NoAppearance", then that means |
| 899 // we don't draw a button, so don't reserve space for it. |
| 900 const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding; |
| 901 if (paddingType == bar_type && style->appearance() != NoPart) |
| 902 padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); |
| 903 |
| 904 return padding; |
909 } | 905 } |
910 | 906 |
911 } | 907 } // namespace WebCore |
OLD | NEW |