Home | History | Annotate | Download | only in rendering
      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 
     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 
     81 RenderTheme::RenderTheme()
     82     : m_hasCustomFocusRingColor(false)
     83 #if USE(NEW_THEME)
     84     , m_platformTheme(platformTheme())
     85 #endif
     86 {
     87 }
     88 
     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 
    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 
    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 
    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 
    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 
    427 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 
    445 String RenderTheme::formatMediaControlsCurrentTime(float currentTime, float /*duration*/) const
    446 {
    447     return formatMediaControlsTime(currentTime);
    448 }
    449 
    450 Color RenderTheme::activeSelectionBackgroundColor() const
    451 {
    452     return platformActiveSelectionBackgroundColor().blendWithWhite();
    453 }
    454 
    455 Color RenderTheme::inactiveSelectionBackgroundColor() const
    456 {
    457     return platformInactiveSelectionBackgroundColor().blendWithWhite();
    458 }
    459 
    460 Color RenderTheme::activeSelectionForegroundColor() const
    461 {
    462     return platformActiveSelectionForegroundColor();
    463 }
    464 
    465 Color RenderTheme::inactiveSelectionForegroundColor() const
    466 {
    467     return platformInactiveSelectionForegroundColor();
    468 }
    469 
    470 Color RenderTheme::activeListBoxSelectionBackgroundColor() const
    471 {
    472     return platformActiveListBoxSelectionBackgroundColor();
    473 }
    474 
    475 Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const
    476 {
    477     return platformInactiveListBoxSelectionBackgroundColor();
    478 }
    479 
    480 Color RenderTheme::activeListBoxSelectionForegroundColor() const
    481 {
    482     return platformActiveListBoxSelectionForegroundColor();
    483 }
    484 
    485 Color RenderTheme::inactiveListBoxSelectionForegroundColor() const
    486 {
    487     return platformInactiveListBoxSelectionForegroundColor();
    488 }
    489 
    490 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 
    496 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 
    502 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 
    509 Color RenderTheme::platformInactiveSelectionForegroundColor() const
    510 {
    511     // Use a black color by default.
    512     return Color::black;
    513 }
    514 
    515 Color RenderTheme::platformActiveListBoxSelectionBackgroundColor() const
    516 {
    517     return platformActiveSelectionBackgroundColor();
    518 }
    519 
    520 Color RenderTheme::platformActiveListBoxSelectionForegroundColor() const
    521 {
    522     return platformActiveSelectionForegroundColor();
    523 }
    524 
    525 Color RenderTheme::platformInactiveListBoxSelectionBackgroundColor() const
    526 {
    527     return platformInactiveSelectionBackgroundColor();
    528 }
    529 
    530 Color RenderTheme::platformInactiveListBoxSelectionForegroundColor() const
    531 {
    532     return platformInactiveSelectionForegroundColor();
    533 }
    534 
    535 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 
    549 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 
    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 
    571 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 
    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 
    610 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 
    626 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 
    631 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 
    646 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 
    674 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 
    687 bool RenderTheme::isChecked(const RenderObject* o) const
    688 {
    689     if (!isHTMLInputElement(o->node()))
    690         return false;
    691     return toHTMLInputElement(o->node())->shouldAppearChecked();
    692 }
    693 
    694 bool RenderTheme::isIndeterminate(const RenderObject* o) const
    695 {
    696     if (!isHTMLInputElement(o->node()))
    697         return false;
    698     return toHTMLInputElement(o->node())->shouldAppearIndeterminate();
    699 }
    700 
    701 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 
    709 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 
    721 bool RenderTheme::isPressed(const RenderObject* o) const
    722 {
    723     if (!o->node())
    724         return false;
    725     return o->node()->active();
    726 }
    727 
    728 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 
    738 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 
    747 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 
    758 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 
    769 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 
    784 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 
    799 void RenderTheme::adjustButtonStyle(RenderStyle* style, Element*) const
    800 {
    801 }
    802 
    803 void RenderTheme::adjustInnerSpinButtonStyle(RenderStyle*, Element*) const
    804 {
    805 }
    806 #endif
    807 
    808 void RenderTheme::adjustMenuListStyle(RenderStyle*, Element*) const
    809 {
    810 }
    811 
    812 IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
    813 {
    814     return bounds.size();
    815 }
    816 
    817 bool RenderTheme::supportsMeter(ControlPart) const
    818 {
    819     return false;
    820 }
    821 
    822 bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
    823 {
    824     return true;
    825 }
    826 
    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 
    909 double RenderTheme::animationRepeatIntervalForProgressBar(RenderProgress*) const
    910 {
    911     return 0;
    912 }
    913 
    914 double RenderTheme::animationDurationForProgressBar(RenderProgress*) const
    915 {
    916     return 0;
    917 }
    918 
    919 bool RenderTheme::shouldHaveSpinButton(HTMLInputElement* inputElement) const
    920 {
    921     return inputElement->isSteppable() && !inputElement->isRangeControl();
    922 }
    923 
    924 void RenderTheme::adjustMenuListButtonStyle(RenderStyle*, Element*) const
    925 {
    926 }
    927 
    928 void RenderTheme::adjustSliderThumbStyle(RenderStyle* style, Element* element) const
    929 {
    930     adjustSliderThumbSize(style, element);
    931 }
    932 
    933 void RenderTheme::adjustSliderThumbSize(RenderStyle*, Element*) const
    934 {
    935 }
    936 
    937 void RenderTheme::adjustSearchFieldStyle(RenderStyle*, Element*) const
    938 {
    939 }
    940 
    941 void RenderTheme::adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const
    942 {
    943 }
    944 
    945 void RenderTheme::adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const
    946 {
    947 }
    948 
    949 void RenderTheme::adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const
    950 {
    951 }
    952 
    953 void RenderTheme::platformColorsDidChange()
    954 {
    955     Page::scheduleForcedStyleRecalcForAllPages();
    956 }
    957 
    958 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 
   1038 Color RenderTheme::platformActiveTextSearchHighlightColor() const
   1039 {
   1040     return Color(255, 150, 50); // Orange.
   1041 }
   1042 
   1043 Color RenderTheme::platformInactiveTextSearchHighlightColor() const
   1044 {
   1045     return Color(255, 255, 0); // Yellow.
   1046 }
   1047 
   1048 Color RenderTheme::tapHighlightColor()
   1049 {
   1050     return theme().platformTapHighlightColor();
   1051 }
   1052 
   1053 void RenderTheme::setCustomFocusRingColor(const Color& c)
   1054 {
   1055     m_customFocusRingColor = c;
   1056     m_hasCustomFocusRingColor = true;
   1057 }
   1058 
   1059 Color RenderTheme::focusRingColor() const
   1060 {
   1061     return m_hasCustomFocusRingColor ? m_customFocusRingColor : theme().platformFocusRingColor();
   1062 }
   1063 
   1064 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 
   1082 bool RenderTheme::shouldOpenPickerWithF4Key() const
   1083 {
   1084     return false;
   1085 }
   1086 
   1087 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
   1088 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 
   1098 bool RenderTheme::shouldUseFallbackTheme(RenderStyle*) const
   1099 {
   1100     return false;
   1101 }
   1102 
   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 
   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
   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 
   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 
   1163 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 
   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 
   1207 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