| 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 |