• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * This file is part of the theme implementation for form controls in WebCore.
3  *
4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "config.h"
23 #include "core/rendering/RenderTheme.h"
24 
25 #include "core/CSSValueKeywords.h"
26 #include "core/HTMLNames.h"
27 #include "core/InputTypeNames.h"
28 #include "core/dom/Document.h"
29 #include "core/dom/shadow/ElementShadow.h"
30 #include "core/editing/FrameSelection.h"
31 #include "core/fileapi/FileList.h"
32 #include "core/frame/LocalFrame.h"
33 #include "core/html/HTMLCollection.h"
34 #include "core/html/HTMLDataListElement.h"
35 #include "core/html/HTMLFormControlElement.h"
36 #include "core/html/HTMLInputElement.h"
37 #include "core/html/HTMLMeterElement.h"
38 #include "core/html/HTMLOptionElement.h"
39 #include "core/html/parser/HTMLParserIdioms.h"
40 #include "core/html/shadow/MediaControlElements.h"
41 #include "core/html/shadow/ShadowElementNames.h"
42 #include "core/html/shadow/SpinButtonElement.h"
43 #include "core/html/shadow/TextControlInnerElements.h"
44 #include "core/page/FocusController.h"
45 #include "core/page/Page.h"
46 #include "core/frame/Settings.h"
47 #include "core/rendering/PaintInfo.h"
48 #include "core/rendering/RenderMeter.h"
49 #include "core/rendering/RenderView.h"
50 #include "core/rendering/style/RenderStyle.h"
51 #include "platform/FileMetadata.h"
52 #include "platform/FloatConversion.h"
53 #include "platform/RuntimeEnabledFeatures.h"
54 #include "platform/fonts/FontSelector.h"
55 #include "platform/graphics/GraphicsContextStateSaver.h"
56 #include "platform/text/PlatformLocale.h"
57 #include "platform/text/StringTruncator.h"
58 #include "public/platform/Platform.h"
59 #include "public/platform/WebFallbackThemeEngine.h"
60 #include "public/platform/WebRect.h"
61 #include "wtf/text/StringBuilder.h"
62 
63 // The methods in this file are shared by all themes on every platform.
64 
65 namespace WebCore {
66 
67 using namespace HTMLNames;
68 
getWebFallbackThemeState(const RenderTheme * theme,const RenderObject * o)69 static blink::WebFallbackThemeEngine::State getWebFallbackThemeState(const RenderTheme* theme, const RenderObject* o)
70 {
71     if (!theme->isEnabled(o))
72         return blink::WebFallbackThemeEngine::StateDisabled;
73     if (theme->isPressed(o))
74         return blink::WebFallbackThemeEngine::StatePressed;
75     if (theme->isHovered(o))
76         return blink::WebFallbackThemeEngine::StateHover;
77 
78     return blink::WebFallbackThemeEngine::StateNormal;
79 }
80 
RenderTheme()81 RenderTheme::RenderTheme()
82     : m_hasCustomFocusRingColor(false)
83 #if USE(NEW_THEME)
84     , m_platformTheme(platformTheme())
85 #endif
86 {
87 }
88 
adjustStyle(RenderStyle * style,Element * e,const CachedUAStyle * uaStyle)89 void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyle* uaStyle)
90 {
91     // Force inline and table display styles to be inline-block (except for table- which is block)
92     ControlPart part = style->appearance();
93     if (style->display() == INLINE || style->display() == INLINE_TABLE || style->display() == TABLE_ROW_GROUP
94         || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_FOOTER_GROUP
95         || style->display() == TABLE_ROW || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_COLUMN
96         || style->display() == TABLE_CELL || style->display() == TABLE_CAPTION)
97         style->setDisplay(INLINE_BLOCK);
98     else if (style->display() == LIST_ITEM || style->display() == TABLE)
99         style->setDisplay(BLOCK);
100 
101     if (uaStyle && uaStyle->hasAppearance && isControlStyled(style, uaStyle)) {
102         if (part == MenulistPart) {
103             style->setAppearance(MenulistButtonPart);
104             part = MenulistButtonPart;
105         } else
106             style->setAppearance(NoControlPart);
107     }
108 
109     if (!style->hasAppearance())
110         return;
111 
112     if (shouldUseFallbackTheme(style)) {
113         adjustStyleUsingFallbackTheme(style, e);
114         return;
115     }
116 
117 #if USE(NEW_THEME)
118     switch (part) {
119     case CheckboxPart:
120     case InnerSpinButtonPart:
121     case RadioPart:
122     case PushButtonPart:
123     case SquareButtonPart:
124     case ButtonPart: {
125         // Border
126         LengthBox borderBox(style->borderTopWidth(), style->borderRightWidth(), style->borderBottomWidth(), style->borderLeftWidth());
127         borderBox = m_platformTheme->controlBorder(part, style->font().fontDescription(), borderBox, style->effectiveZoom());
128         if (borderBox.top().value() != static_cast<int>(style->borderTopWidth())) {
129             if (borderBox.top().value())
130                 style->setBorderTopWidth(borderBox.top().value());
131             else
132                 style->resetBorderTop();
133         }
134         if (borderBox.right().value() != static_cast<int>(style->borderRightWidth())) {
135             if (borderBox.right().value())
136                 style->setBorderRightWidth(borderBox.right().value());
137             else
138                 style->resetBorderRight();
139         }
140         if (borderBox.bottom().value() != static_cast<int>(style->borderBottomWidth())) {
141             style->setBorderBottomWidth(borderBox.bottom().value());
142             if (borderBox.bottom().value())
143                 style->setBorderBottomWidth(borderBox.bottom().value());
144             else
145                 style->resetBorderBottom();
146         }
147         if (borderBox.left().value() != static_cast<int>(style->borderLeftWidth())) {
148             style->setBorderLeftWidth(borderBox.left().value());
149             if (borderBox.left().value())
150                 style->setBorderLeftWidth(borderBox.left().value());
151             else
152                 style->resetBorderLeft();
153         }
154 
155         // Padding
156         LengthBox paddingBox = m_platformTheme->controlPadding(part, style->font().fontDescription(), style->paddingBox(), style->effectiveZoom());
157         if (paddingBox != style->paddingBox())
158             style->setPaddingBox(paddingBox);
159 
160         // Whitespace
161         if (m_platformTheme->controlRequiresPreWhiteSpace(part))
162             style->setWhiteSpace(PRE);
163 
164         // Width / Height
165         // The width and height here are affected by the zoom.
166         // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
167         LengthSize controlSize = m_platformTheme->controlSize(part, style->font().fontDescription(), LengthSize(style->width(), style->height()), style->effectiveZoom());
168         if (controlSize.width() != style->width())
169             style->setWidth(controlSize.width());
170         if (controlSize.height() != style->height())
171             style->setHeight(controlSize.height());
172 
173         // Min-Width / Min-Height
174         LengthSize minControlSize = m_platformTheme->minimumControlSize(part, style->font().fontDescription(), style->effectiveZoom());
175         if (minControlSize.width() != style->minWidth())
176             style->setMinWidth(minControlSize.width());
177         if (minControlSize.height() != style->minHeight())
178             style->setMinHeight(minControlSize.height());
179 
180         // Font
181         FontDescription controlFont = m_platformTheme->controlFont(part, style->font().fontDescription(), style->effectiveZoom());
182         if (controlFont != style->font().fontDescription()) {
183             // Reset our line-height
184             style->setLineHeight(RenderStyle::initialLineHeight());
185 
186             // Now update our font.
187             if (style->setFontDescription(controlFont))
188                 style->font().update(nullptr);
189         }
190     }
191     default:
192         break;
193     }
194 #endif
195 
196     // Call the appropriate style adjustment method based off the appearance value.
197     switch (style->appearance()) {
198 #if !USE(NEW_THEME)
199     case CheckboxPart:
200         return adjustCheckboxStyle(style, e);
201     case RadioPart:
202         return adjustRadioStyle(style, e);
203     case PushButtonPart:
204     case SquareButtonPart:
205     case ButtonPart:
206         return adjustButtonStyle(style, e);
207     case InnerSpinButtonPart:
208         return adjustInnerSpinButtonStyle(style, e);
209 #endif
210     case MenulistPart:
211         return adjustMenuListStyle(style, e);
212     case MenulistButtonPart:
213         return adjustMenuListButtonStyle(style, e);
214     case SliderThumbHorizontalPart:
215     case SliderThumbVerticalPart:
216         return adjustSliderThumbStyle(style, e);
217     case SearchFieldPart:
218         return adjustSearchFieldStyle(style, e);
219     case SearchFieldCancelButtonPart:
220         return adjustSearchFieldCancelButtonStyle(style, e);
221     case SearchFieldDecorationPart:
222         return adjustSearchFieldDecorationStyle(style, e);
223     case SearchFieldResultsDecorationPart:
224         return adjustSearchFieldResultsDecorationStyle(style, e);
225     default:
226         break;
227     }
228 }
229 
paint(RenderObject * o,const PaintInfo & paintInfo,const IntRect & r)230 bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
231 {
232     // If painting is disabled, but we aren't updating control tints, then just bail.
233     // If we are updating control tints, just schedule a repaint if the theme supports tinting
234     // for that control.
235     if (paintInfo.context->updatingControlTints()) {
236         if (controlSupportsTints(o))
237             o->paintInvalidationForWholeRenderer();
238         return false;
239     }
240     ControlPart part = o->style()->appearance();
241 
242     if (shouldUseFallbackTheme(o->style()))
243         return paintUsingFallbackTheme(o, paintInfo, r);
244 
245 #if USE(NEW_THEME)
246     switch (part) {
247     case CheckboxPart:
248     case RadioPart:
249     case PushButtonPart:
250     case SquareButtonPart:
251     case ButtonPart:
252     case InnerSpinButtonPart:
253         m_platformTheme->paint(part, controlStatesForRenderer(o), const_cast<GraphicsContext*>(paintInfo.context), r, o->style()->effectiveZoom(), o->view()->frameView());
254         return false;
255     default:
256         break;
257     }
258 #endif
259 
260     // Call the appropriate paint method based off the appearance value.
261     switch (part) {
262 #if !USE(NEW_THEME)
263     case CheckboxPart:
264         return paintCheckbox(o, paintInfo, r);
265     case RadioPart:
266         return paintRadio(o, paintInfo, r);
267     case PushButtonPart:
268     case SquareButtonPart:
269     case ButtonPart:
270         return paintButton(o, paintInfo, r);
271     case InnerSpinButtonPart:
272         return paintInnerSpinButton(o, paintInfo, r);
273 #endif
274     case MenulistPart:
275         return paintMenuList(o, paintInfo, r);
276     case MeterPart:
277     case RelevancyLevelIndicatorPart:
278     case ContinuousCapacityLevelIndicatorPart:
279     case DiscreteCapacityLevelIndicatorPart:
280     case RatingLevelIndicatorPart:
281         return paintMeter(o, paintInfo, r);
282     case ProgressBarPart:
283         return paintProgressBar(o, paintInfo, r);
284     case SliderHorizontalPart:
285     case SliderVerticalPart:
286         return paintSliderTrack(o, paintInfo, r);
287     case SliderThumbHorizontalPart:
288     case SliderThumbVerticalPart:
289         return paintSliderThumb(o, paintInfo, r);
290     case MediaEnterFullscreenButtonPart:
291     case MediaExitFullscreenButtonPart:
292         return paintMediaFullscreenButton(o, paintInfo, r);
293     case MediaPlayButtonPart:
294         return paintMediaPlayButton(o, paintInfo, r);
295     case MediaOverlayPlayButtonPart:
296         return paintMediaOverlayPlayButton(o, paintInfo, r);
297     case MediaMuteButtonPart:
298         return paintMediaMuteButton(o, paintInfo, r);
299     case MediaToggleClosedCaptionsButtonPart:
300         return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
301     case MediaSliderPart:
302         return paintMediaSliderTrack(o, paintInfo, r);
303     case MediaSliderThumbPart:
304         return paintMediaSliderThumb(o, paintInfo, r);
305     case MediaVolumeSliderContainerPart:
306         return paintMediaVolumeSliderContainer(o, paintInfo, r);
307     case MediaVolumeSliderPart:
308         return paintMediaVolumeSliderTrack(o, paintInfo, r);
309     case MediaVolumeSliderThumbPart:
310         return paintMediaVolumeSliderThumb(o, paintInfo, r);
311     case MediaFullScreenVolumeSliderPart:
312         return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, r);
313     case MediaFullScreenVolumeSliderThumbPart:
314         return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, r);
315     case MediaTimeRemainingPart:
316         return paintMediaTimeRemaining(o, paintInfo, r);
317     case MediaCurrentTimePart:
318         return paintMediaCurrentTime(o, paintInfo, r);
319     case MediaControlsBackgroundPart:
320         return paintMediaControlsBackground(o, paintInfo, r);
321     case MenulistButtonPart:
322     case TextFieldPart:
323     case TextAreaPart:
324     case ListboxPart:
325         return true;
326     case SearchFieldPart:
327         return paintSearchField(o, paintInfo, r);
328     case SearchFieldCancelButtonPart:
329         return paintSearchFieldCancelButton(o, paintInfo, r);
330     case SearchFieldDecorationPart:
331         return paintSearchFieldDecoration(o, paintInfo, r);
332     case SearchFieldResultsDecorationPart:
333         return paintSearchFieldResultsDecoration(o, paintInfo, r);
334     default:
335         break;
336     }
337 
338     return true; // We don't support the appearance, so let the normal background/border paint.
339 }
340 
paintBorderOnly(RenderObject * o,const PaintInfo & paintInfo,const IntRect & r)341 bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
342 {
343     // Call the appropriate paint method based off the appearance value.
344     switch (o->style()->appearance()) {
345     case TextFieldPart:
346         return paintTextField(o, paintInfo, r);
347     case ListboxPart:
348     case TextAreaPart:
349         return paintTextArea(o, paintInfo, r);
350     case MenulistButtonPart:
351     case SearchFieldPart:
352         return true;
353     case CheckboxPart:
354     case RadioPart:
355     case PushButtonPart:
356     case SquareButtonPart:
357     case ButtonPart:
358     case MenulistPart:
359     case MeterPart:
360     case RelevancyLevelIndicatorPart:
361     case ContinuousCapacityLevelIndicatorPart:
362     case DiscreteCapacityLevelIndicatorPart:
363     case RatingLevelIndicatorPart:
364     case ProgressBarPart:
365     case SliderHorizontalPart:
366     case SliderVerticalPart:
367     case SliderThumbHorizontalPart:
368     case SliderThumbVerticalPart:
369     case SearchFieldCancelButtonPart:
370     case SearchFieldDecorationPart:
371     case SearchFieldResultsDecorationPart:
372     default:
373         break;
374     }
375 
376     return false;
377 }
378 
paintDecorations(RenderObject * o,const PaintInfo & paintInfo,const IntRect & r)379 bool RenderTheme::paintDecorations(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
380 {
381     // Call the appropriate paint method based off the appearance value.
382     switch (o->style()->appearance()) {
383     case MenulistButtonPart:
384         return paintMenuListButton(o, paintInfo, r);
385     case TextFieldPart:
386     case TextAreaPart:
387     case ListboxPart:
388     case CheckboxPart:
389     case RadioPart:
390     case PushButtonPart:
391     case SquareButtonPart:
392     case ButtonPart:
393     case MenulistPart:
394     case MeterPart:
395     case RelevancyLevelIndicatorPart:
396     case ContinuousCapacityLevelIndicatorPart:
397     case DiscreteCapacityLevelIndicatorPart:
398     case RatingLevelIndicatorPart:
399     case ProgressBarPart:
400     case SliderHorizontalPart:
401     case SliderVerticalPart:
402     case SliderThumbHorizontalPart:
403     case SliderThumbVerticalPart:
404     case SearchFieldPart:
405     case SearchFieldCancelButtonPart:
406     case SearchFieldDecorationPart:
407     case SearchFieldResultsDecorationPart:
408     default:
409         break;
410     }
411 
412     return false;
413 }
414 
extraDefaultStyleSheet()415 String RenderTheme::extraDefaultStyleSheet()
416 {
417     StringBuilder runtimeCSS;
418     if (RuntimeEnabledFeatures::dialogElementEnabled()) {
419         runtimeCSS.appendLiteral("dialog:not([open]) { display: none; }");
420         runtimeCSS.appendLiteral("dialog { position: absolute; left: 0; right: 0; width: -webkit-fit-content; height: -webkit-fit-content; margin: auto; border: solid; padding: 1em; background: white; color: black;}");
421         runtimeCSS.appendLiteral("dialog::backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0,0,0,0.1); }");
422     }
423 
424     return runtimeCSS.toString();
425 }
426 
formatMediaControlsTime(float time) const427 String RenderTheme::formatMediaControlsTime(float time) const
428 {
429     if (!std::isfinite(time))
430         time = 0;
431     int seconds = (int)fabsf(time);
432     int hours = seconds / (60 * 60);
433     int minutes = (seconds / 60) % 60;
434     seconds %= 60;
435     if (hours) {
436         if (hours > 9)
437             return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
438 
439         return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds);
440     }
441 
442     return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds);
443 }
444 
formatMediaControlsCurrentTime(float currentTime,float) const445 String RenderTheme::formatMediaControlsCurrentTime(float currentTime, float /*duration*/) const
446 {
447     return formatMediaControlsTime(currentTime);
448 }
449 
activeSelectionBackgroundColor() const450 Color RenderTheme::activeSelectionBackgroundColor() const
451 {
452     return platformActiveSelectionBackgroundColor().blendWithWhite();
453 }
454 
inactiveSelectionBackgroundColor() const455 Color RenderTheme::inactiveSelectionBackgroundColor() const
456 {
457     return platformInactiveSelectionBackgroundColor().blendWithWhite();
458 }
459 
activeSelectionForegroundColor() const460 Color RenderTheme::activeSelectionForegroundColor() const
461 {
462     return platformActiveSelectionForegroundColor();
463 }
464 
inactiveSelectionForegroundColor() const465 Color RenderTheme::inactiveSelectionForegroundColor() const
466 {
467     return platformInactiveSelectionForegroundColor();
468 }
469 
activeListBoxSelectionBackgroundColor() const470 Color RenderTheme::activeListBoxSelectionBackgroundColor() const
471 {
472     return platformActiveListBoxSelectionBackgroundColor();
473 }
474 
inactiveListBoxSelectionBackgroundColor() const475 Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const
476 {
477     return platformInactiveListBoxSelectionBackgroundColor();
478 }
479 
activeListBoxSelectionForegroundColor() const480 Color RenderTheme::activeListBoxSelectionForegroundColor() const
481 {
482     return platformActiveListBoxSelectionForegroundColor();
483 }
484 
inactiveListBoxSelectionForegroundColor() const485 Color RenderTheme::inactiveListBoxSelectionForegroundColor() const
486 {
487     return platformInactiveListBoxSelectionForegroundColor();
488 }
489 
platformActiveSelectionBackgroundColor() const490 Color RenderTheme::platformActiveSelectionBackgroundColor() const
491 {
492     // Use a blue color by default if the platform theme doesn't define anything.
493     return Color(0, 0, 255);
494 }
495 
platformActiveSelectionForegroundColor() const496 Color RenderTheme::platformActiveSelectionForegroundColor() const
497 {
498     // Use a white color by default if the platform theme doesn't define anything.
499     return Color::white;
500 }
501 
platformInactiveSelectionBackgroundColor() const502 Color RenderTheme::platformInactiveSelectionBackgroundColor() const
503 {
504     // Use a grey color by default if the platform theme doesn't define anything.
505     // This color matches Firefox's inactive color.
506     return Color(176, 176, 176);
507 }
508 
platformInactiveSelectionForegroundColor() const509 Color RenderTheme::platformInactiveSelectionForegroundColor() const
510 {
511     // Use a black color by default.
512     return Color::black;
513 }
514 
platformActiveListBoxSelectionBackgroundColor() const515 Color RenderTheme::platformActiveListBoxSelectionBackgroundColor() const
516 {
517     return platformActiveSelectionBackgroundColor();
518 }
519 
platformActiveListBoxSelectionForegroundColor() const520 Color RenderTheme::platformActiveListBoxSelectionForegroundColor() const
521 {
522     return platformActiveSelectionForegroundColor();
523 }
524 
platformInactiveListBoxSelectionBackgroundColor() const525 Color RenderTheme::platformInactiveListBoxSelectionBackgroundColor() const
526 {
527     return platformInactiveSelectionBackgroundColor();
528 }
529 
platformInactiveListBoxSelectionForegroundColor() const530 Color RenderTheme::platformInactiveListBoxSelectionForegroundColor() const
531 {
532     return platformInactiveSelectionForegroundColor();
533 }
534 
baselinePosition(const RenderObject * o) const535 int RenderTheme::baselinePosition(const RenderObject* o) const
536 {
537     if (!o->isBox())
538         return 0;
539 
540     const RenderBox* box = toRenderBox(o);
541 
542 #if USE(NEW_THEME)
543     return box->height() + box->marginTop() + m_platformTheme->baselinePositionAdjustment(o->style()->appearance()) * o->style()->effectiveZoom();
544 #else
545     return box->height() + box->marginTop();
546 #endif
547 }
548 
isControlContainer(ControlPart appearance) const549 bool RenderTheme::isControlContainer(ControlPart appearance) const
550 {
551     // There are more leaves than this, but we'll patch this function as we add support for
552     // more controls.
553     return appearance != CheckboxPart && appearance != RadioPart;
554 }
555 
isBackgroundOrBorderStyled(const RenderStyle & style,const CachedUAStyle & uaStyle)556 static bool isBackgroundOrBorderStyled(const RenderStyle& style, const CachedUAStyle& uaStyle)
557 {
558     // Code below excludes the background-repeat from comparison by resetting it
559     FillLayer backgroundCopy = uaStyle.backgroundLayers;
560     FillLayer backgroundLayersCopy = *style.backgroundLayers();
561     backgroundCopy.setRepeatX(NoRepeatFill);
562     backgroundCopy.setRepeatY(NoRepeatFill);
563     backgroundLayersCopy.setRepeatX(NoRepeatFill);
564     backgroundLayersCopy.setRepeatY(NoRepeatFill);
565     // Test the style to see if the UA border and background match.
566     return style.border() != uaStyle.border
567         || backgroundLayersCopy != backgroundCopy
568         || style.visitedDependentColor(CSSPropertyBackgroundColor) != uaStyle.backgroundColor;
569 }
570 
isControlStyled(const RenderStyle * style,const CachedUAStyle * uaStyle) const571 bool RenderTheme::isControlStyled(const RenderStyle* style, const CachedUAStyle* uaStyle) const
572 {
573     ASSERT(uaStyle);
574 
575     switch (style->appearance()) {
576     case PushButtonPart:
577     case SquareButtonPart:
578     case ButtonPart:
579     case ProgressBarPart:
580     case MeterPart:
581     case RelevancyLevelIndicatorPart:
582     case ContinuousCapacityLevelIndicatorPart:
583     case DiscreteCapacityLevelIndicatorPart:
584     case RatingLevelIndicatorPart:
585         return isBackgroundOrBorderStyled(*style, *uaStyle);
586 
587     case ListboxPart:
588     case MenulistPart:
589     case SearchFieldPart:
590     case TextAreaPart:
591     case TextFieldPart:
592         return isBackgroundOrBorderStyled(*style, *uaStyle) || style->boxShadow();
593 
594     case SliderHorizontalPart:
595     case SliderVerticalPart:
596         return style->boxShadow();
597 
598     default:
599         return false;
600     }
601 }
602 
adjustRepaintRect(const RenderObject * o,IntRect & r)603 void RenderTheme::adjustRepaintRect(const RenderObject* o, IntRect& r)
604 {
605 #if USE(NEW_THEME)
606     m_platformTheme->inflateControlPaintRect(o->style()->appearance(), controlStatesForRenderer(o), r, o->style()->effectiveZoom());
607 #endif
608 }
609 
shouldDrawDefaultFocusRing(RenderObject * renderer) const610 bool RenderTheme::shouldDrawDefaultFocusRing(RenderObject* renderer) const
611 {
612     if (supportsFocusRing(renderer->style()))
613         return false;
614     if (!renderer->style()->hasAppearance())
615         return true;
616     Node* node = renderer->node();
617     if (!node)
618         return true;
619     // We can't use RenderTheme::isFocused because outline:auto might be
620     // specified to non-:focus rulesets.
621     if (node->focused() && !node->shouldHaveFocusAppearance())
622         return false;
623     return true;
624 }
625 
supportsFocusRing(const RenderStyle * style) const626 bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
627 {
628     return (style->hasAppearance() && style->appearance() != TextFieldPart && style->appearance() != TextAreaPart && style->appearance() != MenulistButtonPart && style->appearance() != ListboxPart);
629 }
630 
stateChanged(RenderObject * o,ControlState state) const631 bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
632 {
633     // Default implementation assumes the controls don't respond to changes in :hover state
634     if (state == HoverControlState && !supportsHover(o->style()))
635         return false;
636 
637     // Assume pressed state is only responded to if the control is enabled.
638     if (state == PressedControlState && !isEnabled(o))
639         return false;
640 
641     // Repaint the control.
642     o->paintInvalidationForWholeRenderer();
643     return true;
644 }
645 
controlStatesForRenderer(const RenderObject * o) const646 ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
647 {
648     ControlStates result = 0;
649     if (isHovered(o)) {
650         result |= HoverControlState;
651         if (isSpinUpButtonPartHovered(o))
652             result |= SpinUpControlState;
653     }
654     if (isPressed(o)) {
655         result |= PressedControlState;
656         if (isSpinUpButtonPartPressed(o))
657             result |= SpinUpControlState;
658     }
659     if (isFocused(o) && o->style()->outlineStyleIsAuto())
660         result |= FocusControlState;
661     if (isEnabled(o))
662         result |= EnabledControlState;
663     if (isChecked(o))
664         result |= CheckedControlState;
665     if (isReadOnlyControl(o))
666         result |= ReadOnlyControlState;
667     if (!isActive(o))
668         result |= WindowInactiveControlState;
669     if (isIndeterminate(o))
670         result |= IndeterminateControlState;
671     return result;
672 }
673 
isActive(const RenderObject * o) const674 bool RenderTheme::isActive(const RenderObject* o) const
675 {
676     Node* node = o->node();
677     if (!node)
678         return false;
679 
680     Page* page = node->document().page();
681     if (!page)
682         return false;
683 
684     return page->focusController().isActive();
685 }
686 
isChecked(const RenderObject * o) const687 bool RenderTheme::isChecked(const RenderObject* o) const
688 {
689     if (!isHTMLInputElement(o->node()))
690         return false;
691     return toHTMLInputElement(o->node())->shouldAppearChecked();
692 }
693 
isIndeterminate(const RenderObject * o) const694 bool RenderTheme::isIndeterminate(const RenderObject* o) const
695 {
696     if (!isHTMLInputElement(o->node()))
697         return false;
698     return toHTMLInputElement(o->node())->shouldAppearIndeterminate();
699 }
700 
isEnabled(const RenderObject * o) const701 bool RenderTheme::isEnabled(const RenderObject* o) const
702 {
703     Node* node = o->node();
704     if (!node || !node->isElementNode())
705         return true;
706     return !toElement(node)->isDisabledFormControl();
707 }
708 
isFocused(const RenderObject * o) const709 bool RenderTheme::isFocused(const RenderObject* o) const
710 {
711     Node* node = o->node();
712     if (!node)
713         return false;
714 
715     node = node->focusDelegate();
716     Document& document = node->document();
717     LocalFrame* frame = document.frame();
718     return node == document.focusedElement() && node->focused() && node->shouldHaveFocusAppearance() && frame && frame->selection().isFocusedAndActive();
719 }
720 
isPressed(const RenderObject * o) const721 bool RenderTheme::isPressed(const RenderObject* o) const
722 {
723     if (!o->node())
724         return false;
725     return o->node()->active();
726 }
727 
isSpinUpButtonPartPressed(const RenderObject * o) const728 bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
729 {
730     Node* node = o->node();
731     if (!node || !node->active() || !node->isElementNode()
732         || !toElement(node)->isSpinButtonElement())
733         return false;
734     SpinButtonElement* element = toSpinButtonElement(node);
735     return element->upDownState() == SpinButtonElement::Up;
736 }
737 
isReadOnlyControl(const RenderObject * o) const738 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
739 {
740     Node* node = o->node();
741     if (!node || !node->isElementNode() || !toElement(node)->isFormControlElement())
742         return false;
743     HTMLFormControlElement* element = toHTMLFormControlElement(node);
744     return element->isReadOnly();
745 }
746 
isHovered(const RenderObject * o) const747 bool RenderTheme::isHovered(const RenderObject* o) const
748 {
749     Node* node = o->node();
750     if (!node)
751         return false;
752     if (!node->isElementNode() || !toElement(node)->isSpinButtonElement())
753         return node->hovered();
754     SpinButtonElement* element = toSpinButtonElement(node);
755     return element->hovered() && element->upDownState() != SpinButtonElement::Indeterminate;
756 }
757 
isSpinUpButtonPartHovered(const RenderObject * o) const758 bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const
759 {
760     Node* node = o->node();
761     if (!node || !node->isElementNode() || !toElement(node)->isSpinButtonElement())
762         return false;
763     SpinButtonElement* element = toSpinButtonElement(node);
764     return element->upDownState() == SpinButtonElement::Up;
765 }
766 
767 #if !USE(NEW_THEME)
768 
adjustCheckboxStyle(RenderStyle * style,Element *) const769 void RenderTheme::adjustCheckboxStyle(RenderStyle* style, Element*) const
770 {
771     // A summary of the rules for checkbox designed to match WinIE:
772     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
773     // font-size - not honored (control has no text), but we use it to decide which control size to use.
774     setCheckboxSize(style);
775 
776     // padding - not honored by WinIE, needs to be removed.
777     style->resetPadding();
778 
779     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
780     // for now, we will not honor it.
781     style->resetBorder();
782 }
783 
adjustRadioStyle(RenderStyle * style,Element *) const784 void RenderTheme::adjustRadioStyle(RenderStyle* style, Element*) const
785 {
786     // A summary of the rules for checkbox designed to match WinIE:
787     // width/height - honored (WinIE actually scales its control for small widths, but lets it overflow for small heights.)
788     // font-size - not honored (control has no text), but we use it to decide which control size to use.
789     setRadioSize(style);
790 
791     // padding - not honored by WinIE, needs to be removed.
792     style->resetPadding();
793 
794     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
795     // for now, we will not honor it.
796     style->resetBorder();
797 }
798 
adjustButtonStyle(RenderStyle * style,Element *) const799 void RenderTheme::adjustButtonStyle(RenderStyle* style, Element*) const
800 {
801 }
802 
adjustInnerSpinButtonStyle(RenderStyle *,Element *) const803 void RenderTheme::adjustInnerSpinButtonStyle(RenderStyle*, Element*) const
804 {
805 }
806 #endif
807 
adjustMenuListStyle(RenderStyle *,Element *) const808 void RenderTheme::adjustMenuListStyle(RenderStyle*, Element*) const
809 {
810 }
811 
meterSizeForBounds(const RenderMeter *,const IntRect & bounds) const812 IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
813 {
814     return bounds.size();
815 }
816 
supportsMeter(ControlPart) const817 bool RenderTheme::supportsMeter(ControlPart) const
818 {
819     return false;
820 }
821 
paintMeter(RenderObject *,const PaintInfo &,const IntRect &)822 bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
823 {
824     return true;
825 }
826 
paintSliderTicks(RenderObject * o,const PaintInfo & paintInfo,const IntRect & rect)827 void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
828 {
829     Node* node = o->node();
830     if (!isHTMLInputElement(node))
831         return;
832 
833     HTMLInputElement* input = toHTMLInputElement(node);
834     if (!input->isRangeControl())
835         return;
836 
837     HTMLDataListElement* dataList = input->dataList();
838     if (!dataList)
839         return;
840 
841     double min = input->minimum();
842     double max = input->maximum();
843     ControlPart part = o->style()->appearance();
844     // We don't support ticks on alternate sliders like MediaVolumeSliders.
845     if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
846         return;
847     bool isHorizontal = part ==  SliderHorizontalPart;
848 
849     IntSize thumbSize;
850     RenderObject* thumbRenderer = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())->renderer();
851     if (thumbRenderer) {
852         RenderStyle* thumbStyle = thumbRenderer->style();
853         int thumbWidth = thumbStyle->width().intValue();
854         int thumbHeight = thumbStyle->height().intValue();
855         thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
856         thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
857     }
858 
859     IntSize tickSize = sliderTickSize();
860     float zoomFactor = o->style()->effectiveZoom();
861     FloatRect tickRect;
862     int tickRegionSideMargin = 0;
863     int tickRegionWidth = 0;
864     IntRect trackBounds;
865     RenderObject* trackRenderer = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack())->renderer();
866     // We can ignoring transforms because transform is handled by the graphics context.
867     if (trackRenderer)
868         trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms();
869     IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms();
870 
871     // Make position relative to the transformed ancestor element.
872     trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
873     trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y());
874 
875     if (isHorizontal) {
876         tickRect.setWidth(floor(tickSize.width() * zoomFactor));
877         tickRect.setHeight(floor(tickSize.height() * zoomFactor));
878         tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
879         tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
880         tickRegionWidth = trackBounds.width() - thumbSize.width();
881     } else {
882         tickRect.setWidth(floor(tickSize.height() * zoomFactor));
883         tickRect.setHeight(floor(tickSize.width() * zoomFactor));
884         tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
885         tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
886         tickRegionWidth = trackBounds.height() - thumbSize.width();
887     }
888     RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
889     GraphicsContextStateSaver stateSaver(*paintInfo.context);
890     paintInfo.context->setFillColor(o->resolveColor(CSSPropertyColor));
891     for (unsigned i = 0; Element* element = options->item(i); i++) {
892         ASSERT(isHTMLOptionElement(*element));
893         HTMLOptionElement& optionElement = toHTMLOptionElement(*element);
894         String value = optionElement.value();
895         if (!input->isValidValue(value))
896             continue;
897         double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
898         double tickFraction = (parsedValue - min) / (max - min);
899         double tickRatio = isHorizontal && o->style()->isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
900         double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
901         if (isHorizontal)
902             tickRect.setX(tickPosition);
903         else
904             tickRect.setY(tickPosition);
905         paintInfo.context->fillRect(tickRect);
906     }
907 }
908 
animationRepeatIntervalForProgressBar(RenderProgress *) const909 double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
910 {
911     return 0;
912 }
913 
animationDurationForProgressBar(RenderProgress *) const914 double RenderTheme::animationDurationForProgressBar(RenderProgress*) const
915 {
916     return 0;
917 }
918 
shouldHaveSpinButton(HTMLInputElement * inputElement) const919 bool RenderTheme::shouldHaveSpinButton(HTMLInputElement* inputElement) const
920 {
921     return inputElement->isSteppable() && !inputElement->isRangeControl();
922 }
923 
adjustMenuListButtonStyle(RenderStyle *,Element *) const924 void RenderTheme::adjustMenuListButtonStyle(RenderStyle*, Element*) const
925 {
926 }
927 
adjustSliderThumbStyle(RenderStyle * style,Element * element) const928 void RenderTheme::adjustSliderThumbStyle(RenderStyle* style, Element* element) const
929 {
930     adjustSliderThumbSize(style, element);
931 }
932 
adjustSliderThumbSize(RenderStyle *,Element *) const933 void RenderTheme::adjustSliderThumbSize(RenderStyle*, Element*) const
934 {
935 }
936 
adjustSearchFieldStyle(RenderStyle *,Element *) const937 void RenderTheme::adjustSearchFieldStyle(RenderStyle*, Element*) const
938 {
939 }
940 
adjustSearchFieldCancelButtonStyle(RenderStyle *,Element *) const941 void RenderTheme::adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const
942 {
943 }
944 
adjustSearchFieldDecorationStyle(RenderStyle *,Element *) const945 void RenderTheme::adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const
946 {
947 }
948 
adjustSearchFieldResultsDecorationStyle(RenderStyle *,Element *) const949 void RenderTheme::adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const
950 {
951 }
952 
platformColorsDidChange()953 void RenderTheme::platformColorsDidChange()
954 {
955     Page::scheduleForcedStyleRecalcForAllPages();
956 }
957 
systemColor(CSSValueID cssValueId) const958 Color RenderTheme::systemColor(CSSValueID cssValueId) const
959 {
960     switch (cssValueId) {
961     case CSSValueActiveborder:
962         return 0xFFFFFFFF;
963     case CSSValueActivecaption:
964         return 0xFFCCCCCC;
965     case CSSValueAppworkspace:
966         return 0xFFFFFFFF;
967     case CSSValueBackground:
968         return 0xFF6363CE;
969     case CSSValueButtonface:
970         return 0xFFC0C0C0;
971     case CSSValueButtonhighlight:
972         return 0xFFDDDDDD;
973     case CSSValueButtonshadow:
974         return 0xFF888888;
975     case CSSValueButtontext:
976         return 0xFF000000;
977     case CSSValueCaptiontext:
978         return 0xFF000000;
979     case CSSValueGraytext:
980         return 0xFF808080;
981     case CSSValueHighlight:
982         return 0xFFB5D5FF;
983     case CSSValueHighlighttext:
984         return 0xFF000000;
985     case CSSValueInactiveborder:
986         return 0xFFFFFFFF;
987     case CSSValueInactivecaption:
988         return 0xFFFFFFFF;
989     case CSSValueInactivecaptiontext:
990         return 0xFF7F7F7F;
991     case CSSValueInfobackground:
992         return 0xFFFBFCC5;
993     case CSSValueInfotext:
994         return 0xFF000000;
995     case CSSValueMenu:
996         return 0xFFC0C0C0;
997     case CSSValueMenutext:
998         return 0xFF000000;
999     case CSSValueScrollbar:
1000         return 0xFFFFFFFF;
1001     case CSSValueText:
1002         return 0xFF000000;
1003     case CSSValueThreeddarkshadow:
1004         return 0xFF666666;
1005     case CSSValueThreedface:
1006         return 0xFFC0C0C0;
1007     case CSSValueThreedhighlight:
1008         return 0xFFDDDDDD;
1009     case CSSValueThreedlightshadow:
1010         return 0xFFC0C0C0;
1011     case CSSValueThreedshadow:
1012         return 0xFF888888;
1013     case CSSValueWindow:
1014         return 0xFFFFFFFF;
1015     case CSSValueWindowframe:
1016         return 0xFFCCCCCC;
1017     case CSSValueWindowtext:
1018         return 0xFF000000;
1019     case CSSValueInternalActiveListBoxSelection:
1020         return activeListBoxSelectionBackgroundColor();
1021         break;
1022     case CSSValueInternalActiveListBoxSelectionText:
1023         return activeListBoxSelectionForegroundColor();
1024         break;
1025     case CSSValueInternalInactiveListBoxSelection:
1026         return inactiveListBoxSelectionBackgroundColor();
1027         break;
1028     case CSSValueInternalInactiveListBoxSelectionText:
1029         return inactiveListBoxSelectionForegroundColor();
1030         break;
1031     default:
1032         break;
1033     }
1034     ASSERT_NOT_REACHED();
1035     return Color();
1036 }
1037 
platformActiveTextSearchHighlightColor() const1038 Color RenderTheme::platformActiveTextSearchHighlightColor() const
1039 {
1040     return Color(255, 150, 50); // Orange.
1041 }
1042 
platformInactiveTextSearchHighlightColor() const1043 Color RenderTheme::platformInactiveTextSearchHighlightColor() const
1044 {
1045     return Color(255, 255, 0); // Yellow.
1046 }
1047 
tapHighlightColor()1048 Color RenderTheme::tapHighlightColor()
1049 {
1050     return theme().platformTapHighlightColor();
1051 }
1052 
setCustomFocusRingColor(const Color & c)1053 void RenderTheme::setCustomFocusRingColor(const Color& c)
1054 {
1055     m_customFocusRingColor = c;
1056     m_hasCustomFocusRingColor = true;
1057 }
1058 
focusRingColor() const1059 Color RenderTheme::focusRingColor() const
1060 {
1061     return m_hasCustomFocusRingColor ? m_customFocusRingColor : theme().platformFocusRingColor();
1062 }
1063 
fileListNameForWidth(Locale & locale,const FileList * fileList,const Font & font,int width) const1064 String RenderTheme::fileListNameForWidth(Locale& locale, const FileList* fileList, const Font& font, int width) const
1065 {
1066     if (width <= 0)
1067         return String();
1068 
1069     String string;
1070     if (fileList->isEmpty()) {
1071         string = locale.queryString(blink::WebLocalizedString::FileButtonNoFileSelectedLabel);
1072     } else if (fileList->length() == 1) {
1073         string = fileList->item(0)->name();
1074     } else {
1075         // FIXME: Localization of fileList->length().
1076         return StringTruncator::rightTruncate(locale.queryString(blink::WebLocalizedString::MultipleFileUploadText, String::number(fileList->length())), width, font, StringTruncator::EnableRoundingHacks);
1077     }
1078 
1079     return StringTruncator::centerTruncate(string, width, font, StringTruncator::EnableRoundingHacks);
1080 }
1081 
shouldOpenPickerWithF4Key() const1082 bool RenderTheme::shouldOpenPickerWithF4Key() const
1083 {
1084     return false;
1085 }
1086 
1087 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
supportsCalendarPicker(const AtomicString & type) const1088 bool RenderTheme::supportsCalendarPicker(const AtomicString& type) const
1089 {
1090     return type == InputTypeNames::date
1091         || type == InputTypeNames::datetime
1092         || type == InputTypeNames::datetime_local
1093         || type == InputTypeNames::month
1094         || type == InputTypeNames::week;
1095 }
1096 #endif
1097 
shouldUseFallbackTheme(RenderStyle *) const1098 bool RenderTheme::shouldUseFallbackTheme(RenderStyle*) const
1099 {
1100     return false;
1101 }
1102 
adjustStyleUsingFallbackTheme(RenderStyle * style,Element * e)1103 void RenderTheme::adjustStyleUsingFallbackTheme(RenderStyle* style, Element* e)
1104 {
1105     ControlPart part = style->appearance();
1106     switch (part) {
1107     case CheckboxPart:
1108         return adjustCheckboxStyleUsingFallbackTheme(style, e);
1109     case RadioPart:
1110         return adjustRadioStyleUsingFallbackTheme(style, e);
1111     default:
1112         break;
1113     }
1114 }
1115 
paintUsingFallbackTheme(RenderObject * o,const PaintInfo & i,const IntRect & r)1116 bool RenderTheme::paintUsingFallbackTheme(RenderObject* o, const PaintInfo& i, const IntRect& r)
1117 {
1118     ControlPart part = o->style()->appearance();
1119     switch (part) {
1120     case CheckboxPart:
1121         return paintCheckboxUsingFallbackTheme(o, i, r);
1122     case RadioPart:
1123         return paintRadioUsingFallbackTheme(o, i, r);
1124     default:
1125         break;
1126     }
1127     return true;
1128 }
1129 
1130 // static
setSizeIfAuto(RenderStyle * style,const IntSize & size)1131 void RenderTheme::setSizeIfAuto(RenderStyle* style, const IntSize& size)
1132 {
1133     if (style->width().isIntrinsicOrAuto())
1134         style->setWidth(Length(size.width(), Fixed));
1135     if (style->height().isAuto())
1136         style->setHeight(Length(size.height(), Fixed));
1137 }
1138 
paintCheckboxUsingFallbackTheme(RenderObject * o,const PaintInfo & i,const IntRect & r)1139 bool RenderTheme::paintCheckboxUsingFallbackTheme(RenderObject* o, const PaintInfo& i, const IntRect& r)
1140 {
1141     if (i.context->paintingDisabled())
1142         return false;
1143     blink::WebFallbackThemeEngine::ExtraParams extraParams;
1144     blink::WebCanvas* canvas = i.context->canvas();
1145     extraParams.button.checked = isChecked(o);
1146     extraParams.button.indeterminate = isIndeterminate(o);
1147 
1148     float zoomLevel = o->style()->effectiveZoom();
1149     GraphicsContextStateSaver stateSaver(*i.context);
1150     IntRect unzoomedRect = r;
1151     if (zoomLevel != 1) {
1152         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1153         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1154         i.context->translate(unzoomedRect.x(), unzoomedRect.y());
1155         i.context->scale(zoomLevel, zoomLevel);
1156         i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1157     }
1158 
1159     blink::Platform::current()->fallbackThemeEngine()->paint(canvas, blink::WebFallbackThemeEngine::PartCheckbox, getWebFallbackThemeState(this, o), blink::WebRect(unzoomedRect), &extraParams);
1160     return false;
1161 }
1162 
adjustCheckboxStyleUsingFallbackTheme(RenderStyle * style,Element *) const1163 void RenderTheme::adjustCheckboxStyleUsingFallbackTheme(RenderStyle* style, Element*) const
1164 {
1165     // If the width and height are both specified, then we have nothing to do.
1166     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
1167         return;
1168 
1169     IntSize size = blink::Platform::current()->fallbackThemeEngine()->getSize(blink::WebFallbackThemeEngine::PartCheckbox);
1170     float zoomLevel = style->effectiveZoom();
1171     size.setWidth(size.width() * zoomLevel);
1172     size.setHeight(size.height() * zoomLevel);
1173     setSizeIfAuto(style, size);
1174 
1175     // padding - not honored by WinIE, needs to be removed.
1176     style->resetPadding();
1177 
1178     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
1179     // for now, we will not honor it.
1180     style->resetBorder();
1181 }
1182 
paintRadioUsingFallbackTheme(RenderObject * o,const PaintInfo & i,const IntRect & r)1183 bool RenderTheme::paintRadioUsingFallbackTheme(RenderObject* o, const PaintInfo& i, const IntRect& r)
1184 {
1185     if (i.context->paintingDisabled())
1186         return false;
1187     blink::WebFallbackThemeEngine::ExtraParams extraParams;
1188     blink::WebCanvas* canvas = i.context->canvas();
1189     extraParams.button.checked = isChecked(o);
1190     extraParams.button.indeterminate = isIndeterminate(o);
1191 
1192     float zoomLevel = o->style()->effectiveZoom();
1193     GraphicsContextStateSaver stateSaver(*i.context);
1194     IntRect unzoomedRect = r;
1195     if (zoomLevel != 1) {
1196         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1197         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1198         i.context->translate(unzoomedRect.x(), unzoomedRect.y());
1199         i.context->scale(zoomLevel, zoomLevel);
1200         i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1201     }
1202 
1203     blink::Platform::current()->fallbackThemeEngine()->paint(canvas, blink::WebFallbackThemeEngine::PartRadio, getWebFallbackThemeState(this, o), blink::WebRect(unzoomedRect), &extraParams);
1204     return false;
1205 }
1206 
adjustRadioStyleUsingFallbackTheme(RenderStyle * style,Element *) const1207 void RenderTheme::adjustRadioStyleUsingFallbackTheme(RenderStyle* style, Element*) const
1208 {
1209     // If the width and height are both specified, then we have nothing to do.
1210     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
1211         return;
1212 
1213     IntSize size = blink::Platform::current()->fallbackThemeEngine()->getSize(blink::WebFallbackThemeEngine::PartRadio);
1214     float zoomLevel = style->effectiveZoom();
1215     size.setWidth(size.width() * zoomLevel);
1216     size.setHeight(size.height() * zoomLevel);
1217     setSizeIfAuto(style, size);
1218 
1219     // padding - not honored by WinIE, needs to be removed.
1220     style->resetPadding();
1221 
1222     // border - honored by WinIE, but looks terrible (just paints in the control box and turns off the Windows XP theme)
1223     // for now, we will not honor it.
1224     style->resetBorder();
1225 }
1226 
1227 } // namespace WebCore
1228