Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2008, 2009 Google, Inc.
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Library General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Library General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Library General Public License
     16  * along with this library; see the file COPYING.LIB.  If not, write to
     17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18  * Boston, MA 02110-1301, USA.
     19  */
     20 
     21 #import "config.h"
     22 #import "core/rendering/RenderThemeChromiumMac.h"
     23 
     24 #import "CSSValueKeywords.h"
     25 #import "HTMLNames.h"
     26 #import "UserAgentStyleSheets.h"
     27 #import "core/css/CSSValueList.h"
     28 #import "core/dom/Document.h"
     29 #import "core/dom/Element.h"
     30 #import "core/fileapi/FileList.h"
     31 #import "core/html/HTMLInputElement.h"
     32 #import "core/html/HTMLMediaElement.h"
     33 #import "core/html/HTMLMeterElement.h"
     34 #import "core/html/HTMLPlugInImageElement.h"
     35 #import "core/html/TimeRanges.h"
     36 #import "core/html/shadow/MediaControlElements.h"
     37 #import "core/page/FrameView.h"
     38 #import "core/platform/LayoutTestSupport.h"
     39 #import "core/platform/LocalizedStrings.h"
     40 #import "core/platform/SharedBuffer.h"
     41 #import "core/platform/graphics/BitmapImage.h"
     42 #import "core/platform/graphics/GraphicsContextStateSaver.h"
     43 #import "core/platform/graphics/Image.h"
     44 #import "core/platform/graphics/ImageBuffer.h"
     45 #import "core/platform/graphics/StringTruncator.h"
     46 #import "core/platform/graphics/cg/GraphicsContextCG.h"
     47 #import "core/platform/graphics/mac/ColorMac.h"
     48 #import "core/platform/mac/LocalCurrentGraphicsContext.h"
     49 #import "core/platform/mac/ThemeMac.h"
     50 #import "core/platform/mac/WebCoreNSCellExtras.h"
     51 #import "core/rendering/PaintInfo.h"
     52 #import "core/rendering/RenderLayer.h"
     53 #import "core/rendering/RenderMedia.h"
     54 #import "core/rendering/RenderMediaControls.h"
     55 #import "core/rendering/RenderMediaControlsChromium.h"
     56 #import "core/rendering/RenderMeter.h"
     57 #import "core/rendering/RenderProgress.h"
     58 #import "core/rendering/RenderSlider.h"
     59 #import "core/rendering/RenderView.h"
     60 
     61 #import <AvailabilityMacros.h>
     62 #import <Carbon/Carbon.h>
     63 #import <Cocoa/Cocoa.h>
     64 #import <math.h>
     65 #import <wtf/RetainPtr.h>
     66 #import <wtf/StdLibExtras.h>
     67 
     68 using namespace std;
     69 
     70 // The methods in this file are specific to the Mac OS X platform.
     71 
     72 // We estimate the animation rate of a Mac OS X progress bar is 33 fps.
     73 // Hard code the value here because we haven't found API for it.
     74 const double progressAnimationFrameRate = 0.033;
     75 
     76 // Mac OS X progress bar animation seems to have 256 frames.
     77 const double progressAnimationNumFrames = 256;
     78 
     79 @interface WebCoreRenderThemeNotificationObserver : NSObject
     80 {
     81     WebCore::RenderTheme *_theme;
     82 }
     83 
     84 - (id)initWithTheme:(WebCore::RenderTheme *)theme;
     85 - (void)systemColorsDidChange:(NSNotification *)notification;
     86 
     87 @end
     88 
     89 @implementation WebCoreRenderThemeNotificationObserver
     90 
     91 - (id)initWithTheme:(WebCore::RenderTheme *)theme
     92 {
     93     if (!(self = [super init]))
     94         return nil;
     95 
     96     _theme = theme;
     97     return self;
     98 }
     99 
    100 - (void)systemColorsDidChange:(NSNotification *)unusedNotification
    101 {
    102     ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]);
    103     _theme->platformColorsDidChange();
    104 }
    105 
    106 @end
    107 
    108 @interface NSTextFieldCell (WKDetails)
    109 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
    110 @end
    111 
    112 
    113 @interface WebCoreTextFieldCell : NSTextFieldCell
    114 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
    115 @end
    116 
    117 @implementation WebCoreTextFieldCell
    118 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus
    119 {
    120     // FIXME: This is a post-Lion-only workaround for <rdar://problem/11385461>. When that bug is resolved, we should remove this code.
    121     CFMutableDictionaryRef coreUIDrawOptions = CFDictionaryCreateMutableCopy(NULL, 0, [super _coreUIDrawOptionsWithFrame:cellFrame inView:controlView includeFocus:includeFocus]);
    122     CFDictionarySetValue(coreUIDrawOptions, @"borders only", kCFBooleanTrue);
    123     return (CFDictionaryRef)[NSMakeCollectable(coreUIDrawOptions) autorelease];
    124 }
    125 @end
    126 
    127 @interface RTCMFlippedView : NSView
    128 {}
    129 
    130 - (BOOL)isFlipped;
    131 - (NSText *)currentEditor;
    132 
    133 @end
    134 
    135 @implementation RTCMFlippedView
    136 
    137 - (BOOL)isFlipped {
    138     return [[NSGraphicsContext currentContext] isFlipped];
    139 }
    140 
    141 - (NSText *)currentEditor {
    142     return nil;
    143 }
    144 
    145 @end
    146 
    147 // Forward declare Mac SPIs.
    148 extern "C" {
    149 void _NSDrawCarbonThemeBezel(NSRect frame, BOOL enabled, BOOL flipped);
    150 // Request for public API: rdar://13787640
    151 void _NSDrawCarbonThemeListBox(NSRect frame, BOOL enabled, BOOL flipped, BOOL always_yes);
    152 }
    153 
    154 namespace WebCore {
    155 
    156 using namespace HTMLNames;
    157 
    158 enum {
    159     topMargin,
    160     rightMargin,
    161     bottomMargin,
    162     leftMargin
    163 };
    164 
    165 enum {
    166     topPadding,
    167     rightPadding,
    168     bottomPadding,
    169     leftPadding
    170 };
    171 
    172 RenderThemeChromiumMac::RenderThemeChromiumMac()
    173     : m_notificationObserver(AdoptNS, [[WebCoreRenderThemeNotificationObserver alloc] initWithTheme:this])
    174 {
    175     [[NSNotificationCenter defaultCenter] addObserver:m_notificationObserver.get()
    176                                                         selector:@selector(systemColorsDidChange:)
    177                                                             name:NSSystemColorsDidChangeNotification
    178                                                           object:nil];
    179 }
    180 
    181 RenderThemeChromiumMac::~RenderThemeChromiumMac()
    182 {
    183     [[NSNotificationCenter defaultCenter] removeObserver:m_notificationObserver.get()];
    184 }
    185 
    186 Color RenderThemeChromiumMac::platformActiveSelectionBackgroundColor() const
    187 {
    188     NSColor* color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    189     return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
    190 }
    191 
    192 Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const
    193 {
    194     NSColor* color = [[NSColor secondarySelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    195     return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
    196 }
    197 
    198 Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const
    199 {
    200     NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    201     return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
    202 }
    203 
    204 Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const
    205 {
    206     return Color::white;
    207 }
    208 
    209 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const
    210 {
    211     return Color::black;
    212 }
    213 
    214 Color RenderThemeChromiumMac::platformFocusRingColor() const
    215 {
    216     if (usesTestModeFocusRingColor())
    217         return oldAquaFocusRingColor();
    218 
    219     return systemColor(CSSValueWebkitFocusRingColor);
    220 }
    221 
    222 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const
    223 {
    224     return platformInactiveSelectionBackgroundColor();
    225 }
    226 
    227 static FontWeight toFontWeight(NSInteger appKitFontWeight)
    228 {
    229     ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15);
    230     if (appKitFontWeight > 14)
    231         appKitFontWeight = 14;
    232     else if (appKitFontWeight < 1)
    233         appKitFontWeight = 1;
    234 
    235     static FontWeight fontWeights[] = {
    236         FontWeight100,
    237         FontWeight100,
    238         FontWeight200,
    239         FontWeight300,
    240         FontWeight400,
    241         FontWeight500,
    242         FontWeight600,
    243         FontWeight600,
    244         FontWeight700,
    245         FontWeight800,
    246         FontWeight800,
    247         FontWeight900,
    248         FontWeight900,
    249         FontWeight900
    250     };
    251     return fontWeights[appKitFontWeight - 1];
    252 }
    253 
    254 void RenderThemeChromiumMac::systemFont(CSSValueID cssValueId, FontDescription& fontDescription) const
    255 {
    256     DEFINE_STATIC_LOCAL(FontDescription, systemFont, ());
    257     DEFINE_STATIC_LOCAL(FontDescription, smallSystemFont, ());
    258     DEFINE_STATIC_LOCAL(FontDescription, menuFont, ());
    259     DEFINE_STATIC_LOCAL(FontDescription, labelFont, ());
    260     DEFINE_STATIC_LOCAL(FontDescription, miniControlFont, ());
    261     DEFINE_STATIC_LOCAL(FontDescription, smallControlFont, ());
    262     DEFINE_STATIC_LOCAL(FontDescription, controlFont, ());
    263 
    264     FontDescription* cachedDesc;
    265     NSFont* font = nil;
    266     switch (cssValueId) {
    267         case CSSValueSmallCaption:
    268             cachedDesc = &smallSystemFont;
    269             if (!smallSystemFont.isAbsoluteSize())
    270                 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
    271             break;
    272         case CSSValueMenu:
    273             cachedDesc = &menuFont;
    274             if (!menuFont.isAbsoluteSize())
    275                 font = [NSFont menuFontOfSize:[NSFont systemFontSize]];
    276             break;
    277         case CSSValueStatusBar:
    278             cachedDesc = &labelFont;
    279             if (!labelFont.isAbsoluteSize())
    280                 font = [NSFont labelFontOfSize:[NSFont labelFontSize]];
    281             break;
    282         case CSSValueWebkitMiniControl:
    283             cachedDesc = &miniControlFont;
    284             if (!miniControlFont.isAbsoluteSize())
    285                 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
    286             break;
    287         case CSSValueWebkitSmallControl:
    288             cachedDesc = &smallControlFont;
    289             if (!smallControlFont.isAbsoluteSize())
    290                 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]];
    291             break;
    292         case CSSValueWebkitControl:
    293             cachedDesc = &controlFont;
    294             if (!controlFont.isAbsoluteSize())
    295                 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
    296             break;
    297         default:
    298             cachedDesc = &systemFont;
    299             if (!systemFont.isAbsoluteSize())
    300                 font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
    301     }
    302 
    303     if (font) {
    304         NSFontManager *fontManager = [NSFontManager sharedFontManager];
    305         cachedDesc->setIsAbsoluteSize(true);
    306         cachedDesc->setGenericFamily(FontDescription::NoFamily);
    307         cachedDesc->firstFamily().setFamily([font webCoreFamilyName]);
    308         cachedDesc->setSpecifiedSize([font pointSize]);
    309         cachedDesc->setWeight(toFontWeight([fontManager weightOfFont:font]));
    310         cachedDesc->setItalic([fontManager traitsOfFont:font] & NSItalicFontMask);
    311     }
    312     fontDescription = *cachedDesc;
    313 }
    314 
    315 static RGBA32 convertNSColorToColor(NSColor *color)
    316 {
    317     NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    318     if (colorInColorSpace) {
    319         static const double scaleFactor = nextafter(256.0, 0.0);
    320         return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]),
    321             static_cast<int>(scaleFactor * [colorInColorSpace greenComponent]),
    322             static_cast<int>(scaleFactor * [colorInColorSpace blueComponent]));
    323     }
    324 
    325     // This conversion above can fail if the NSColor in question is an NSPatternColor
    326     // (as many system colors are). These colors are actually a repeating pattern
    327     // not just a solid color. To work around this we simply draw a 1x1 image of
    328     // the color and use that pixel's color. It might be better to use an average of
    329     // the colors in the pattern instead.
    330     NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
    331                                                                              pixelsWide:1
    332                                                                              pixelsHigh:1
    333                                                                           bitsPerSample:8
    334                                                                         samplesPerPixel:4
    335                                                                                hasAlpha:YES
    336                                                                                isPlanar:NO
    337                                                                          colorSpaceName:NSDeviceRGBColorSpace
    338                                                                             bytesPerRow:4
    339                                                                            bitsPerPixel:32];
    340 
    341     [NSGraphicsContext saveGraphicsState];
    342     [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]];
    343     NSEraseRect(NSMakeRect(0, 0, 1, 1));
    344     [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
    345     [NSGraphicsContext restoreGraphicsState];
    346 
    347     NSUInteger pixel[4];
    348     [offscreenRep getPixel:pixel atX:0 y:0];
    349 
    350     [offscreenRep release];
    351 
    352     return makeRGB(pixel[0], pixel[1], pixel[2]);
    353 }
    354 
    355 static RGBA32 menuBackgroundColor()
    356 {
    357     NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
    358                                                                              pixelsWide:1
    359                                                                              pixelsHigh:1
    360                                                                           bitsPerSample:8
    361                                                                         samplesPerPixel:4
    362                                                                                hasAlpha:YES
    363                                                                                isPlanar:NO
    364                                                                          colorSpaceName:NSDeviceRGBColorSpace
    365                                                                             bytesPerRow:4
    366                                                                            bitsPerPixel:32];
    367 
    368     CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep] graphicsPort]);
    369     CGRect rect = CGRectMake(0, 0, 1, 1);
    370     HIThemeMenuDrawInfo drawInfo;
    371     drawInfo.version =  0;
    372     drawInfo.menuType = kThemeMenuTypePopUp;
    373     HIThemeDrawMenuBackground(&rect, &drawInfo, context, kHIThemeOrientationInverted);
    374 
    375     NSUInteger pixel[4];
    376     [offscreenRep getPixel:pixel atX:0 y:0];
    377 
    378     [offscreenRep release];
    379 
    380     return makeRGB(pixel[0], pixel[1], pixel[2]);
    381 }
    382 
    383 void RenderThemeChromiumMac::platformColorsDidChange()
    384 {
    385     m_systemColorCache.clear();
    386     RenderTheme::platformColorsDidChange();
    387 }
    388 
    389 Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
    390 {
    391     {
    392         HashMap<int, RGBA32>::iterator it = m_systemColorCache.find(cssValueId);
    393         if (it != m_systemColorCache.end())
    394             return it->value;
    395     }
    396 
    397     Color color = Color::transparent;
    398     switch (cssValueId) {
    399         case CSSValueActiveborder:
    400             color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
    401             break;
    402         case CSSValueActivecaption:
    403             color = convertNSColorToColor([NSColor windowFrameTextColor]);
    404             break;
    405         case CSSValueAppworkspace:
    406             color = convertNSColorToColor([NSColor headerColor]);
    407             break;
    408         case CSSValueBackground:
    409             // Use theme independent default
    410             break;
    411         case CSSValueButtonface:
    412             // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
    413             // We may want to change this to use the NSColor in future.
    414             color = 0xFFC0C0C0;
    415             break;
    416         case CSSValueButtonhighlight:
    417             color = convertNSColorToColor([NSColor controlHighlightColor]);
    418             break;
    419         case CSSValueButtonshadow:
    420             color = convertNSColorToColor([NSColor controlShadowColor]);
    421             break;
    422         case CSSValueButtontext:
    423             color = convertNSColorToColor([NSColor controlTextColor]);
    424             break;
    425         case CSSValueCaptiontext:
    426             color = convertNSColorToColor([NSColor textColor]);
    427             break;
    428         case CSSValueGraytext:
    429             color = convertNSColorToColor([NSColor disabledControlTextColor]);
    430             break;
    431         case CSSValueHighlight:
    432             color = convertNSColorToColor([NSColor selectedTextBackgroundColor]);
    433             break;
    434         case CSSValueHighlighttext:
    435             color = convertNSColorToColor([NSColor selectedTextColor]);
    436             break;
    437         case CSSValueInactiveborder:
    438             color = convertNSColorToColor([NSColor controlBackgroundColor]);
    439             break;
    440         case CSSValueInactivecaption:
    441             color = convertNSColorToColor([NSColor controlBackgroundColor]);
    442             break;
    443         case CSSValueInactivecaptiontext:
    444             color = convertNSColorToColor([NSColor textColor]);
    445             break;
    446         case CSSValueInfobackground:
    447             // There is no corresponding NSColor for this so we use a hard coded value.
    448             color = 0xFFFBFCC5;
    449             break;
    450         case CSSValueInfotext:
    451             color = convertNSColorToColor([NSColor textColor]);
    452             break;
    453         case CSSValueMenu:
    454             color = menuBackgroundColor();
    455             break;
    456         case CSSValueMenutext:
    457             color = convertNSColorToColor([NSColor selectedMenuItemTextColor]);
    458             break;
    459         case CSSValueScrollbar:
    460             color = convertNSColorToColor([NSColor scrollBarColor]);
    461             break;
    462         case CSSValueText:
    463             color = convertNSColorToColor([NSColor textColor]);
    464             break;
    465         case CSSValueThreeddarkshadow:
    466             color = convertNSColorToColor([NSColor controlDarkShadowColor]);
    467             break;
    468         case CSSValueThreedshadow:
    469             color = convertNSColorToColor([NSColor shadowColor]);
    470             break;
    471         case CSSValueThreedface:
    472             // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
    473             // We may want to change this to use the NSColor in future.
    474             color = 0xFFC0C0C0;
    475             break;
    476         case CSSValueThreedhighlight:
    477             color = convertNSColorToColor([NSColor highlightColor]);
    478             break;
    479         case CSSValueThreedlightshadow:
    480             color = convertNSColorToColor([NSColor controlLightHighlightColor]);
    481             break;
    482         case CSSValueWebkitFocusRingColor:
    483             color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
    484             break;
    485         case CSSValueWindow:
    486             color = convertNSColorToColor([NSColor windowBackgroundColor]);
    487             break;
    488         case CSSValueWindowframe:
    489             color = convertNSColorToColor([NSColor windowFrameColor]);
    490             break;
    491         case CSSValueWindowtext:
    492             color = convertNSColorToColor([NSColor windowFrameTextColor]);
    493             break;
    494         default:
    495             break;
    496     }
    497 
    498     if (!color.alpha())
    499         color = RenderTheme::systemColor(cssValueId);
    500 
    501     if (color.alpha())
    502         m_systemColorCache.set(cssValueId, color.rgb());
    503 
    504     return color;
    505 }
    506 
    507 bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const CachedUAStyle& uaStyle) const
    508 {
    509     if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart)
    510         return style->border() != uaStyle.border || style->boxShadow();
    511 
    512     // FIXME: This is horrible, but there is not much else that can be done.  Menu lists cannot draw properly when
    513     // scaled.  They can't really draw properly when transformed either.  We can't detect the transform case at style
    514     // adjustment time so that will just have to stay broken.  We can however detect that we're zooming.  If zooming
    515     // is in effect we treat it like the control is styled.
    516     if (style->appearance() == MenulistPart && style->effectiveZoom() != 1.0f)
    517         return true;
    518     // FIXME: NSSearchFieldCell doesn't work well when scaled.
    519     if (style->appearance() == SearchFieldPart && style->effectiveZoom() != 1)
    520         return true;
    521 
    522     return RenderTheme::isControlStyled(style, uaStyle);
    523 }
    524 
    525 const int sliderThumbShadowBlur = 1;
    526 
    527 void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r)
    528 {
    529     ControlPart part = o->style()->appearance();
    530 
    531 #if USE(NEW_THEME)
    532     switch (part) {
    533         case CheckboxPart:
    534         case RadioPart:
    535         case PushButtonPart:
    536         case SquareButtonPart:
    537         case ButtonPart:
    538         case InnerSpinButtonPart:
    539             return RenderTheme::adjustRepaintRect(o, r);
    540         default:
    541             break;
    542     }
    543 #endif
    544 
    545     float zoomLevel = o->style()->effectiveZoom();
    546 
    547     if (part == MenulistPart) {
    548         setPopupButtonCellState(o, r);
    549         IntSize size = popupButtonSizes()[[popupButton() controlSize]];
    550         size.setHeight(size.height() * zoomLevel);
    551         size.setWidth(r.width());
    552         r = inflateRect(r, size, popupButtonMargins(), zoomLevel);
    553     } else if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
    554         r.setHeight(r.height() + sliderThumbShadowBlur);
    555     }
    556 }
    557 
    558 IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& size, const int* margins, float zoomLevel) const
    559 {
    560     // Only do the inflation if the available width/height are too small.  Otherwise try to
    561     // fit the glow/check space into the available box's width/height.
    562     int widthDelta = r.width() - (size.width() + margins[leftMargin] * zoomLevel + margins[rightMargin] * zoomLevel);
    563     int heightDelta = r.height() - (size.height() + margins[topMargin] * zoomLevel + margins[bottomMargin] * zoomLevel);
    564     IntRect result(r);
    565     if (widthDelta < 0) {
    566         result.setX(result.x() - margins[leftMargin] * zoomLevel);
    567         result.setWidth(result.width() - widthDelta);
    568     }
    569     if (heightDelta < 0) {
    570         result.setY(result.y() - margins[topMargin] * zoomLevel);
    571         result.setHeight(result.height() - heightDelta);
    572     }
    573     return result;
    574 }
    575 
    576 FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const
    577 {
    578     FloatRect partRect(inputRect);
    579 
    580     // Compute an offset between the part renderer and the input renderer
    581     FloatSize offsetFromInputRenderer;
    582     const RenderObject* renderer = partRenderer;
    583     while (renderer && renderer != inputRenderer) {
    584         RenderObject* containingRenderer = renderer->container();
    585         offsetFromInputRenderer -= roundedIntSize(renderer->offsetFromContainer(containingRenderer, LayoutPoint()));
    586         renderer = containingRenderer;
    587     }
    588     // If the input renderer was not a container, something went wrong
    589     ASSERT(renderer == inputRenderer);
    590     // Move the rect into partRenderer's coords
    591     partRect.move(offsetFromInputRenderer);
    592     // Account for the local drawing offset (tx, ty)
    593     partRect.move(r.x(), r.y());
    594 
    595     return partRect;
    596 }
    597 
    598 void RenderThemeChromiumMac::updateCheckedState(NSCell* cell, const RenderObject* o)
    599 {
    600     bool oldIndeterminate = [cell state] == NSMixedState;
    601     bool indeterminate = isIndeterminate(o);
    602     bool checked = isChecked(o);
    603 
    604     if (oldIndeterminate != indeterminate) {
    605         [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
    606         return;
    607     }
    608 
    609     bool oldChecked = [cell state] == NSOnState;
    610     if (checked != oldChecked)
    611         [cell setState:checked ? NSOnState : NSOffState];
    612 }
    613 
    614 void RenderThemeChromiumMac::updateEnabledState(NSCell* cell, const RenderObject* o)
    615 {
    616     bool oldEnabled = [cell isEnabled];
    617     bool enabled = isEnabled(o);
    618     if (enabled != oldEnabled)
    619         [cell setEnabled:enabled];
    620 }
    621 
    622 void RenderThemeChromiumMac::updateFocusedState(NSCell* cell, const RenderObject* o)
    623 {
    624     bool oldFocused = [cell showsFirstResponder];
    625     bool focused = isFocused(o) && o->style()->outlineStyleIsAuto();
    626     if (focused != oldFocused)
    627         [cell setShowsFirstResponder:focused];
    628 }
    629 
    630 void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject* o)
    631 {
    632     bool oldPressed = [cell isHighlighted];
    633     bool pressed = (o->node() && o->node()->active());
    634     if (pressed != oldPressed)
    635         [cell setHighlighted:pressed];
    636 }
    637 
    638 bool RenderThemeChromiumMac::controlSupportsTints(const RenderObject* o) const
    639 {
    640     // An alternate way to implement this would be to get the appropriate cell object
    641     // and call the private _needRedrawOnWindowChangedKeyState method. An advantage of
    642     // that would be that we would match AppKit behavior more closely, but a disadvantage
    643     // would be that we would rely on an AppKit SPI method.
    644 
    645     if (!isEnabled(o))
    646         return false;
    647 
    648     // Checkboxes only have tint when checked.
    649     if (o->style()->appearance() == CheckboxPart)
    650         return isChecked(o);
    651 
    652     // For now assume other controls have tint if enabled.
    653     return true;
    654 }
    655 
    656 NSControlSize RenderThemeChromiumMac::controlSizeForFont(RenderStyle* style) const
    657 {
    658     int fontSize = style->fontSize();
    659     if (fontSize >= 16)
    660         return NSRegularControlSize;
    661     if (fontSize >= 11)
    662         return NSSmallControlSize;
    663     return NSMiniControlSize;
    664 }
    665 
    666 // We don't use controlSizeForFont() for search field decorations because it needs to fit
    667 // into the search field. The font size will already be modified by
    668 // setFontFromControlSize() called on the search field.
    669 static NSControlSize searchFieldControlSizeForFont(RenderStyle* style)
    670 {
    671     int fontSize = style->fontSize();
    672     if (fontSize >= 13)
    673         return NSRegularControlSize;
    674     if (fontSize >= 11)
    675         return NSSmallControlSize;
    676     return NSMiniControlSize;
    677 }
    678 
    679 void RenderThemeChromiumMac::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize, float zoomLevel)
    680 {
    681     NSControlSize size;
    682     if (minSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomLevel) &&
    683         minSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomLevel))
    684         size = NSRegularControlSize;
    685     else if (minSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomLevel) &&
    686              minSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomLevel))
    687         size = NSSmallControlSize;
    688     else
    689         size = NSMiniControlSize;
    690     if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
    691         [cell setControlSize:size];
    692 }
    693 
    694 IntSize RenderThemeChromiumMac::sizeForFont(RenderStyle* style, const IntSize* sizes) const
    695 {
    696     if (style->effectiveZoom() != 1.0f) {
    697         IntSize result = sizes[controlSizeForFont(style)];
    698         return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
    699     }
    700     return sizes[controlSizeForFont(style)];
    701 }
    702 
    703 IntSize RenderThemeChromiumMac::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const
    704 {
    705     if (style->effectiveZoom() != 1.0f) {
    706         IntSize result = sizes[controlSizeForSystemFont(style)];
    707         return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
    708     }
    709     return sizes[controlSizeForSystemFont(style)];
    710 }
    711 
    712 void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const
    713 {
    714     // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
    715     IntSize size = sizeForFont(style, sizes);
    716     if (style->width().isIntrinsicOrAuto() && size.width() > 0)
    717         style->setWidth(Length(size.width(), Fixed));
    718     if (style->height().isAuto() && size.height() > 0)
    719         style->setHeight(Length(size.height(), Fixed));
    720 }
    721 
    722 void RenderThemeChromiumMac::setFontFromControlSize(RenderStyle* style, NSControlSize controlSize) const
    723 {
    724     FontDescription fontDescription;
    725     fontDescription.setIsAbsoluteSize(true);
    726     fontDescription.setGenericFamily(FontDescription::SerifFamily);
    727 
    728     NSFont* font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSize]];
    729     fontDescription.firstFamily().setFamily([font webCoreFamilyName]);
    730     fontDescription.setComputedSize([font pointSize] * style->effectiveZoom());
    731     fontDescription.setSpecifiedSize([font pointSize] * style->effectiveZoom());
    732 
    733     // Reset line height
    734     style->setLineHeight(RenderStyle::initialLineHeight());
    735 
    736     if (style->setFontDescription(fontDescription))
    737         style->font().update(0);
    738 }
    739 
    740 NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
    741 {
    742     float fontSize = style->fontSize();
    743     float zoomLevel = style->effectiveZoom();
    744     if (zoomLevel != 1)
    745         fontSize /= zoomLevel;
    746     if (fontSize >= [NSFont systemFontSizeForControlSize:NSRegularControlSize])
    747         return NSRegularControlSize;
    748     if (fontSize >= [NSFont systemFontSizeForControlSize:NSSmallControlSize])
    749         return NSSmallControlSize;
    750     return NSMiniControlSize;
    751 }
    752 
    753 bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
    754 {
    755     LocalCurrentGraphicsContext localContext(paintInfo.context);
    756 
    757 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
    758     bool useNSTextFieldCell = o->style()->hasAppearance()
    759         && o->style()->visitedDependentColor(CSSPropertyBackgroundColor) == Color::white
    760         && !o->style()->hasBackgroundImage();
    761 
    762     // We do not use NSTextFieldCell to draw styled text fields on Lion and SnowLeopard because
    763     // there are a number of bugs on those platforms that require NSTextFieldCell to be in charge
    764     // of painting its own background. We need WebCore to paint styled backgrounds, so we'll use
    765     // this AppKit SPI function instead.
    766     if (!useNSTextFieldCell) {
    767         _NSDrawCarbonThemeBezel(r, isEnabled(o) && !isReadOnlyControl(o), YES);
    768         return false;
    769     }
    770 #endif
    771 
    772     NSTextFieldCell *textField = this->textField();
    773 
    774     GraphicsContextStateSaver stateSaver(*paintInfo.context);
    775 
    776     [textField setEnabled:(isEnabled(o) && !isReadOnlyControl(o))];
    777     [textField drawWithFrame:NSRect(r) inView:documentViewFor(o)];
    778 
    779     [textField setControlView:nil];
    780 
    781     return false;
    782 }
    783 
    784 void RenderThemeChromiumMac::adjustTextFieldStyle(RenderStyle*, Element*) const
    785 {
    786 }
    787 
    788 bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const PaintInfo& paintInfo, const IntRect& r)
    789 {
    790     if (paintInfo.context->paintingDisabled())
    791         return true;
    792 
    793     // This draws the caps lock indicator as it was done by WKDrawCapsLockIndicator.
    794     LocalCurrentGraphicsContext localContext(paintInfo.context);
    795     CGContextRef c = localContext.cgContext();
    796     CGMutablePathRef shape = CGPathCreateMutable();
    797 
    798     // To draw the caps lock indicator, draw the shape into a small
    799     // square that is then scaled to the size of r.
    800     const CGFloat kSquareSize = 17;
    801 
    802     // Create a rounted square shape.
    803     CGPathMoveToPoint(shape, NULL, 16.5, 4.5);
    804     CGPathAddArc(shape, NULL, 12.5, 12.5, 4, 0,        M_PI_2,   false);
    805     CGPathAddArc(shape, NULL, 4.5,  12.5, 4, M_PI_2,   M_PI,     false);
    806     CGPathAddArc(shape, NULL, 4.5,  4.5,  4, M_PI,     3*M_PI/2, false);
    807     CGPathAddArc(shape, NULL, 12.5, 4.5,  4, 3*M_PI/2, 0,        false);
    808 
    809     // Draw the arrow - note this is drawing in a flipped coordinate system, so the
    810     // arrow is pointing down.
    811     CGPathMoveToPoint(shape, NULL, 8.5, 2);  // Tip point.
    812     CGPathAddLineToPoint(shape, NULL, 4,     7);
    813     CGPathAddLineToPoint(shape, NULL, 6.25,  7);
    814     CGPathAddLineToPoint(shape, NULL, 6.25,  10.25);
    815     CGPathAddLineToPoint(shape, NULL, 10.75, 10.25);
    816     CGPathAddLineToPoint(shape, NULL, 10.75, 7);
    817     CGPathAddLineToPoint(shape, NULL, 13,    7);
    818     CGPathAddLineToPoint(shape, NULL, 8.5,   2);
    819 
    820     // Draw the rectangle that underneath (or above in the flipped system) the arrow.
    821     CGPathAddLineToPoint(shape, NULL, 10.75, 12);
    822     CGPathAddLineToPoint(shape, NULL, 6.25,  12);
    823     CGPathAddLineToPoint(shape, NULL, 6.25,  14.25);
    824     CGPathAddLineToPoint(shape, NULL, 10.75, 14.25);
    825     CGPathAddLineToPoint(shape, NULL, 10.75, 12);
    826 
    827     // Scale and translate the shape.
    828     CGRect cgr = r;
    829     CGFloat maxX = CGRectGetMaxX(cgr);
    830     CGFloat minY = CGRectGetMinY(cgr);
    831     CGFloat heightScale = r.height() / kSquareSize;
    832     CGAffineTransform transform = CGAffineTransformMake(
    833         heightScale, 0,  // A  B
    834         0, heightScale,  // C  D
    835         maxX - r.height(), minY);  // Tx Ty
    836 
    837     CGMutablePathRef paintPath = CGPathCreateMutable();
    838     CGPathAddPath(paintPath, &transform, shape);
    839     CGPathRelease(shape);
    840 
    841     CGContextSetRGBFillColor(c, 0, 0, 0, 0.4);
    842     CGContextBeginPath(c);
    843     CGContextAddPath(c, paintPath);
    844     CGContextFillPath(c);
    845     CGPathRelease(paintPath);
    846 
    847     return false;
    848 }
    849 
    850 bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
    851 {
    852     LocalCurrentGraphicsContext localContext(paintInfo.context);
    853     _NSDrawCarbonThemeListBox(r, isEnabled(o) && !isReadOnlyControl(o), YES, YES);
    854     return false;
    855 }
    856 
    857 void RenderThemeChromiumMac::adjustTextAreaStyle(RenderStyle*, Element*) const
    858 {
    859 }
    860 
    861 const int* RenderThemeChromiumMac::popupButtonMargins() const
    862 {
    863     static const int margins[3][4] =
    864     {
    865         { 0, 3, 1, 3 },
    866         { 0, 3, 2, 3 },
    867         { 0, 1, 0, 1 }
    868     };
    869     return margins[[popupButton() controlSize]];
    870 }
    871 
    872 const IntSize* RenderThemeChromiumMac::popupButtonSizes() const
    873 {
    874     static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
    875     return sizes;
    876 }
    877 
    878 const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const
    879 {
    880     static const int padding[3][4] =
    881     {
    882         { 2, 26, 3, 8 },
    883         { 2, 23, 3, 8 },
    884         { 2, 22, 3, 10 }
    885     };
    886     return padding[size];
    887 }
    888 
    889 bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
    890 {
    891     LocalCurrentGraphicsContext localContext(paintInfo.context);
    892     setPopupButtonCellState(o, r);
    893 
    894     NSPopUpButtonCell* popupButton = this->popupButton();
    895 
    896     float zoomLevel = o->style()->effectiveZoom();
    897     IntSize size = popupButtonSizes()[[popupButton controlSize]];
    898     size.setHeight(size.height() * zoomLevel);
    899     size.setWidth(r.width());
    900 
    901     // Now inflate it to account for the shadow.
    902     IntRect inflatedRect = r;
    903     if (r.width() >= minimumMenuListSize(o->style()))
    904         inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(), zoomLevel);
    905 
    906     GraphicsContextStateSaver stateSaver(*paintInfo.context);
    907 
    908     // On Leopard, the cell will draw outside of the given rect, so we have to clip to the rect
    909     paintInfo.context->clip(inflatedRect);
    910 
    911     if (zoomLevel != 1.0f) {
    912         inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
    913         inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
    914         paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
    915         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
    916         paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
    917     }
    918 
    919     NSView *view = documentViewFor(o);
    920     [popupButton drawWithFrame:inflatedRect inView:view];
    921 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
    922     if (isFocused(o) && o->style()->outlineStyleIsAuto())
    923         [popupButton _web_drawFocusRingWithFrame:inflatedRect inView:view];
    924 #endif
    925     [popupButton setControlView:nil];
    926 
    927     return false;
    928 }
    929 
    930 IntSize RenderThemeChromiumMac::meterSizeForBounds(const RenderMeter* renderMeter, const IntRect& bounds) const
    931 {
    932     if (NoControlPart == renderMeter->style()->appearance())
    933         return bounds.size();
    934 
    935     NSLevelIndicatorCell* cell = levelIndicatorFor(renderMeter);
    936     // Makes enough room for cell's intrinsic size.
    937     NSSize cellSize = [cell cellSizeForBounds:IntRect(IntPoint(), bounds.size())];
    938     return IntSize(bounds.width() < cellSize.width ? cellSize.width : bounds.width(),
    939                    bounds.height() < cellSize.height ? cellSize.height : bounds.height());
    940 }
    941 
    942 bool RenderThemeChromiumMac::paintMeter(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
    943 {
    944     if (!renderObject->isMeter())
    945         return true;
    946 
    947     LocalCurrentGraphicsContext localContext(paintInfo.context);
    948 
    949     NSLevelIndicatorCell* cell = levelIndicatorFor(toRenderMeter(renderObject));
    950     GraphicsContextStateSaver stateSaver(*paintInfo.context);
    951 
    952     [cell drawWithFrame:rect inView:documentViewFor(renderObject)];
    953     [cell setControlView:nil];
    954     return false;
    955 }
    956 
    957 bool RenderThemeChromiumMac::supportsMeter(ControlPart part) const
    958 {
    959     switch (part) {
    960     case RelevancyLevelIndicatorPart:
    961     case DiscreteCapacityLevelIndicatorPart:
    962     case RatingLevelIndicatorPart:
    963     case MeterPart:
    964     case ContinuousCapacityLevelIndicatorPart:
    965         return true;
    966     default:
    967         return false;
    968     }
    969 }
    970 
    971 NSLevelIndicatorStyle RenderThemeChromiumMac::levelIndicatorStyleFor(ControlPart part) const
    972 {
    973     switch (part) {
    974     case RelevancyLevelIndicatorPart:
    975         return NSRelevancyLevelIndicatorStyle;
    976     case DiscreteCapacityLevelIndicatorPart:
    977         return NSDiscreteCapacityLevelIndicatorStyle;
    978     case RatingLevelIndicatorPart:
    979         return NSRatingLevelIndicatorStyle;
    980     case MeterPart:
    981     case ContinuousCapacityLevelIndicatorPart:
    982     default:
    983         return NSContinuousCapacityLevelIndicatorStyle;
    984     }
    985 
    986 }
    987 
    988 NSLevelIndicatorCell* RenderThemeChromiumMac::levelIndicatorFor(const RenderMeter* renderMeter) const
    989 {
    990     RenderStyle* style = renderMeter->style();
    991     ASSERT(style->appearance() != NoControlPart);
    992 
    993     if (!m_levelIndicator)
    994         m_levelIndicator.adoptNS([[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle]);
    995     NSLevelIndicatorCell* cell = m_levelIndicator.get();
    996 
    997     HTMLMeterElement* element = renderMeter->meterElement();
    998     double value = element->value();
    999 
   1000     // Because NSLevelIndicatorCell does not support optimum-in-the-middle type coloring,
   1001     // we explicitly control the color instead giving low and high value to NSLevelIndicatorCell as is.
   1002     switch (element->gaugeRegion()) {
   1003     case HTMLMeterElement::GaugeRegionOptimum:
   1004         // Make meter the green
   1005         [cell setWarningValue:value + 1];
   1006         [cell setCriticalValue:value + 2];
   1007         break;
   1008     case HTMLMeterElement::GaugeRegionSuboptimal:
   1009         // Make the meter yellow
   1010         [cell setWarningValue:value - 1];
   1011         [cell setCriticalValue:value + 1];
   1012         break;
   1013     case HTMLMeterElement::GaugeRegionEvenLessGood:
   1014         // Make the meter red
   1015         [cell setWarningValue:value - 2];
   1016         [cell setCriticalValue:value - 1];
   1017         break;
   1018     }
   1019 
   1020     [cell setLevelIndicatorStyle:levelIndicatorStyleFor(style->appearance())];
   1021     [cell setBaseWritingDirection:style->isLeftToRightDirection() ? NSWritingDirectionLeftToRight : NSWritingDirectionRightToLeft];
   1022     [cell setMinValue:element->min()];
   1023     [cell setMaxValue:element->max()];
   1024     RetainPtr<NSNumber> valueObject = [NSNumber numberWithDouble:value];
   1025     [cell setObjectValue:valueObject.get()];
   1026 
   1027     return cell;
   1028 }
   1029 
   1030 const IntSize* RenderThemeChromiumMac::progressBarSizes() const
   1031 {
   1032     static const IntSize sizes[3] = { IntSize(0, 20), IntSize(0, 12), IntSize(0, 12) };
   1033     return sizes;
   1034 }
   1035 
   1036 const int* RenderThemeChromiumMac::progressBarMargins(NSControlSize controlSize) const
   1037 {
   1038     static const int margins[3][4] =
   1039     {
   1040         { 0, 0, 1, 0 },
   1041         { 0, 0, 1, 0 },
   1042         { 0, 0, 1, 0 },
   1043     };
   1044     return margins[controlSize];
   1045 }
   1046 
   1047 int RenderThemeChromiumMac::minimumProgressBarHeight(RenderStyle* style) const
   1048 {
   1049     return sizeForSystemFont(style, progressBarSizes()).height();
   1050 }
   1051 
   1052 double RenderThemeChromiumMac::animationRepeatIntervalForProgressBar(RenderProgress*) const
   1053 {
   1054     return progressAnimationFrameRate;
   1055 }
   1056 
   1057 double RenderThemeChromiumMac::animationDurationForProgressBar(RenderProgress*) const
   1058 {
   1059     return progressAnimationNumFrames * progressAnimationFrameRate;
   1060 }
   1061 
   1062 void RenderThemeChromiumMac::adjustProgressBarStyle(RenderStyle*, Element*) const
   1063 {
   1064 }
   1065 
   1066 bool RenderThemeChromiumMac::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
   1067 {
   1068     if (!renderObject->isProgress())
   1069         return true;
   1070 
   1071     float zoomLevel = renderObject->style()->effectiveZoom();
   1072     int controlSize = controlSizeForFont(renderObject->style());
   1073     IntSize size = progressBarSizes()[controlSize];
   1074     size.setHeight(size.height() * zoomLevel);
   1075     size.setWidth(rect.width());
   1076 
   1077     // Now inflate it to account for the shadow.
   1078     IntRect inflatedRect = rect;
   1079     if (rect.height() <= minimumProgressBarHeight(renderObject->style()))
   1080         inflatedRect = inflateRect(inflatedRect, size, progressBarMargins(controlSize), zoomLevel);
   1081 
   1082     RenderProgress* renderProgress = toRenderProgress(renderObject);
   1083     HIThemeTrackDrawInfo trackInfo;
   1084     trackInfo.version = 0;
   1085     if (controlSize == NSRegularControlSize)
   1086         trackInfo.kind = renderProgress->position() < 0 ? kThemeLargeIndeterminateBar : kThemeLargeProgressBar;
   1087     else
   1088         trackInfo.kind = renderProgress->position() < 0 ? kThemeMediumIndeterminateBar : kThemeMediumProgressBar;
   1089 
   1090     trackInfo.bounds = IntRect(IntPoint(), inflatedRect.size());
   1091     trackInfo.min = 0;
   1092     trackInfo.max = numeric_limits<SInt32>::max();
   1093     trackInfo.value = lround(renderProgress->position() * nextafter(trackInfo.max, 0));
   1094     trackInfo.trackInfo.progress.phase = lround(renderProgress->animationProgress() * nextafter(progressAnimationNumFrames, 0));
   1095     trackInfo.attributes = kThemeTrackHorizontal;
   1096     trackInfo.enableState = isActive(renderObject) ? kThemeTrackActive : kThemeTrackInactive;
   1097     trackInfo.reserved = 0;
   1098     trackInfo.filler1 = 0;
   1099 
   1100     OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(inflatedRect.size(), 1);
   1101     if (!imageBuffer)
   1102         return true;
   1103 
   1104     ContextContainer cgContextContainer(imageBuffer->context());
   1105     CGContextRef cgContext = cgContextContainer.context();
   1106     HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal);
   1107 
   1108     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1109 
   1110     if (!renderProgress->style()->isLeftToRightDirection()) {
   1111         paintInfo.context->translate(2 * inflatedRect.x() + inflatedRect.width(), 0);
   1112         paintInfo.context->scale(FloatSize(-1, 1));
   1113     }
   1114 
   1115     paintInfo.context->drawImageBuffer(imageBuffer.get(), inflatedRect.location());
   1116     return false;
   1117 }
   1118 
   1119 const float baseFontSize = 11.0f;
   1120 const float baseArrowHeight = 4.0f;
   1121 const float baseArrowWidth = 5.0f;
   1122 const float baseSpaceBetweenArrows = 2.0f;
   1123 const int arrowPaddingLeft = 6;
   1124 const int arrowPaddingRight = 6;
   1125 const int paddingBeforeSeparator = 4;
   1126 const int baseBorderRadius = 5;
   1127 const int styledPopupPaddingLeft = 8;
   1128 const int styledPopupPaddingTop = 1;
   1129 const int styledPopupPaddingBottom = 2;
   1130 
   1131 static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
   1132 {
   1133     static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f };
   1134     static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f };
   1135     float a = inData[0];
   1136     int i = 0;
   1137     for (i = 0; i < 4; i++)
   1138         outData[i] = (1.0f - a) * dark[i] + a * light[i];
   1139 }
   1140 
   1141 static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
   1142 {
   1143     static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
   1144     static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f };
   1145     float a = inData[0];
   1146     int i = 0;
   1147     for (i = 0; i < 4; i++)
   1148         outData[i] = (1.0f - a) * dark[i] + a * light[i];
   1149 }
   1150 
   1151 static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
   1152 {
   1153     static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f };
   1154     static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
   1155     float a = inData[0];
   1156     int i = 0;
   1157     for (i = 0; i < 4; i++)
   1158         outData[i] = (1.0f - a) * dark[i] + a * light[i];
   1159 }
   1160 
   1161 void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1162 {
   1163     if (r.isEmpty())
   1164         return;
   1165 
   1166     ContextContainer cgContextContainer(paintInfo.context);
   1167     CGContextRef context = cgContextContainer.context();
   1168 
   1169     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1170 
   1171     RoundedRect border = o->style()->getRoundedBorderFor(r, o->view());
   1172     int radius = border.radii().topLeft().width();
   1173 
   1174     CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
   1175 
   1176     FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
   1177     struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
   1178     RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
   1179     RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
   1180 
   1181     FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
   1182     struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
   1183     RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
   1184     RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(),  bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
   1185 
   1186     struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
   1187     RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
   1188     RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
   1189 
   1190     RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
   1191 
   1192     RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(),  r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
   1193 
   1194     {
   1195         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1196         CGContextClipToRect(context, r);
   1197         paintInfo.context->clipRoundedRect(border);
   1198         context = cgContextContainer.context();
   1199         CGContextDrawShading(context, mainShading.get());
   1200     }
   1201 
   1202     {
   1203         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1204         CGContextClipToRect(context, topGradient);
   1205         paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(topGradient), border.radii().topLeft(), border.radii().topRight(), IntSize(), IntSize()));
   1206         context = cgContextContainer.context();
   1207         CGContextDrawShading(context, topShading.get());
   1208     }
   1209 
   1210     if (!bottomGradient.isEmpty()) {
   1211         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1212         CGContextClipToRect(context, bottomGradient);
   1213         paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(bottomGradient), IntSize(), IntSize(), border.radii().bottomLeft(), border.radii().bottomRight()));
   1214         context = cgContextContainer.context();
   1215         CGContextDrawShading(context, bottomShading.get());
   1216     }
   1217 
   1218     {
   1219         GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1220         CGContextClipToRect(context, r);
   1221         paintInfo.context->clipRoundedRect(border);
   1222         context = cgContextContainer.context();
   1223         CGContextDrawShading(context, leftShading.get());
   1224         CGContextDrawShading(context, rightShading.get());
   1225     }
   1226 }
   1227 
   1228 bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1229 {
   1230     IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
   1231                              r.y() + o->style()->borderTopWidth(),
   1232                              r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
   1233                              r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
   1234     // Draw the gradients to give the styled popup menu a button appearance
   1235     paintMenuListButtonGradients(o, paintInfo, bounds);
   1236 
   1237     // Since we actually know the size of the control here, we restrict the font scale to make sure the arrows will fit vertically in the bounds
   1238     float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
   1239     float centerY = bounds.y() + bounds.height() / 2.0f;
   1240     float arrowHeight = baseArrowHeight * fontScale;
   1241     float arrowWidth = baseArrowWidth * fontScale;
   1242     float leftEdge = bounds.maxX() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
   1243     float spaceBetweenArrows = baseSpaceBetweenArrows * fontScale;
   1244 
   1245     if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
   1246         return false;
   1247 
   1248     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1249 
   1250     paintInfo.context->setFillColor(o->resolveColor(CSSPropertyColor));
   1251     paintInfo.context->setStrokeStyle(NoStroke);
   1252 
   1253     FloatPoint arrow1[3];
   1254     arrow1[0] = FloatPoint(leftEdge, centerY - spaceBetweenArrows / 2.0f);
   1255     arrow1[1] = FloatPoint(leftEdge + arrowWidth, centerY - spaceBetweenArrows / 2.0f);
   1256     arrow1[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY - spaceBetweenArrows / 2.0f - arrowHeight);
   1257 
   1258     // Draw the top arrow
   1259     paintInfo.context->drawConvexPolygon(3, arrow1, true);
   1260 
   1261     FloatPoint arrow2[3];
   1262     arrow2[0] = FloatPoint(leftEdge, centerY + spaceBetweenArrows / 2.0f);
   1263     arrow2[1] = FloatPoint(leftEdge + arrowWidth, centerY + spaceBetweenArrows / 2.0f);
   1264     arrow2[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + spaceBetweenArrows / 2.0f + arrowHeight);
   1265 
   1266     // Draw the bottom arrow
   1267     paintInfo.context->drawConvexPolygon(3, arrow2, true);
   1268 
   1269     Color leftSeparatorColor(0, 0, 0, 40);
   1270     Color rightSeparatorColor(255, 255, 255, 40);
   1271 
   1272     // FIXME: Should the separator thickness and space be scaled up by fontScale?
   1273     int separatorSpace = 2; // Deliberately ignores zoom since it looks nicer if it stays thin.
   1274     int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft * o->style()->effectiveZoom()); // FIXME: Round?
   1275 
   1276     // Draw the separator to the left of the arrows
   1277     paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
   1278     paintInfo.context->setStrokeStyle(SolidStroke);
   1279     paintInfo.context->setStrokeColor(leftSeparatorColor);
   1280     paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
   1281                                 IntPoint(leftEdgeOfSeparator, bounds.maxY()));
   1282 
   1283     paintInfo.context->setStrokeColor(rightSeparatorColor);
   1284     paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
   1285                                 IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
   1286     return false;
   1287 }
   1288 
   1289 static const IntSize* menuListButtonSizes()
   1290 {
   1291     static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
   1292     return sizes;
   1293 }
   1294 
   1295 void RenderThemeChromiumMac::adjustMenuListStyle(RenderStyle* style, Element* e) const
   1296 {
   1297     NSControlSize controlSize = controlSizeForFont(style);
   1298 
   1299     style->resetBorder();
   1300     style->resetPadding();
   1301 
   1302     // Height is locked to auto.
   1303     style->setHeight(Length(Auto));
   1304 
   1305     // White-space is locked to pre
   1306     style->setWhiteSpace(PRE);
   1307 
   1308     // Set the foreground color to black or gray when we have the aqua look.
   1309     // Cast to RGB32 is to work around a compiler bug.
   1310     style->setColor(e && !e->isDisabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
   1311 
   1312     // Set the button's vertical size.
   1313     setSizeFromFont(style, menuListButtonSizes());
   1314 
   1315     // Our font is locked to the appropriate system font size for the control.  To clarify, we first use the CSS-specified font to figure out
   1316     // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
   1317     // system font for the control size instead.
   1318     setFontFromControlSize(style, controlSize);
   1319 }
   1320 
   1321 const int autofillPopupHorizontalPadding = 4;
   1322 
   1323 // These functions are called with MenuListPart or MenulistButtonPart appearance by RenderMenuList, or with TextFieldPart appearance by AutofillPopupMenuClient.
   1324 // We assume only AutofillPopupMenuClient gives TexfieldPart appearance here.
   1325 // We want to change only Autofill padding.
   1326 // In the future, we have to separate Autofill popup window logic from WebKit to Chromium.
   1327 int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const
   1328 {
   1329     if (style->appearance() == TextFieldPart)
   1330         return autofillPopupHorizontalPadding;
   1331 
   1332     if (style->appearance() == MenulistPart)
   1333         return popupButtonPadding(controlSizeForFont(style))[leftPadding] * style->effectiveZoom();
   1334     if (style->appearance() == MenulistButtonPart)
   1335         return styledPopupPaddingLeft * style->effectiveZoom();
   1336     return 0;
   1337 }
   1338 
   1339 int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const
   1340 {
   1341     if (style->appearance() == TextFieldPart)
   1342         return autofillPopupHorizontalPadding;
   1343 
   1344     if (style->appearance() == MenulistPart)
   1345         return popupButtonPadding(controlSizeForFont(style))[rightPadding] * style->effectiveZoom();
   1346     if (style->appearance() == MenulistButtonPart) {
   1347         float fontScale = style->fontSize() / baseFontSize;
   1348         float arrowWidth = baseArrowWidth * fontScale;
   1349         return static_cast<int>(ceilf(arrowWidth + (arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator) * style->effectiveZoom()));
   1350     }
   1351     return 0;
   1352 }
   1353 
   1354 int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const
   1355 {
   1356     if (style->appearance() == MenulistPart)
   1357         return popupButtonPadding(controlSizeForFont(style))[topPadding] * style->effectiveZoom();
   1358     if (style->appearance() == MenulistButtonPart)
   1359         return styledPopupPaddingTop * style->effectiveZoom();
   1360     return 0;
   1361 }
   1362 
   1363 int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const
   1364 {
   1365     if (style->appearance() == MenulistPart)
   1366         return popupButtonPadding(controlSizeForFont(style))[bottomPadding] * style->effectiveZoom();
   1367     if (style->appearance() == MenulistButtonPart)
   1368         return styledPopupPaddingBottom * style->effectiveZoom();
   1369     return 0;
   1370 }
   1371 
   1372 void RenderThemeChromiumMac::adjustMenuListButtonStyle(RenderStyle* style, Element*) const
   1373 {
   1374     float fontScale = style->fontSize() / baseFontSize;
   1375 
   1376     style->resetPadding();
   1377     style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
   1378 
   1379     const int minHeight = 15;
   1380     style->setMinHeight(Length(minHeight, Fixed));
   1381 
   1382     style->setLineHeight(RenderStyle::initialLineHeight());
   1383 }
   1384 
   1385 void RenderThemeChromiumMac::setPopupButtonCellState(const RenderObject* o, const IntRect& r)
   1386 {
   1387     NSPopUpButtonCell* popupButton = this->popupButton();
   1388 
   1389     // Set the control size based off the rectangle we're painting into.
   1390     setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom());
   1391 
   1392     // Update the various states we respond to.
   1393     updateActiveState(popupButton, o);
   1394     updateCheckedState(popupButton, o);
   1395     updateEnabledState(popupButton, o);
   1396     updatePressedState(popupButton, o);
   1397 #if BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
   1398     updateFocusedState(popupButton, o);
   1399 #endif
   1400 }
   1401 
   1402 const IntSize* RenderThemeChromiumMac::menuListSizes() const
   1403 {
   1404     static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) };
   1405     return sizes;
   1406 }
   1407 
   1408 int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const
   1409 {
   1410     return sizeForSystemFont(style, menuListSizes()).width();
   1411 }
   1412 
   1413 const int sliderTrackWidth = 5;
   1414 const int sliderTrackBorderWidth = 1;
   1415 
   1416 bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1417 {
   1418     paintSliderTicks(o, paintInfo, r);
   1419 
   1420     float zoomLevel = o->style()->effectiveZoom();
   1421     FloatRect unzoomedRect = r;
   1422 
   1423     if (o->style()->appearance() ==  SliderHorizontalPart || o->style()->appearance() ==  MediaSliderPart) {
   1424         unzoomedRect.setY(ceilf(unzoomedRect.y() + unzoomedRect.height() / 2 - zoomLevel * sliderTrackWidth / 2));
   1425         unzoomedRect.setHeight(zoomLevel * sliderTrackWidth);
   1426     } else if (o->style()->appearance() == SliderVerticalPart) {
   1427         unzoomedRect.setX(ceilf(unzoomedRect.x() + unzoomedRect.width() / 2 - zoomLevel * sliderTrackWidth / 2));
   1428         unzoomedRect.setWidth(zoomLevel * sliderTrackWidth);
   1429     }
   1430 
   1431     if (zoomLevel != 1) {
   1432         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
   1433         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
   1434     }
   1435 
   1436     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1437     if (zoomLevel != 1) {
   1438         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
   1439         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
   1440         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
   1441     }
   1442 
   1443     Color fillColor(205, 205, 205);
   1444     Color borderGradientTopColor(109, 109, 109);
   1445     Color borderGradientBottomColor(181, 181, 181);
   1446     Color shadowColor(0, 0, 0, 118);
   1447 
   1448     if (!isEnabled(o)) {
   1449         Color tintColor(255, 255, 255, 128);
   1450         fillColor = fillColor.blend(tintColor);
   1451         borderGradientTopColor = borderGradientTopColor.blend(tintColor);
   1452         borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
   1453         shadowColor = shadowColor.blend(tintColor);
   1454     }
   1455 
   1456     Color tintColor;
   1457     if (!isEnabled(o))
   1458         tintColor = Color(255, 255, 255, 128);
   1459 
   1460     bool isVerticalSlider = o->style()->appearance() == SliderVerticalPart;
   1461 
   1462     int fillRadiusSize = (sliderTrackWidth - sliderTrackBorderWidth) / 2;
   1463     IntSize fillRadius(fillRadiusSize, fillRadiusSize);
   1464     IntRect fillBounds = enclosedIntRect(unzoomedRect);
   1465     RoundedRect fillRect(fillBounds, fillRadius, fillRadius, fillRadius, fillRadius);
   1466     paintInfo.context->fillRoundedRect(fillRect, fillColor);
   1467 
   1468     IntSize shadowOffset(isVerticalSlider ? 1 : 0,
   1469                          isVerticalSlider ? 0 : 1);
   1470     int shadowBlur = 3;
   1471     int shadowSpread = 0;
   1472     paintInfo.context->save();
   1473     paintInfo.context->drawInnerShadow(fillRect, shadowColor, shadowOffset, shadowBlur, shadowSpread);
   1474     paintInfo.context->restore();
   1475 
   1476     RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(),
   1477         isVerticalSlider ? fillBounds.maxXMinYCorner() : fillBounds.minXMaxYCorner());
   1478     borderGradient->addColorStop(0.0, borderGradientTopColor);
   1479     borderGradient->addColorStop(1.0, borderGradientBottomColor);
   1480     Path borderPath;
   1481     FloatRect borderRect(unzoomedRect);
   1482     borderRect.inflate(-sliderTrackBorderWidth / 2.0);
   1483     float borderRadiusSize = (isVerticalSlider ? borderRect.width() : borderRect.height()) / 2;
   1484     FloatSize borderRadius(borderRadiusSize, borderRadiusSize);
   1485     borderPath.addRoundedRect(borderRect, borderRadius, borderRadius, borderRadius, borderRadius);
   1486     paintInfo.context->setStrokeGradient(borderGradient);
   1487     paintInfo.context->setStrokeThickness(sliderTrackBorderWidth);
   1488     paintInfo.context->strokePath(borderPath);
   1489     return false;
   1490 }
   1491 
   1492 const int sliderThumbWidth = 15;
   1493 const int sliderThumbHeight = 15;
   1494 const int sliderThumbBorderWidth = 1;
   1495 
   1496 bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1497 {
   1498     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1499     float zoomLevel = o->style()->effectiveZoom();
   1500 
   1501     FloatRect unzoomedRect(r.x(), r.y(), sliderThumbWidth, sliderThumbHeight);
   1502     if (zoomLevel != 1.0f) {
   1503         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
   1504         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
   1505         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
   1506     }
   1507 
   1508     Color fillGradientTopColor(250, 250, 250);
   1509     Color fillGradientUpperMiddleColor(244, 244, 244);
   1510     Color fillGradientLowerMiddleColor(236, 236, 236);
   1511     Color fillGradientBottomColor(238, 238, 238);
   1512     Color borderGradientTopColor(151, 151, 151);
   1513     Color borderGradientBottomColor(128, 128, 128);
   1514     Color shadowColor(0, 0, 0, 36);
   1515 
   1516     if (!isEnabled(o)) {
   1517         Color tintColor(255, 255, 255, 128);
   1518         fillGradientTopColor = fillGradientTopColor.blend(tintColor);
   1519         fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
   1520         fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
   1521         fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
   1522         borderGradientTopColor = borderGradientTopColor.blend(tintColor);
   1523         borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
   1524         shadowColor = shadowColor.blend(tintColor);
   1525     } else if (isPressed(o)) {
   1526         Color tintColor(0, 0, 0, 32);
   1527         fillGradientTopColor = fillGradientTopColor.blend(tintColor);
   1528         fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
   1529         fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
   1530         fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
   1531         borderGradientTopColor = borderGradientTopColor.blend(tintColor);
   1532         borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
   1533         shadowColor = shadowColor.blend(tintColor);
   1534     }
   1535 
   1536     FloatRect borderBounds = unzoomedRect;
   1537     borderBounds.inflate(sliderThumbBorderWidth / 2.0);
   1538 
   1539     FloatRect shadowBounds = unzoomedRect;
   1540     borderBounds.inflate(-sliderThumbBorderWidth);
   1541     FloatSize shadowOffset(0, 1);
   1542     paintInfo.context->setShadow(shadowOffset, sliderThumbShadowBlur, shadowColor);
   1543     paintInfo.context->setFillColor(Color::black);
   1544     paintInfo.context->fillEllipse(borderBounds);
   1545     paintInfo.context->clearShadow();
   1546 
   1547     IntRect fillBounds = enclosedIntRect(unzoomedRect);
   1548     RefPtr<Gradient> fillGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
   1549     fillGradient->addColorStop(0.0, fillGradientTopColor);
   1550     fillGradient->addColorStop(0.52, fillGradientUpperMiddleColor);
   1551     fillGradient->addColorStop(0.52, fillGradientLowerMiddleColor);
   1552     fillGradient->addColorStop(1.0, fillGradientBottomColor);
   1553     paintInfo.context->setFillGradient(fillGradient);
   1554     paintInfo.context->fillEllipse(borderBounds);
   1555 
   1556     RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
   1557     borderGradient->addColorStop(0.0, borderGradientTopColor);
   1558     borderGradient->addColorStop(1.0, borderGradientBottomColor);
   1559     paintInfo.context->setStrokeGradient(borderGradient);
   1560     paintInfo.context->setStrokeThickness(sliderThumbBorderWidth);
   1561     paintInfo.context->strokeEllipse(borderBounds);
   1562 
   1563     if (isFocused(o)) {
   1564         Path borderPath;
   1565         borderPath.addEllipse(borderBounds);
   1566         paintInfo.context->drawFocusRing(borderPath, 5, -2, focusRingColor());
   1567     }
   1568 
   1569     return false;
   1570 }
   1571 
   1572 bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1573 {
   1574     LocalCurrentGraphicsContext localContext(paintInfo.context);
   1575 
   1576     NSSearchFieldCell* search = this->search();
   1577     setSearchCellState(o, r);
   1578     [search setControlSize:searchFieldControlSizeForFont(o->style())];
   1579 
   1580     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1581 
   1582     float zoomLevel = o->style()->effectiveZoom();
   1583 
   1584     IntRect unzoomedRect = r;
   1585 
   1586     if (zoomLevel != 1.0f) {
   1587         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
   1588         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
   1589         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
   1590         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
   1591         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
   1592     }
   1593 
   1594     // Set the search button to nil before drawing.  Then reset it so we can draw it later.
   1595     [search setSearchButtonCell:nil];
   1596 
   1597     [search drawWithFrame:NSRect(unzoomedRect) inView:documentViewFor(o)];
   1598 
   1599     [search setControlView:nil];
   1600     [search resetSearchButtonCell];
   1601 
   1602     return false;
   1603 }
   1604 
   1605 void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&)
   1606 {
   1607     NSSearchFieldCell* search = this->search();
   1608 
   1609     // Update the various states we respond to.
   1610     updateActiveState(search, o);
   1611     updateEnabledState(search, o);
   1612     updateFocusedState(search, o);
   1613 }
   1614 
   1615 const IntSize* RenderThemeChromiumMac::searchFieldSizes() const
   1616 {
   1617     static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 15) };
   1618     return sizes;
   1619 }
   1620 
   1621 static const int* searchFieldHorizontalPaddings()
   1622 {
   1623     static const int sizes[3] = { 3, 2, 1 };
   1624     return sizes;
   1625 }
   1626 
   1627 void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const
   1628 {
   1629     // If the width and height are both specified, then we have nothing to do.
   1630     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
   1631         return;
   1632 
   1633     // Use the font size to determine the intrinsic width of the control.
   1634     setSizeFromFont(style, searchFieldSizes());
   1635 }
   1636 
   1637 const int searchFieldBorderWidth = 2;
   1638 void RenderThemeChromiumMac::adjustSearchFieldStyle(RenderStyle* style, Element*) const
   1639 {
   1640     // Override border.
   1641     style->resetBorder();
   1642     const short borderWidth = searchFieldBorderWidth * style->effectiveZoom();
   1643     style->setBorderLeftWidth(borderWidth);
   1644     style->setBorderLeftStyle(INSET);
   1645     style->setBorderRightWidth(borderWidth);
   1646     style->setBorderRightStyle(INSET);
   1647     style->setBorderBottomWidth(borderWidth);
   1648     style->setBorderBottomStyle(INSET);
   1649     style->setBorderTopWidth(borderWidth);
   1650     style->setBorderTopStyle(INSET);
   1651 
   1652     // Override height.
   1653     style->setHeight(Length(Auto));
   1654     setSearchFieldSize(style);
   1655 
   1656     NSControlSize controlSize = controlSizeForFont(style);
   1657 
   1658     // Override padding size to match AppKit text positioning.
   1659     const int verticalPadding = 1 * style->effectiveZoom();
   1660     const int horizontalPadding = searchFieldHorizontalPaddings()[controlSize] * style->effectiveZoom();
   1661     style->setPaddingLeft(Length(horizontalPadding, Fixed));
   1662     style->setPaddingRight(Length(horizontalPadding, Fixed));
   1663     style->setPaddingTop(Length(verticalPadding, Fixed));
   1664     style->setPaddingBottom(Length(verticalPadding, Fixed));
   1665 
   1666     setFontFromControlSize(style, controlSize);
   1667 
   1668     style->setBoxShadow(nullptr);
   1669 }
   1670 
   1671 bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1672 {
   1673     Element* input = o->node()->shadowHost();
   1674     if (!input)
   1675         input = toElement(o->node());
   1676 
   1677     if (!input->renderer()->isBox())
   1678         return false;
   1679 
   1680     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1681 
   1682     float zoomLevel = o->style()->effectiveZoom();
   1683     FloatRect unzoomedRect(r);
   1684     if (zoomLevel != 1.0f) {
   1685         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
   1686         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
   1687         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
   1688         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
   1689         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
   1690     }
   1691 
   1692     Color fillColor(200, 200, 200);
   1693 
   1694     if (isPressed(o)) {
   1695         Color tintColor(0, 0, 0, 32);
   1696         fillColor = fillColor.blend(tintColor);
   1697     }
   1698 
   1699     float centerX = unzoomedRect.x() + unzoomedRect.width() / 2;
   1700     float centerY = unzoomedRect.y() + unzoomedRect.height() / 2;
   1701     // The line width is 3px on a regular sized, high DPI NSCancelButtonCell
   1702     // (which is 28px wide).
   1703     float lineWidth = unzoomedRect.width() * 3 / 28;
   1704     // The line length is 16px on a regular sized, high DPI NSCancelButtonCell.
   1705     float lineLength = unzoomedRect.width() * 16 / 28;
   1706 
   1707     Path xPath;
   1708     FloatSize lineRectRadius(lineWidth / 2, lineWidth / 2);
   1709     xPath.addRoundedRect(FloatRect(-lineLength / 2, -lineWidth / 2, lineLength, lineWidth),
   1710         lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
   1711     xPath.addRoundedRect(FloatRect(-lineWidth / 2, -lineLength / 2, lineWidth, lineLength),
   1712         lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
   1713 
   1714     paintInfo.context->translate(centerX, centerY);
   1715     paintInfo.context->rotate(deg2rad(45.0));
   1716     paintInfo.context->clipOut(xPath);
   1717     paintInfo.context->rotate(deg2rad(-45.0));
   1718     paintInfo.context->translate(-centerX, -centerY);
   1719 
   1720     paintInfo.context->setFillColor(fillColor);
   1721     paintInfo.context->fillEllipse(unzoomedRect);
   1722 
   1723     return false;
   1724 }
   1725 
   1726 const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const
   1727 {
   1728     static const IntSize sizes[3] = { IntSize(14, 14), IntSize(11, 11), IntSize(9, 9) };
   1729     return sizes;
   1730 }
   1731 
   1732 void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(RenderStyle* style, Element*) const
   1733 {
   1734     IntSize size = sizeForSystemFont(style, cancelButtonSizes());
   1735     style->setWidth(Length(size.width(), Fixed));
   1736     style->setHeight(Length(size.height(), Fixed));
   1737     style->setBoxShadow(nullptr);
   1738 }
   1739 
   1740 const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const
   1741 {
   1742     static const IntSize sizes[3] = { IntSize(15, 14), IntSize(16, 13), IntSize(14, 11) };
   1743     return sizes;
   1744 }
   1745 
   1746 void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(RenderStyle* style, Element*) const
   1747 {
   1748     NSControlSize controlSize = controlSizeForSystemFont(style);
   1749     IntSize searchFieldSize = searchFieldSizes()[controlSize];
   1750     int width = searchFieldSize.height() / 2 - searchFieldBorderWidth - searchFieldHorizontalPaddings()[controlSize];
   1751     style->setWidth(Length(width, Fixed));
   1752     style->setHeight(Length(0, Fixed));
   1753     style->setBoxShadow(nullptr);
   1754 }
   1755 
   1756 bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&)
   1757 {
   1758     return false;
   1759 }
   1760 
   1761 void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(RenderStyle* style, Element*) const
   1762 {
   1763     IntSize size = sizeForSystemFont(style, resultsButtonSizes());
   1764     style->setWidth(Length(size.width(), Fixed));
   1765     style->setHeight(Length(size.height(), Fixed));
   1766     style->setBoxShadow(nullptr);
   1767 }
   1768 
   1769 bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
   1770 {
   1771     Node* input = o->node()->shadowHost();
   1772     if (!input)
   1773         input = o->node();
   1774     if (!input->renderer()->isBox())
   1775         return false;
   1776 
   1777     GraphicsContextStateSaver stateSaver(*paintInfo.context);
   1778 
   1779     float zoomLevel = o->style()->effectiveZoom();
   1780     FloatRect unzoomedRect(r);
   1781     if (zoomLevel != 1) {
   1782         unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
   1783         unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
   1784         paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
   1785         paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
   1786         paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
   1787     }
   1788 
   1789     LocalCurrentGraphicsContext localContext(paintInfo.context);
   1790 
   1791     NSSearchFieldCell* search = this->search();
   1792     setSearchCellState(input->renderer(), r);
   1793     [search setControlSize:searchFieldControlSizeForFont(o->style())];
   1794     if ([search searchMenuTemplate] != nil)
   1795         [search setSearchMenuTemplate:nil];
   1796 
   1797     updateActiveState([search searchButtonCell], o);
   1798 
   1799     [[search searchButtonCell] drawWithFrame:unzoomedRect inView:documentViewFor(o)];
   1800     [[search searchButtonCell] setControlView:nil];
   1801     return false;
   1802 }
   1803 
   1804 IntSize RenderThemeChromiumMac::sliderTickSize() const
   1805 {
   1806     return IntSize(1, 3);
   1807 }
   1808 
   1809 int RenderThemeChromiumMac::sliderTickOffsetFromTrackCenter() const
   1810 {
   1811     return -9;
   1812 }
   1813 
   1814 void RenderThemeChromiumMac::adjustSliderThumbSize(RenderStyle* style, Element*) const
   1815 {
   1816     float zoomLevel = style->effectiveZoom();
   1817     if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
   1818         style->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
   1819         style->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
   1820     }
   1821 
   1822     adjustMediaSliderThumbSize(style);
   1823 }
   1824 
   1825 NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const
   1826 {
   1827     if (!m_popupButton) {
   1828         m_popupButton.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]);
   1829         [m_popupButton.get() setUsesItemFromMenu:NO];
   1830         [m_popupButton.get() setFocusRingType:NSFocusRingTypeExterior];
   1831     }
   1832 
   1833     return m_popupButton.get();
   1834 }
   1835 
   1836 NSSearchFieldCell* RenderThemeChromiumMac::search() const
   1837 {
   1838     if (!m_search) {
   1839         m_search.adoptNS([[NSSearchFieldCell alloc] initTextCell:@""]);
   1840         [m_search.get() setBezelStyle:NSTextFieldRoundedBezel];
   1841         [m_search.get() setBezeled:YES];
   1842         [m_search.get() setEditable:YES];
   1843         [m_search.get() setFocusRingType:NSFocusRingTypeExterior];
   1844     }
   1845 
   1846     return m_search.get();
   1847 }
   1848 
   1849 NSMenu* RenderThemeChromiumMac::searchMenuTemplate() const
   1850 {
   1851     if (!m_searchMenuTemplate)
   1852         m_searchMenuTemplate.adoptNS([[NSMenu alloc] initWithTitle:@""]);
   1853 
   1854     return m_searchMenuTemplate.get();
   1855 }
   1856 
   1857 NSTextFieldCell* RenderThemeChromiumMac::textField() const
   1858 {
   1859     if (!m_textField) {
   1860         m_textField.adoptNS([[WebCoreTextFieldCell alloc] initTextCell:@""]);
   1861         [m_textField.get() setBezeled:YES];
   1862         [m_textField.get() setEditable:YES];
   1863         [m_textField.get() setFocusRingType:NSFocusRingTypeExterior];
   1864 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
   1865         [m_textField.get() setDrawsBackground:YES];
   1866         [m_textField.get() setBackgroundColor:[NSColor whiteColor]];
   1867 #else
   1868         // Post-Lion, WebCore can be in charge of paintinng the background thanks to
   1869         // the workaround in place for <rdar://problem/11385461>, which is implemented
   1870         // above as _coreUIDrawOptionsWithFrame.
   1871         [m_textField.get() setDrawsBackground:NO];
   1872 #endif
   1873     }
   1874 
   1875     return m_textField.get();
   1876 }
   1877 
   1878 String RenderThemeChromiumMac::fileListNameForWidth(const FileList* fileList, const Font& font, int width, bool multipleFilesAllowed) const
   1879 {
   1880     if (width <= 0)
   1881         return String();
   1882 
   1883     String strToTruncate;
   1884     if (fileList->isEmpty())
   1885         strToTruncate = fileListDefaultLabel(multipleFilesAllowed);
   1886     else if (fileList->length() == 1)
   1887         strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(fileList->item(0)->path())];
   1888     else
   1889         return StringTruncator::rightTruncate(multipleFileUploadText(fileList->length()), width, font, StringTruncator::EnableRoundingHacks);
   1890 
   1891     return StringTruncator::centerTruncate(strToTruncate, width, font, StringTruncator::EnableRoundingHacks);
   1892 }
   1893 
   1894 NSView* FlippedView()
   1895 {
   1896     static NSView* view = [[RTCMFlippedView alloc] init];
   1897     return view;
   1898 }
   1899 
   1900 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page*)
   1901 {
   1902     static RenderTheme* rt = RenderThemeChromiumMac::create().leakRef();
   1903     return rt;
   1904 }
   1905 
   1906 PassRefPtr<RenderTheme> RenderThemeChromiumMac::create()
   1907 {
   1908     return adoptRef(new RenderThemeChromiumMac);
   1909 }
   1910 
   1911 bool RenderThemeChromiumMac::usesTestModeFocusRingColor() const
   1912 {
   1913     return isRunningLayoutTest();
   1914 }
   1915 
   1916 NSView* RenderThemeChromiumMac::documentViewFor(RenderObject*) const
   1917 {
   1918     return FlippedView();
   1919 }
   1920 
   1921 // Updates the control tint (a.k.a. active state) of |cell| (from |o|).
   1922 // In the Chromium port, the renderer runs as a background process and controls'
   1923 // NSCell(s) lack a parent NSView. Therefore controls don't have their tint
   1924 // color updated correctly when the application is activated/deactivated.
   1925 // FocusController's setActive() is called when the application is
   1926 // activated/deactivated, which causes a repaint at which time this code is
   1927 // called.
   1928 // This function should be called before drawing any NSCell-derived controls,
   1929 // unless you're sure it isn't needed.
   1930 void RenderThemeChromiumMac::updateActiveState(NSCell* cell, const RenderObject* o)
   1931 {
   1932     NSControlTint oldTint = [cell controlTint];
   1933     NSControlTint tint = isActive(o) ? [NSColor currentControlTint] :
   1934                                        static_cast<NSControlTint>(NSClearControlTint);
   1935 
   1936     if (tint != oldTint)
   1937         [cell setControlTint:tint];
   1938 }
   1939 
   1940 bool RenderThemeChromiumMac::shouldShowPlaceholderWhenFocused() const
   1941 {
   1942     return true;
   1943 }
   1944 
   1945 void RenderThemeChromiumMac::adjustMediaSliderThumbSize(RenderStyle* style) const
   1946 {
   1947     RenderMediaControlsChromium::adjustMediaSliderThumbSize(style);
   1948 }
   1949 
   1950 bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1951 {
   1952     return RenderMediaControlsChromium::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);
   1953 }
   1954 
   1955 bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1956 {
   1957     return RenderMediaControlsChromium::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect);
   1958 }
   1959 
   1960 bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1961 {
   1962     return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect);
   1963 }
   1964 
   1965 String RenderThemeChromiumMac::extraFullScreenStyleSheet()
   1966 {
   1967     // FIXME: Chromium may wish to style its default media controls differently in fullscreen.
   1968     return String();
   1969 }
   1970 
   1971 String RenderThemeChromiumMac::extraDefaultStyleSheet()
   1972 {
   1973     return RenderTheme::extraDefaultStyleSheet() +
   1974            String(themeChromiumUserAgentStyleSheet, sizeof(themeChromiumUserAgentStyleSheet));
   1975 }
   1976 
   1977 bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1978 {
   1979     return true;
   1980 }
   1981 
   1982 bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1983 {
   1984     return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
   1985 }
   1986 
   1987 bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1988 {
   1989     return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
   1990 }
   1991 
   1992 bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   1993 {
   1994     return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
   1995 }
   1996 
   1997 String RenderThemeChromiumMac::formatMediaControlsTime(float time) const
   1998 {
   1999     return RenderMediaControlsChromium::formatMediaControlsTime(time);
   2000 }
   2001 
   2002 String RenderThemeChromiumMac::formatMediaControlsCurrentTime(float currentTime, float duration) const
   2003 {
   2004     return RenderMediaControlsChromium::formatMediaControlsCurrentTime(currentTime, duration);
   2005 }
   2006 
   2007 bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   2008 {
   2009     return RenderMediaControlsChromium::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect);
   2010 }
   2011 
   2012 bool RenderThemeChromiumMac::paintMediaToggleClosedCaptionsButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
   2013 {
   2014     return RenderMediaControlsChromium::paintMediaControlsPart(MediaShowClosedCaptionsButton, object, paintInfo, rect);
   2015 }
   2016 
   2017 bool RenderThemeChromiumMac::shouldUseFallbackTheme(RenderStyle* style) const
   2018 {
   2019     ControlPart part = style->appearance();
   2020     if (part == CheckboxPart || part == RadioPart)
   2021         return style->effectiveZoom() != 1;
   2022     return false;
   2023 }
   2024 
   2025 } // namespace WebCore
   2026