2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2009 Google, Inc.
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.
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.
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.
22 #import "core/rendering/RenderThemeChromiumMac.h"
24 #import "core/CSSValueKeywords.h"
25 #import "core/HTMLNames.h"
26 #import "core/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/frame/FrameView.h"
32 #import "core/html/HTMLInputElement.h"
33 #import "core/html/HTMLMediaElement.h"
34 #import "core/html/HTMLMeterElement.h"
35 #import "core/html/TimeRanges.h"
36 #import "core/html/shadow/MediaControlElements.h"
37 #import "core/rendering/PaintInfo.h"
38 #import "core/rendering/RenderLayer.h"
39 #import "core/rendering/RenderMedia.h"
40 #import "core/rendering/RenderMediaControls.h"
41 #import "core/rendering/RenderMeter.h"
42 #import "core/rendering/RenderProgress.h"
43 #import "core/rendering/RenderSlider.h"
44 #import "core/rendering/RenderView.h"
45 #import "core/rendering/style/ShadowList.h"
46 #import "platform/LayoutTestSupport.h"
47 #import "platform/SharedBuffer.h"
48 #import "platform/graphics/BitmapImage.h"
49 #import "platform/graphics/GraphicsContextStateSaver.h"
50 #import "platform/graphics/Image.h"
51 #import "platform/graphics/ImageBuffer.h"
52 #import "platform/mac/ColorMac.h"
53 #import "platform/mac/LocalCurrentGraphicsContext.h"
54 #import "platform/mac/ThemeMac.h"
55 #import "platform/mac/WebCoreNSCellExtras.h"
56 #import "platform/text/PlatformLocale.h"
57 #import "platform/text/StringTruncator.h"
58 #import <AvailabilityMacros.h>
59 #import <Carbon/Carbon.h>
60 #import <Cocoa/Cocoa.h>
62 #import <wtf/RetainPtr.h>
63 #import <wtf/StdLibExtras.h>
65 // The methods in this file are specific to the Mac OS X platform.
67 // We estimate the animation rate of a Mac OS X progress bar is 33 fps.
68 // Hard code the value here because we haven't found API for it.
69 const double progressAnimationFrameRate = 0.033;
71 // Mac OS X progress bar animation seems to have 256 frames.
72 const double progressAnimationNumFrames = 256;
74 @interface WebCoreRenderThemeNotificationObserver : NSObject
76 blink::RenderTheme *_theme;
79 - (id)initWithTheme:(blink::RenderTheme *)theme;
80 - (void)systemColorsDidChange:(NSNotification *)notification;
84 @implementation WebCoreRenderThemeNotificationObserver
86 - (id)initWithTheme:(blink::RenderTheme *)theme
88 if (!(self = [super init]))
95 - (void)systemColorsDidChange:(NSNotification *)unusedNotification
97 ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]);
98 _theme->platformColorsDidChange();
103 @interface NSTextFieldCell (WKDetails)
104 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
108 @interface WebCoreTextFieldCell : NSTextFieldCell
109 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
112 @implementation WebCoreTextFieldCell
113 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus
115 // FIXME: This is a post-Lion-only workaround for <rdar://problem/11385461>. When that bug is resolved, we should remove this code.
116 CFMutableDictionaryRef coreUIDrawOptions = CFDictionaryCreateMutableCopy(NULL, 0, [super _coreUIDrawOptionsWithFrame:cellFrame inView:controlView includeFocus:includeFocus]);
117 CFDictionarySetValue(coreUIDrawOptions, @"borders only", kCFBooleanTrue);
118 return (CFDictionaryRef)[NSMakeCollectable(coreUIDrawOptions) autorelease];
122 @interface RTCMFlippedView : NSView
126 - (NSText *)currentEditor;
130 @implementation RTCMFlippedView
133 return [[NSGraphicsContext currentContext] isFlipped];
136 - (NSText *)currentEditor {
142 // Forward declare Mac SPIs.
144 void _NSDrawCarbonThemeBezel(NSRect frame, BOOL enabled, BOOL flipped);
145 // Request for public API: rdar://13787640
146 void _NSDrawCarbonThemeListBox(NSRect frame, BOOL enabled, BOOL flipped, BOOL always_yes);
151 using namespace HTMLNames;
153 RenderThemeChromiumMac::RenderThemeChromiumMac()
154 : m_notificationObserver(AdoptNS, [[WebCoreRenderThemeNotificationObserver alloc] initWithTheme:this])
156 [[NSNotificationCenter defaultCenter] addObserver:m_notificationObserver.get()
157 selector:@selector(systemColorsDidChange:)
158 name:NSSystemColorsDidChangeNotification
162 RenderThemeChromiumMac::~RenderThemeChromiumMac()
164 [[NSNotificationCenter defaultCenter] removeObserver:m_notificationObserver.get()];
167 Color RenderThemeChromiumMac::platformActiveSelectionBackgroundColor() const
169 NSColor* color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
170 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
173 Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const
175 NSColor* color = [[NSColor secondarySelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
176 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
179 Color RenderThemeChromiumMac::platformActiveSelectionForegroundColor() const
184 Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const
186 NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
187 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
190 Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const
195 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const
200 Color RenderThemeChromiumMac::platformFocusRingColor() const
202 static const RGBA32 oldAquaFocusRingColor = 0xFF7DADD9;
203 if (usesTestModeFocusRingColor())
204 return oldAquaFocusRingColor;
206 return systemColor(CSSValueWebkitFocusRingColor);
209 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const
211 return platformInactiveSelectionBackgroundColor();
214 static FontWeight toFontWeight(NSInteger appKitFontWeight)
216 ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15);
217 if (appKitFontWeight > 14)
218 appKitFontWeight = 14;
219 else if (appKitFontWeight < 1)
220 appKitFontWeight = 1;
222 static FontWeight fontWeights[] = {
238 return fontWeights[appKitFontWeight - 1];
241 static inline NSFont* systemNSFont(CSSValueID systemFontID)
243 switch (systemFontID) {
244 case CSSValueSmallCaption:
245 return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
247 return [NSFont menuFontOfSize:[NSFont systemFontSize]];
248 case CSSValueStatusBar:
249 return [NSFont labelFontOfSize:[NSFont labelFontSize]];
250 case CSSValueWebkitMiniControl:
251 return [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
252 case CSSValueWebkitSmallControl:
253 return [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]];
254 case CSSValueWebkitControl:
255 return [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
257 return [NSFont systemFontOfSize:[NSFont systemFontSize]];
261 void RenderThemeChromiumMac::systemFont(CSSValueID systemFontID, FontStyle& fontStyle, FontWeight& fontWeight, float& fontSize, AtomicString& fontFamily) const
263 NSFont* font = systemNSFont(systemFontID);
267 NSFontManager *fontManager = [NSFontManager sharedFontManager];
268 fontStyle = ([fontManager traitsOfFont:font] & NSItalicFontMask) ? FontStyleItalic : FontStyleNormal;
269 fontWeight = toFontWeight([fontManager weightOfFont:font]);
270 fontSize = [font pointSize];
271 fontFamily = [font webCoreFamilyName];
274 static RGBA32 convertNSColorToColor(NSColor *color)
276 NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
277 if (colorInColorSpace) {
278 static const double scaleFactor = nextafter(256.0, 0.0);
279 return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]),
280 static_cast<int>(scaleFactor * [colorInColorSpace greenComponent]),
281 static_cast<int>(scaleFactor * [colorInColorSpace blueComponent]));
284 // This conversion above can fail if the NSColor in question is an NSPatternColor
285 // (as many system colors are). These colors are actually a repeating pattern
286 // not just a solid color. To work around this we simply draw a 1x1 image of
287 // the color and use that pixel's color. It might be better to use an average of
288 // the colors in the pattern instead.
289 NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
296 colorSpaceName:NSDeviceRGBColorSpace
300 [NSGraphicsContext saveGraphicsState];
301 [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]];
302 NSEraseRect(NSMakeRect(0, 0, 1, 1));
303 [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
304 [NSGraphicsContext restoreGraphicsState];
307 [offscreenRep getPixel:pixel atX:0 y:0];
309 [offscreenRep release];
311 return makeRGB(pixel[0], pixel[1], pixel[2]);
314 static RGBA32 menuBackgroundColor()
316 NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
323 colorSpaceName:NSDeviceRGBColorSpace
327 CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep] graphicsPort]);
328 CGRect rect = CGRectMake(0, 0, 1, 1);
329 HIThemeMenuDrawInfo drawInfo;
330 drawInfo.version = 0;
331 drawInfo.menuType = kThemeMenuTypePopUp;
332 HIThemeDrawMenuBackground(&rect, &drawInfo, context, kHIThemeOrientationInverted);
335 [offscreenRep getPixel:pixel atX:0 y:0];
337 [offscreenRep release];
339 return makeRGB(pixel[0], pixel[1], pixel[2]);
342 void RenderThemeChromiumMac::platformColorsDidChange()
344 m_systemColorCache.clear();
345 RenderTheme::platformColorsDidChange();
348 Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
351 HashMap<int, RGBA32>::iterator it = m_systemColorCache.find(cssValueId);
352 if (it != m_systemColorCache.end())
357 bool needsFallback = false;
358 switch (cssValueId) {
359 case CSSValueActiveborder:
360 color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
362 case CSSValueActivecaption:
363 color = convertNSColorToColor([NSColor windowFrameTextColor]);
365 case CSSValueAppworkspace:
366 color = convertNSColorToColor([NSColor headerColor]);
368 case CSSValueBackground:
369 // Use theme independent default
370 needsFallback = true;
372 case CSSValueButtonface:
373 // We use this value instead of NSColor's controlColor to avoid website
374 // incompatibilities. We may want to change this to use the NSColor in
378 case CSSValueButtonhighlight:
379 color = convertNSColorToColor([NSColor controlHighlightColor]);
381 case CSSValueButtonshadow:
382 color = convertNSColorToColor([NSColor controlShadowColor]);
384 case CSSValueButtontext:
385 color = convertNSColorToColor([NSColor controlTextColor]);
387 case CSSValueCaptiontext:
388 color = convertNSColorToColor([NSColor textColor]);
390 case CSSValueGraytext:
391 color = convertNSColorToColor([NSColor disabledControlTextColor]);
393 case CSSValueHighlight:
394 color = convertNSColorToColor([NSColor selectedTextBackgroundColor]);
396 case CSSValueHighlighttext:
397 color = convertNSColorToColor([NSColor selectedTextColor]);
399 case CSSValueInactiveborder:
400 color = convertNSColorToColor([NSColor controlBackgroundColor]);
402 case CSSValueInactivecaption:
403 color = convertNSColorToColor([NSColor controlBackgroundColor]);
405 case CSSValueInactivecaptiontext:
406 color = convertNSColorToColor([NSColor textColor]);
408 case CSSValueInfobackground:
409 // There is no corresponding NSColor for this so we use a hard coded
413 case CSSValueInfotext:
414 color = convertNSColorToColor([NSColor textColor]);
417 color = menuBackgroundColor();
419 case CSSValueMenutext:
420 color = convertNSColorToColor([NSColor selectedMenuItemTextColor]);
422 case CSSValueScrollbar:
423 color = convertNSColorToColor([NSColor scrollBarColor]);
426 color = convertNSColorToColor([NSColor textColor]);
428 case CSSValueThreeddarkshadow:
429 color = convertNSColorToColor([NSColor controlDarkShadowColor]);
431 case CSSValueThreedshadow:
432 color = convertNSColorToColor([NSColor shadowColor]);
434 case CSSValueThreedface:
435 // We use this value instead of NSColor's controlColor to avoid website
436 // incompatibilities. We may want to change this to use the NSColor in
440 case CSSValueThreedhighlight:
441 color = convertNSColorToColor([NSColor highlightColor]);
443 case CSSValueThreedlightshadow:
444 color = convertNSColorToColor([NSColor controlLightHighlightColor]);
446 case CSSValueWebkitFocusRingColor:
447 color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
450 color = convertNSColorToColor([NSColor windowBackgroundColor]);
452 case CSSValueWindowframe:
453 color = convertNSColorToColor([NSColor windowFrameColor]);
455 case CSSValueWindowtext:
456 color = convertNSColorToColor([NSColor windowFrameTextColor]);
459 needsFallback = true;
464 color = RenderTheme::systemColor(cssValueId);
466 m_systemColorCache.set(cssValueId, color.rgb());
471 bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const CachedUAStyle* uaStyle) const
474 if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart)
475 return style->border() != uaStyle->border || style->boxShadow();
477 // FIXME: This is horrible, but there is not much else that can be done.
478 // Menu lists cannot draw properly when scaled. They can't really draw
479 // properly when transformed either. We can't detect the transform case at
480 // style adjustment time so that will just have to stay broken. We can
481 // however detect that we're zooming. If zooming is in effect we treat it
482 // like the control is styled.
483 if (style->appearance() == MenulistPart && style->effectiveZoom() != 1.0f)
485 // FIXME: NSSearchFieldCell doesn't work well when scaled.
486 if (style->appearance() == SearchFieldPart && style->effectiveZoom() != 1)
489 return RenderTheme::isControlStyled(style, uaStyle);
492 const int sliderThumbShadowBlur = 1;
494 void RenderThemeChromiumMac::adjustPaintInvalidationRect(const RenderObject* o, IntRect& r)
496 ControlPart part = o->style()->appearance();
503 case SquareButtonPart:
505 case InnerSpinButtonPart:
506 return RenderTheme::adjustPaintInvalidationRect(o, r);
512 float zoomLevel = o->style()->effectiveZoom();
514 if (part == MenulistPart) {
515 setPopupButtonCellState(o, r);
516 IntSize size = popupButtonSizes()[[popupButton() controlSize]];
517 size.setHeight(size.height() * zoomLevel);
518 size.setWidth(r.width());
519 r = ThemeMac::inflateRect(r, size, popupButtonMargins(), zoomLevel);
520 } else if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
521 r.setHeight(r.height() + sliderThumbShadowBlur);
525 FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const
527 FloatRect partRect(inputRect);
529 // Compute an offset between the part renderer and the input renderer.
530 FloatSize offsetFromInputRenderer;
531 const RenderObject* renderer = partRenderer;
532 while (renderer && renderer != inputRenderer) {
533 RenderObject* containingRenderer = renderer->container();
534 offsetFromInputRenderer -= roundedIntSize(renderer->offsetFromContainer(containingRenderer, LayoutPoint()));
535 renderer = containingRenderer;
537 // If the input renderer was not a container, something went wrong.
538 ASSERT(renderer == inputRenderer);
539 // Move the rect into partRenderer's coords.
540 partRect.move(offsetFromInputRenderer);
541 // Account for the local drawing offset (tx, ty).
542 partRect.move(r.x(), r.y());
547 void RenderThemeChromiumMac::updateCheckedState(NSCell* cell, const RenderObject* o)
549 bool oldIndeterminate = [cell state] == NSMixedState;
550 bool indeterminate = isIndeterminate(o);
551 bool checked = isChecked(o);
553 if (oldIndeterminate != indeterminate) {
554 [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
558 bool oldChecked = [cell state] == NSOnState;
559 if (checked != oldChecked)
560 [cell setState:checked ? NSOnState : NSOffState];
563 void RenderThemeChromiumMac::updateEnabledState(NSCell* cell, const RenderObject* o)
565 bool oldEnabled = [cell isEnabled];
566 bool enabled = isEnabled(o);
567 if (enabled != oldEnabled)
568 [cell setEnabled:enabled];
571 void RenderThemeChromiumMac::updateFocusedState(NSCell* cell, const RenderObject* o)
573 bool oldFocused = [cell showsFirstResponder];
574 bool focused = isFocused(o) && o->style()->outlineStyleIsAuto();
575 if (focused != oldFocused)
576 [cell setShowsFirstResponder:focused];
579 void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject* o)
581 bool oldPressed = [cell isHighlighted];
582 bool pressed = o->node() && o->node()->active();
583 if (pressed != oldPressed)
584 [cell setHighlighted:pressed];
587 NSControlSize RenderThemeChromiumMac::controlSizeForFont(RenderStyle* style) const
589 int fontSize = style->fontSize();
591 return NSRegularControlSize;
593 return NSSmallControlSize;
594 return NSMiniControlSize;
597 // We don't use controlSizeForFont() for search field decorations because it
598 // needs to fit into the search field. The font size will already be modified by
599 // setFontFromControlSize() called on the search field.
600 static NSControlSize searchFieldControlSizeForFont(RenderStyle* style)
602 int fontSize = style->fontSize();
604 return NSRegularControlSize;
606 return NSSmallControlSize;
607 return NSMiniControlSize;
610 void RenderThemeChromiumMac::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize, float zoomLevel)
613 if (minSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomLevel) &&
614 minSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomLevel))
615 size = NSRegularControlSize;
616 else if (minSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomLevel) &&
617 minSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomLevel))
618 size = NSSmallControlSize;
620 size = NSMiniControlSize;
621 // Only update if we have to, since AppKit does work even if the size is the
623 if (size != [cell controlSize])
624 [cell setControlSize:size];
627 IntSize RenderThemeChromiumMac::sizeForFont(RenderStyle* style, const IntSize* sizes) const
629 if (style->effectiveZoom() != 1.0f) {
630 IntSize result = sizes[controlSizeForFont(style)];
631 return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
633 return sizes[controlSizeForFont(style)];
636 IntSize RenderThemeChromiumMac::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const
638 if (style->effectiveZoom() != 1.0f) {
639 IntSize result = sizes[controlSizeForSystemFont(style)];
640 return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
642 return sizes[controlSizeForSystemFont(style)];
645 void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const
647 // FIXME: Check is flawed, since it doesn't take min-width/max-width into
649 IntSize size = sizeForFont(style, sizes);
650 if (style->width().isIntrinsicOrAuto() && size.width() > 0)
651 style->setWidth(Length(size.width(), Fixed));
652 if (style->height().isAuto() && size.height() > 0)
653 style->setHeight(Length(size.height(), Fixed));
656 void RenderThemeChromiumMac::setFontFromControlSize(RenderStyle* style, NSControlSize controlSize) const
658 FontDescription fontDescription;
659 fontDescription.setIsAbsoluteSize(true);
660 fontDescription.setGenericFamily(FontDescription::SerifFamily);
662 NSFont* font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSize]];
663 fontDescription.firstFamily().setFamily([font webCoreFamilyName]);
664 fontDescription.setComputedSize([font pointSize] * style->effectiveZoom());
665 fontDescription.setSpecifiedSize([font pointSize] * style->effectiveZoom());
667 // Reset line height.
668 style->setLineHeight(RenderStyle::initialLineHeight());
670 if (style->setFontDescription(fontDescription))
671 style->font().update(nullptr);
674 NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
676 float fontSize = style->fontSize();
677 float zoomLevel = style->effectiveZoom();
679 fontSize /= zoomLevel;
680 if (fontSize >= [NSFont systemFontSizeForControlSize:NSRegularControlSize])
681 return NSRegularControlSize;
682 if (fontSize >= [NSFont systemFontSizeForControlSize:NSSmallControlSize])
683 return NSSmallControlSize;
684 return NSMiniControlSize;
687 bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
689 LocalCurrentGraphicsContext localContext(paintInfo.context, r);
691 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
692 bool useNSTextFieldCell = o->style()->hasAppearance()
693 && o->style()->visitedDependentColor(CSSPropertyBackgroundColor) == Color::white
694 && !o->style()->hasBackgroundImage();
696 // We do not use NSTextFieldCell to draw styled text fields on Lion and
697 // SnowLeopard because there are a number of bugs on those platforms that
698 // require NSTextFieldCell to be in charge of painting its own
699 // background. We need WebCore to paint styled backgrounds, so we'll use
700 // this AppKit SPI function instead.
701 if (!useNSTextFieldCell) {
702 _NSDrawCarbonThemeBezel(r, isEnabled(o) && !isReadOnlyControl(o), YES);
707 NSTextFieldCell *textField = this->textField();
709 GraphicsContextStateSaver stateSaver(*paintInfo.context);
711 [textField setEnabled:(isEnabled(o) && !isReadOnlyControl(o))];
712 [textField drawWithFrame:NSRect(r) inView:documentViewFor(o)];
714 [textField setControlView:nil];
719 bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const PaintInfo& paintInfo, const IntRect& r)
721 // This draws the caps lock indicator as it was done by
722 // WKDrawCapsLockIndicator.
723 LocalCurrentGraphicsContext localContext(paintInfo.context, r);
724 CGContextRef c = localContext.cgContext();
725 CGMutablePathRef shape = CGPathCreateMutable();
727 // To draw the caps lock indicator, draw the shape into a small
728 // square that is then scaled to the size of r.
729 const CGFloat kSquareSize = 17;
731 // Create a rounted square shape.
732 CGPathMoveToPoint(shape, NULL, 16.5, 4.5);
733 CGPathAddArc(shape, NULL, 12.5, 12.5, 4, 0, M_PI_2, false);
734 CGPathAddArc(shape, NULL, 4.5, 12.5, 4, M_PI_2, M_PI, false);
735 CGPathAddArc(shape, NULL, 4.5, 4.5, 4, M_PI, 3*M_PI/2, false);
736 CGPathAddArc(shape, NULL, 12.5, 4.5, 4, 3*M_PI/2, 0, false);
738 // Draw the arrow - note this is drawing in a flipped coordinate system, so
739 // the arrow is pointing down.
740 CGPathMoveToPoint(shape, NULL, 8.5, 2); // Tip point.
741 CGPathAddLineToPoint(shape, NULL, 4, 7);
742 CGPathAddLineToPoint(shape, NULL, 6.25, 7);
743 CGPathAddLineToPoint(shape, NULL, 6.25, 10.25);
744 CGPathAddLineToPoint(shape, NULL, 10.75, 10.25);
745 CGPathAddLineToPoint(shape, NULL, 10.75, 7);
746 CGPathAddLineToPoint(shape, NULL, 13, 7);
747 CGPathAddLineToPoint(shape, NULL, 8.5, 2);
749 // Draw the rectangle that underneath (or above in the flipped system) the
751 CGPathAddLineToPoint(shape, NULL, 10.75, 12);
752 CGPathAddLineToPoint(shape, NULL, 6.25, 12);
753 CGPathAddLineToPoint(shape, NULL, 6.25, 14.25);
754 CGPathAddLineToPoint(shape, NULL, 10.75, 14.25);
755 CGPathAddLineToPoint(shape, NULL, 10.75, 12);
757 // Scale and translate the shape.
759 CGFloat maxX = CGRectGetMaxX(cgr);
760 CGFloat minY = CGRectGetMinY(cgr);
761 CGFloat heightScale = r.height() / kSquareSize;
762 CGAffineTransform transform = CGAffineTransformMake(
763 heightScale, 0, // A B
764 0, heightScale, // C D
765 maxX - r.height(), minY); // Tx Ty
767 CGMutablePathRef paintPath = CGPathCreateMutable();
768 CGPathAddPath(paintPath, &transform, shape);
769 CGPathRelease(shape);
771 CGContextSetRGBFillColor(c, 0, 0, 0, 0.4);
772 CGContextBeginPath(c);
773 CGContextAddPath(c, paintPath);
774 CGContextFillPath(c);
775 CGPathRelease(paintPath);
780 bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
782 LocalCurrentGraphicsContext localContext(paintInfo.context, r);
783 _NSDrawCarbonThemeListBox(r, isEnabled(o) && !isReadOnlyControl(o), YES, YES);
787 const int* RenderThemeChromiumMac::popupButtonMargins() const
789 static const int margins[3][4] =
795 return margins[[popupButton() controlSize]];
798 const IntSize* RenderThemeChromiumMac::popupButtonSizes() const
800 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
804 const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const
806 static const int padding[3][4] =
812 return padding[size];
815 bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
817 setPopupButtonCellState(o, r);
819 NSPopUpButtonCell* popupButton = this->popupButton();
821 float zoomLevel = o->style()->effectiveZoom();
822 IntSize size = popupButtonSizes()[[popupButton controlSize]];
823 size.setHeight(size.height() * zoomLevel);
824 size.setWidth(r.width());
826 // Now inflate it to account for the shadow.
827 IntRect inflatedRect = r;
828 if (r.width() >= minimumMenuListSize(o->style()))
829 inflatedRect = ThemeMac::inflateRect(inflatedRect, size, popupButtonMargins(), zoomLevel);
831 LocalCurrentGraphicsContext localContext(paintInfo.context, ThemeMac::inflateRectForFocusRing(inflatedRect));
832 GraphicsContextStateSaver stateSaver(*paintInfo.context);
834 // On Leopard, the cell will draw outside of the given rect, so we have to
836 paintInfo.context->clip(inflatedRect);
838 if (zoomLevel != 1.0f) {
839 inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
840 inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
841 paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
842 paintInfo.context->scale(zoomLevel, zoomLevel);
843 paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
846 NSView *view = documentViewFor(o);
847 [popupButton drawWithFrame:inflatedRect inView:view];
848 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
849 if (isFocused(o) && o->style()->outlineStyleIsAuto())
850 [popupButton _web_drawFocusRingWithFrame:inflatedRect inView:view];
852 [popupButton setControlView:nil];
857 IntSize RenderThemeChromiumMac::meterSizeForBounds(const RenderMeter* renderMeter, const IntRect& bounds) const
859 if (NoControlPart == renderMeter->style()->appearance())
860 return bounds.size();
862 NSLevelIndicatorCell* cell = levelIndicatorFor(renderMeter);
863 // Makes enough room for cell's intrinsic size.
864 NSSize cellSize = [cell cellSizeForBounds:IntRect(IntPoint(), bounds.size())];
865 return IntSize(bounds.width() < cellSize.width ? cellSize.width : bounds.width(),
866 bounds.height() < cellSize.height ? cellSize.height : bounds.height());
869 bool RenderThemeChromiumMac::paintMeter(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
871 if (!renderObject->isMeter())
874 LocalCurrentGraphicsContext localContext(paintInfo.context, rect);
876 NSLevelIndicatorCell* cell = levelIndicatorFor(toRenderMeter(renderObject));
877 GraphicsContextStateSaver stateSaver(*paintInfo.context);
879 [cell drawWithFrame:rect inView:documentViewFor(renderObject)];
880 [cell setControlView:nil];
884 bool RenderThemeChromiumMac::supportsMeter(ControlPart part) const
887 case RelevancyLevelIndicatorPart:
888 case DiscreteCapacityLevelIndicatorPart:
889 case RatingLevelIndicatorPart:
891 case ContinuousCapacityLevelIndicatorPart:
898 NSLevelIndicatorStyle RenderThemeChromiumMac::levelIndicatorStyleFor(ControlPart part) const
901 case RelevancyLevelIndicatorPart:
902 return NSRelevancyLevelIndicatorStyle;
903 case DiscreteCapacityLevelIndicatorPart:
904 return NSDiscreteCapacityLevelIndicatorStyle;
905 case RatingLevelIndicatorPart:
906 return NSRatingLevelIndicatorStyle;
908 case ContinuousCapacityLevelIndicatorPart:
910 return NSContinuousCapacityLevelIndicatorStyle;
914 NSLevelIndicatorCell* RenderThemeChromiumMac::levelIndicatorFor(const RenderMeter* renderMeter) const
916 RenderStyle* style = renderMeter->style();
917 ASSERT(style->appearance() != NoControlPart);
919 if (!m_levelIndicator)
920 m_levelIndicator.adoptNS([[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle]);
921 NSLevelIndicatorCell* cell = m_levelIndicator.get();
923 HTMLMeterElement* element = renderMeter->meterElement();
924 double value = element->value();
926 // Because NSLevelIndicatorCell does not support optimum-in-the-middle type
927 // coloring, we explicitly control the color instead giving low and high
928 // value to NSLevelIndicatorCell as is.
929 switch (element->gaugeRegion()) {
930 case HTMLMeterElement::GaugeRegionOptimum:
931 // Make meter the green.
932 [cell setWarningValue:value + 1];
933 [cell setCriticalValue:value + 2];
935 case HTMLMeterElement::GaugeRegionSuboptimal:
936 // Make the meter yellow.
937 [cell setWarningValue:value - 1];
938 [cell setCriticalValue:value + 1];
940 case HTMLMeterElement::GaugeRegionEvenLessGood:
941 // Make the meter red.
942 [cell setWarningValue:value - 2];
943 [cell setCriticalValue:value - 1];
947 [cell setLevelIndicatorStyle:levelIndicatorStyleFor(style->appearance())];
948 [cell setBaseWritingDirection:style->isLeftToRightDirection() ? NSWritingDirectionLeftToRight : NSWritingDirectionRightToLeft];
949 [cell setMinValue:element->min()];
950 [cell setMaxValue:element->max()];
951 RetainPtr<NSNumber> valueObject = [NSNumber numberWithDouble:value];
952 [cell setObjectValue:valueObject.get()];
957 const IntSize* RenderThemeChromiumMac::progressBarSizes() const
959 static const IntSize sizes[3] = { IntSize(0, 20), IntSize(0, 12), IntSize(0, 12) };
963 const int* RenderThemeChromiumMac::progressBarMargins(NSControlSize controlSize) const
965 static const int margins[3][4] =
971 return margins[controlSize];
974 int RenderThemeChromiumMac::minimumProgressBarHeight(RenderStyle* style) const
976 return sizeForSystemFont(style, progressBarSizes()).height();
979 double RenderThemeChromiumMac::animationRepeatIntervalForProgressBar(RenderProgress*) const
981 return progressAnimationFrameRate;
984 double RenderThemeChromiumMac::animationDurationForProgressBar(RenderProgress*) const
986 return progressAnimationNumFrames * progressAnimationFrameRate;
989 bool RenderThemeChromiumMac::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
991 if (!renderObject->isProgress())
994 float zoomLevel = renderObject->style()->effectiveZoom();
995 int controlSize = controlSizeForFont(renderObject->style());
996 IntSize size = progressBarSizes()[controlSize];
997 size.setHeight(size.height() * zoomLevel);
998 size.setWidth(rect.width());
1000 // Now inflate it to account for the shadow.
1001 IntRect inflatedRect = rect;
1002 if (rect.height() <= minimumProgressBarHeight(renderObject->style()))
1003 inflatedRect = ThemeMac::inflateRect(inflatedRect, size, progressBarMargins(controlSize), zoomLevel);
1005 RenderProgress* renderProgress = toRenderProgress(renderObject);
1006 HIThemeTrackDrawInfo trackInfo;
1007 trackInfo.version = 0;
1008 if (controlSize == NSRegularControlSize)
1009 trackInfo.kind = renderProgress->position() < 0 ? kThemeLargeIndeterminateBar : kThemeLargeProgressBar;
1011 trackInfo.kind = renderProgress->position() < 0 ? kThemeMediumIndeterminateBar : kThemeMediumProgressBar;
1013 trackInfo.bounds = IntRect(IntPoint(), inflatedRect.size());
1015 trackInfo.max = std::numeric_limits<SInt32>::max();
1016 trackInfo.value = lround(renderProgress->position() * nextafter(trackInfo.max, 0));
1017 trackInfo.trackInfo.progress.phase = lround(renderProgress->animationProgress() * nextafter(progressAnimationNumFrames, 0));
1018 trackInfo.attributes = kThemeTrackHorizontal;
1019 trackInfo.enableState = isActive(renderObject) ? kThemeTrackActive : kThemeTrackInactive;
1020 trackInfo.reserved = 0;
1021 trackInfo.filler1 = 0;
1023 OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(inflatedRect.size());
1027 LocalCurrentGraphicsContext localContext(imageBuffer->context(), IntRect(IntPoint(), inflatedRect.size()));
1028 CGContextRef cgContext = localContext.cgContext();
1029 HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal);
1031 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1033 if (!renderProgress->style()->isLeftToRightDirection()) {
1034 paintInfo.context->translate(2 * inflatedRect.x() + inflatedRect.width(), 0);
1035 paintInfo.context->scale(-1, 1);
1038 paintInfo.context->drawImageBuffer(imageBuffer.get(),
1039 FloatRect(inflatedRect.location(), imageBuffer->size()));
1043 const float baseFontSize = 11.0f;
1044 const float baseArrowHeight = 4.0f;
1045 const float baseArrowWidth = 5.0f;
1046 const float baseSpaceBetweenArrows = 2.0f;
1047 const int arrowPaddingLeft = 6;
1048 const int arrowPaddingRight = 6;
1049 const int paddingBeforeSeparator = 4;
1050 const int baseBorderRadius = 5;
1051 const int styledPopupPaddingLeft = 8;
1052 const int styledPopupPaddingTop = 1;
1053 const int styledPopupPaddingBottom = 2;
1055 bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1057 IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
1058 r.y() + o->style()->borderTopWidth(),
1059 r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
1060 r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
1061 // Since we actually know the size of the control here, we restrict the font
1062 // scale to make sure the arrows will fit vertically in the bounds
1063 float fontScale = std::min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
1064 float centerY = bounds.y() + bounds.height() / 2.0f;
1065 float arrowHeight = baseArrowHeight * fontScale;
1066 float arrowWidth = baseArrowWidth * fontScale;
1067 float leftEdge = bounds.maxX() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
1068 float spaceBetweenArrows = baseSpaceBetweenArrows * fontScale;
1070 if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
1073 Color color = o->style()->visitedDependentColor(CSSPropertyColor);
1075 FloatPoint arrow1[3];
1076 arrow1[0] = FloatPoint(leftEdge, centerY - spaceBetweenArrows / 2.0f);
1077 arrow1[1] = FloatPoint(leftEdge + arrowWidth, centerY - spaceBetweenArrows / 2.0f);
1078 arrow1[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY - spaceBetweenArrows / 2.0f - arrowHeight);
1080 // Draw the top arrow.
1081 paintInfo.context->fillPolygon(3, arrow1, color, true);
1083 FloatPoint arrow2[3];
1084 arrow2[0] = FloatPoint(leftEdge, centerY + spaceBetweenArrows / 2.0f);
1085 arrow2[1] = FloatPoint(leftEdge + arrowWidth, centerY + spaceBetweenArrows / 2.0f);
1086 arrow2[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + spaceBetweenArrows / 2.0f + arrowHeight);
1088 // Draw the bottom arrow.
1089 paintInfo.context->fillPolygon(3, arrow2, color, true);
1093 static const IntSize* menuListButtonSizes()
1095 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
1099 void RenderThemeChromiumMac::adjustMenuListStyle(RenderStyle* style, Element* e) const
1101 NSControlSize controlSize = controlSizeForFont(style);
1103 style->resetBorder();
1104 style->resetPadding();
1106 // Height is locked to auto.
1107 style->setHeight(Length(Auto));
1109 // White-space is locked to pre.
1110 style->setWhiteSpace(PRE);
1112 // Set the foreground color to black or gray when we have the aqua look.
1113 // Cast to RGB32 is to work around a compiler bug.
1114 style->setColor(e && !e->isDisabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
1116 // Set the button's vertical size.
1117 setSizeFromFont(style, menuListButtonSizes());
1119 // Our font is locked to the appropriate system font size for the
1120 // control. To clarify, we first use the CSS-specified font to figure out a
1121 // reasonable control size, but once that control size is determined, we
1122 // throw that font away and use the appropriate system font for the control
1124 setFontFromControlSize(style, controlSize);
1127 const int autofillPopupHorizontalPadding = 4;
1129 // These functions are called with MenuListPart or MenulistButtonPart appearance
1130 // by RenderMenuList, or with TextFieldPart appearance by
1131 // AutofillPopupMenuClient. We assume only AutofillPopupMenuClient gives
1132 // TexfieldPart appearance here. We want to change only Autofill padding. In
1133 // the future, we have to separate Autofill popup window logic from WebKit to
1135 int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const
1137 if (style->appearance() == TextFieldPart)
1138 return autofillPopupHorizontalPadding;
1140 if (style->appearance() == MenulistPart)
1141 return popupButtonPadding(controlSizeForFont(style))[ThemeMac::LeftMargin] * style->effectiveZoom();
1142 if (style->appearance() == MenulistButtonPart)
1143 return styledPopupPaddingLeft * style->effectiveZoom();
1147 int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const
1149 if (style->appearance() == TextFieldPart)
1150 return autofillPopupHorizontalPadding;
1152 if (style->appearance() == MenulistPart)
1153 return popupButtonPadding(controlSizeForFont(style))[ThemeMac::RightMargin] * style->effectiveZoom();
1154 if (style->appearance() == MenulistButtonPart) {
1155 float fontScale = style->fontSize() / baseFontSize;
1156 float arrowWidth = baseArrowWidth * fontScale;
1157 return static_cast<int>(ceilf(arrowWidth + (arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator) * style->effectiveZoom()));
1162 int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const
1164 if (style->appearance() == MenulistPart)
1165 return popupButtonPadding(controlSizeForFont(style))[ThemeMac::TopMargin] * style->effectiveZoom();
1166 if (style->appearance() == MenulistButtonPart)
1167 return styledPopupPaddingTop * style->effectiveZoom();
1171 int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const
1173 if (style->appearance() == MenulistPart)
1174 return popupButtonPadding(controlSizeForFont(style))[ThemeMac::BottomMargin] * style->effectiveZoom();
1175 if (style->appearance() == MenulistButtonPart)
1176 return styledPopupPaddingBottom * style->effectiveZoom();
1180 void RenderThemeChromiumMac::adjustMenuListButtonStyle(RenderStyle* style, Element*) const
1182 float fontScale = style->fontSize() / baseFontSize;
1184 style->resetPadding();
1185 style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
1187 const int minHeight = 15;
1188 style->setMinHeight(Length(minHeight, Fixed));
1190 style->setLineHeight(RenderStyle::initialLineHeight());
1193 void RenderThemeChromiumMac::setPopupButtonCellState(const RenderObject* o, const IntRect& r)
1195 NSPopUpButtonCell* popupButton = this->popupButton();
1197 // Set the control size based off the rectangle we're painting into.
1198 setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom());
1200 // Update the various states we respond to.
1201 updateActiveState(popupButton, o);
1202 updateCheckedState(popupButton, o);
1203 updateEnabledState(popupButton, o);
1204 updatePressedState(popupButton, o);
1205 #if BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
1206 updateFocusedState(popupButton, o);
1210 const IntSize* RenderThemeChromiumMac::menuListSizes() const
1212 static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) };
1216 int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const
1218 return sizeForSystemFont(style, menuListSizes()).width();
1221 const int sliderTrackWidth = 5;
1222 const int sliderTrackBorderWidth = 1;
1224 bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1226 paintSliderTicks(o, paintInfo, r);
1228 float zoomLevel = o->style()->effectiveZoom();
1229 FloatRect unzoomedRect = r;
1231 if (o->style()->appearance() == SliderHorizontalPart || o->style()->appearance() == MediaSliderPart) {
1232 unzoomedRect.setY(ceilf(unzoomedRect.y() + unzoomedRect.height() / 2 - zoomLevel * sliderTrackWidth / 2));
1233 unzoomedRect.setHeight(zoomLevel * sliderTrackWidth);
1234 } else if (o->style()->appearance() == SliderVerticalPart) {
1235 unzoomedRect.setX(ceilf(unzoomedRect.x() + unzoomedRect.width() / 2 - zoomLevel * sliderTrackWidth / 2));
1236 unzoomedRect.setWidth(zoomLevel * sliderTrackWidth);
1239 if (zoomLevel != 1) {
1240 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1241 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1244 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1245 if (zoomLevel != 1) {
1246 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1247 paintInfo.context->scale(zoomLevel, zoomLevel);
1248 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1251 Color fillColor(205, 205, 205);
1252 Color borderGradientTopColor(109, 109, 109);
1253 Color borderGradientBottomColor(181, 181, 181);
1254 Color shadowColor(0, 0, 0, 118);
1256 if (!isEnabled(o)) {
1257 Color tintColor(255, 255, 255, 128);
1258 fillColor = fillColor.blend(tintColor);
1259 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1260 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1261 shadowColor = shadowColor.blend(tintColor);
1266 tintColor = Color(255, 255, 255, 128);
1268 bool isVerticalSlider = o->style()->appearance() == SliderVerticalPart;
1270 int fillRadiusSize = (sliderTrackWidth - sliderTrackBorderWidth) / 2;
1271 IntSize fillRadius(fillRadiusSize, fillRadiusSize);
1272 IntRect fillBounds = enclosedIntRect(unzoomedRect);
1273 RoundedRect fillRect(fillBounds, fillRadius, fillRadius, fillRadius, fillRadius);
1274 paintInfo.context->fillRoundedRect(fillRect, fillColor);
1276 IntSize shadowOffset(isVerticalSlider ? 1 : 0,
1277 isVerticalSlider ? 0 : 1);
1279 int shadowSpread = 0;
1280 paintInfo.context->save();
1281 paintInfo.context->drawInnerShadow(fillRect, shadowColor, shadowOffset, shadowBlur, shadowSpread);
1282 paintInfo.context->restore();
1284 RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(),
1285 isVerticalSlider ? fillBounds.maxXMinYCorner() : fillBounds.minXMaxYCorner());
1286 borderGradient->addColorStop(0.0, borderGradientTopColor);
1287 borderGradient->addColorStop(1.0, borderGradientBottomColor);
1289 FloatRect borderRect(unzoomedRect);
1290 borderRect.inflate(-sliderTrackBorderWidth / 2.0);
1291 float borderRadiusSize = (isVerticalSlider ? borderRect.width() : borderRect.height()) / 2;
1292 FloatSize borderRadius(borderRadiusSize, borderRadiusSize);
1293 borderPath.addRoundedRect(borderRect, borderRadius, borderRadius, borderRadius, borderRadius);
1294 paintInfo.context->setStrokeGradient(borderGradient);
1295 paintInfo.context->setStrokeThickness(sliderTrackBorderWidth);
1296 paintInfo.context->strokePath(borderPath);
1300 const int sliderThumbWidth = 15;
1301 const int sliderThumbHeight = 15;
1302 const int sliderThumbBorderWidth = 1;
1304 bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1306 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1307 float zoomLevel = o->style()->effectiveZoom();
1309 FloatRect unzoomedRect(r.x(), r.y(), sliderThumbWidth, sliderThumbHeight);
1310 if (zoomLevel != 1.0f) {
1311 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1312 paintInfo.context->scale(zoomLevel, zoomLevel);
1313 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1316 Color fillGradientTopColor(250, 250, 250);
1317 Color fillGradientUpperMiddleColor(244, 244, 244);
1318 Color fillGradientLowerMiddleColor(236, 236, 236);
1319 Color fillGradientBottomColor(238, 238, 238);
1320 Color borderGradientTopColor(151, 151, 151);
1321 Color borderGradientBottomColor(128, 128, 128);
1322 Color shadowColor(0, 0, 0, 36);
1324 if (!isEnabled(o)) {
1325 Color tintColor(255, 255, 255, 128);
1326 fillGradientTopColor = fillGradientTopColor.blend(tintColor);
1327 fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
1328 fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
1329 fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
1330 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1331 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1332 shadowColor = shadowColor.blend(tintColor);
1333 } else if (isPressed(o)) {
1334 Color tintColor(0, 0, 0, 32);
1335 fillGradientTopColor = fillGradientTopColor.blend(tintColor);
1336 fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
1337 fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
1338 fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
1339 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1340 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1341 shadowColor = shadowColor.blend(tintColor);
1344 FloatRect borderBounds = unzoomedRect;
1345 borderBounds.inflate(sliderThumbBorderWidth / 2.0);
1347 borderBounds.inflate(-sliderThumbBorderWidth);
1348 FloatSize shadowOffset(0, 1);
1349 paintInfo.context->setShadow(shadowOffset, sliderThumbShadowBlur, shadowColor);
1350 paintInfo.context->setFillColor(Color::black);
1351 paintInfo.context->fillEllipse(borderBounds);
1352 paintInfo.context->clearShadow();
1354 IntRect fillBounds = enclosedIntRect(unzoomedRect);
1355 RefPtr<Gradient> fillGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
1356 fillGradient->addColorStop(0.0, fillGradientTopColor);
1357 fillGradient->addColorStop(0.52, fillGradientUpperMiddleColor);
1358 fillGradient->addColorStop(0.52, fillGradientLowerMiddleColor);
1359 fillGradient->addColorStop(1.0, fillGradientBottomColor);
1360 paintInfo.context->setFillGradient(fillGradient);
1361 paintInfo.context->fillEllipse(borderBounds);
1363 RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
1364 borderGradient->addColorStop(0.0, borderGradientTopColor);
1365 borderGradient->addColorStop(1.0, borderGradientBottomColor);
1366 paintInfo.context->setStrokeGradient(borderGradient);
1367 paintInfo.context->setStrokeThickness(sliderThumbBorderWidth);
1368 paintInfo.context->strokeEllipse(borderBounds);
1372 borderPath.addEllipse(borderBounds);
1373 paintInfo.context->drawFocusRing(borderPath, 5, -2, focusRingColor());
1379 bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1381 LocalCurrentGraphicsContext localContext(paintInfo.context, r);
1383 NSSearchFieldCell* search = this->search();
1384 setSearchCellState(o, r);
1385 [search setControlSize:searchFieldControlSizeForFont(o->style())];
1387 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1389 float zoomLevel = o->style()->effectiveZoom();
1391 IntRect unzoomedRect = r;
1393 if (zoomLevel != 1.0f) {
1394 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1395 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1396 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1397 paintInfo.context->scale(zoomLevel, zoomLevel);
1398 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1401 // Set the search button to nil before drawing. Then reset it so we can
1403 [search setSearchButtonCell:nil];
1405 [search drawWithFrame:NSRect(unzoomedRect) inView:documentViewFor(o)];
1407 [search setControlView:nil];
1408 [search resetSearchButtonCell];
1413 void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&)
1415 NSSearchFieldCell* search = this->search();
1417 // Update the various states we respond to.
1418 updateActiveState(search, o);
1419 updateEnabledState(search, o);
1420 updateFocusedState(search, o);
1423 const IntSize* RenderThemeChromiumMac::searchFieldSizes() const
1425 static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 15) };
1429 static const int* searchFieldHorizontalPaddings()
1431 static const int sizes[3] = { 3, 2, 1 };
1435 void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const
1437 // If the width and height are both specified, then we have nothing to do.
1438 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
1441 // Use the font size to determine the intrinsic width of the control.
1442 setSizeFromFont(style, searchFieldSizes());
1445 const int searchFieldBorderWidth = 2;
1446 void RenderThemeChromiumMac::adjustSearchFieldStyle(RenderStyle* style, Element*) const
1449 style->resetBorder();
1450 const short borderWidth = searchFieldBorderWidth * style->effectiveZoom();
1451 style->setBorderLeftWidth(borderWidth);
1452 style->setBorderLeftStyle(INSET);
1453 style->setBorderRightWidth(borderWidth);
1454 style->setBorderRightStyle(INSET);
1455 style->setBorderBottomWidth(borderWidth);
1456 style->setBorderBottomStyle(INSET);
1457 style->setBorderTopWidth(borderWidth);
1458 style->setBorderTopStyle(INSET);
1461 style->setHeight(Length(Auto));
1462 setSearchFieldSize(style);
1464 NSControlSize controlSize = controlSizeForFont(style);
1466 // Override padding size to match AppKit text positioning.
1467 const int verticalPadding = 1 * style->effectiveZoom();
1468 const int horizontalPadding = searchFieldHorizontalPaddings()[controlSize] * style->effectiveZoom();
1469 style->setPaddingLeft(Length(horizontalPadding, Fixed));
1470 style->setPaddingRight(Length(horizontalPadding, Fixed));
1471 style->setPaddingTop(Length(verticalPadding, Fixed));
1472 style->setPaddingBottom(Length(verticalPadding, Fixed));
1474 setFontFromControlSize(style, controlSize);
1476 style->setBoxShadow(nullptr);
1479 bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1483 Element* input = o->node()->shadowHost();
1485 input = toElement(o->node());
1487 if (!input->renderer()->isBox())
1490 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1492 float zoomLevel = o->style()->effectiveZoom();
1493 FloatRect unzoomedRect(r);
1494 if (zoomLevel != 1.0f) {
1495 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1496 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1497 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1498 paintInfo.context->scale(zoomLevel, zoomLevel);
1499 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1502 Color fillColor(200, 200, 200);
1505 Color tintColor(0, 0, 0, 32);
1506 fillColor = fillColor.blend(tintColor);
1509 float centerX = unzoomedRect.x() + unzoomedRect.width() / 2;
1510 float centerY = unzoomedRect.y() + unzoomedRect.height() / 2;
1511 // The line width is 3px on a regular sized, high DPI NSCancelButtonCell
1512 // (which is 28px wide).
1513 float lineWidth = unzoomedRect.width() * 3 / 28;
1514 // The line length is 16px on a regular sized, high DPI NSCancelButtonCell.
1515 float lineLength = unzoomedRect.width() * 16 / 28;
1518 FloatSize lineRectRadius(lineWidth / 2, lineWidth / 2);
1519 xPath.addRoundedRect(FloatRect(-lineLength / 2, -lineWidth / 2, lineLength, lineWidth),
1520 lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
1521 xPath.addRoundedRect(FloatRect(-lineWidth / 2, -lineLength / 2, lineWidth, lineLength),
1522 lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
1524 paintInfo.context->translate(centerX, centerY);
1525 paintInfo.context->rotate(deg2rad(45.0));
1526 paintInfo.context->clipOut(xPath);
1527 paintInfo.context->rotate(deg2rad(-45.0));
1528 paintInfo.context->translate(-centerX, -centerY);
1530 paintInfo.context->setFillColor(fillColor);
1531 paintInfo.context->fillEllipse(unzoomedRect);
1536 const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const
1538 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(11, 11), IntSize(9, 9) };
1542 void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(RenderStyle* style, Element*) const
1544 IntSize size = sizeForSystemFont(style, cancelButtonSizes());
1545 style->setWidth(Length(size.width(), Fixed));
1546 style->setHeight(Length(size.height(), Fixed));
1547 style->setBoxShadow(nullptr);
1550 const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const
1552 static const IntSize sizes[3] = { IntSize(15, 14), IntSize(16, 13), IntSize(14, 11) };
1556 void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(RenderStyle* style, Element*) const
1558 NSControlSize controlSize = controlSizeForSystemFont(style);
1559 IntSize searchFieldSize = searchFieldSizes()[controlSize];
1560 int width = searchFieldSize.height() / 2 - searchFieldBorderWidth - searchFieldHorizontalPaddings()[controlSize];
1561 style->setWidth(Length(width, Fixed));
1562 style->setHeight(Length(0, Fixed));
1563 style->setBoxShadow(nullptr);
1566 bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&)
1571 void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(RenderStyle* style, Element*) const
1573 IntSize size = sizeForSystemFont(style, resultsButtonSizes());
1574 style->setWidth(Length(size.width(), Fixed));
1575 style->setHeight(Length(size.height(), Fixed));
1576 style->setBoxShadow(nullptr);
1579 bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1583 Node* input = o->node()->shadowHost();
1586 if (!input->renderer()->isBox())
1589 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1591 float zoomLevel = o->style()->effectiveZoom();
1592 FloatRect unzoomedRect(r);
1593 if (zoomLevel != 1) {
1594 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1595 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1596 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1597 paintInfo.context->scale(zoomLevel, zoomLevel);
1598 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1601 LocalCurrentGraphicsContext localContext(paintInfo.context, r);
1603 NSSearchFieldCell* search = this->search();
1604 setSearchCellState(input->renderer(), r);
1605 [search setControlSize:searchFieldControlSizeForFont(o->style())];
1606 if ([search searchMenuTemplate] != nil)
1607 [search setSearchMenuTemplate:nil];
1609 updateActiveState([search searchButtonCell], o);
1611 [[search searchButtonCell] drawWithFrame:unzoomedRect inView:documentViewFor(o)];
1612 [[search searchButtonCell] setControlView:nil];
1616 IntSize RenderThemeChromiumMac::sliderTickSize() const
1618 return IntSize(1, 3);
1621 int RenderThemeChromiumMac::sliderTickOffsetFromTrackCenter() const
1626 void RenderThemeChromiumMac::adjustSliderThumbSize(RenderStyle* style, Element*) const
1628 float zoomLevel = style->effectiveZoom();
1629 if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
1630 style->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
1631 style->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
1634 adjustMediaSliderThumbSize(style);
1637 NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const
1639 if (!m_popupButton) {
1640 m_popupButton.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]);
1641 [m_popupButton.get() setUsesItemFromMenu:NO];
1642 [m_popupButton.get() setFocusRingType:NSFocusRingTypeExterior];
1645 return m_popupButton.get();
1648 NSSearchFieldCell* RenderThemeChromiumMac::search() const
1651 m_search.adoptNS([[NSSearchFieldCell alloc] initTextCell:@""]);
1652 [m_search.get() setBezelStyle:NSTextFieldRoundedBezel];
1653 [m_search.get() setBezeled:YES];
1654 [m_search.get() setEditable:YES];
1655 [m_search.get() setFocusRingType:NSFocusRingTypeExterior];
1656 SEL sel = @selector(setCenteredLook:);
1657 if ([m_search.get() respondsToSelector:sel]) {
1658 BOOL boolValue = NO;
1659 NSMethodSignature* signature = [NSSearchFieldCell instanceMethodSignatureForSelector:sel];
1660 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
1661 [invocation setTarget:m_search.get()];
1662 [invocation setSelector:sel];
1663 [invocation setArgument:&boolValue atIndex:2];
1664 [invocation invoke];
1668 return m_search.get();
1671 NSTextFieldCell* RenderThemeChromiumMac::textField() const
1674 m_textField.adoptNS([[WebCoreTextFieldCell alloc] initTextCell:@""]);
1675 [m_textField.get() setBezeled:YES];
1676 [m_textField.get() setEditable:YES];
1677 [m_textField.get() setFocusRingType:NSFocusRingTypeExterior];
1678 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
1679 [m_textField.get() setDrawsBackground:YES];
1680 [m_textField.get() setBackgroundColor:[NSColor whiteColor]];
1682 // Post-Lion, WebCore can be in charge of paintinng the background
1683 // thanks to the workaround in place for <rdar://problem/11385461>,
1684 // which is implemented above as _coreUIDrawOptionsWithFrame.
1685 [m_textField.get() setDrawsBackground:NO];
1689 return m_textField.get();
1692 String RenderThemeChromiumMac::fileListNameForWidth(Locale& locale, const FileList* fileList, const Font& font, int width) const
1697 String strToTruncate;
1698 if (fileList->isEmpty()) {
1699 strToTruncate = locale.queryString(WebLocalizedString::FileButtonNoFileSelectedLabel);
1700 } else if (fileList->length() == 1) {
1701 File* file = fileList->item(0);
1702 if (file->userVisibility() == File::IsUserVisible)
1703 strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(fileList->item(0)->path())];
1705 strToTruncate = file->name();
1707 // FIXME: Localization of fileList->length().
1708 return StringTruncator::rightTruncate(locale.queryString(WebLocalizedString::MultipleFileUploadText, String::number(fileList->length())), width, font);
1711 return StringTruncator::centerTruncate(strToTruncate, width, font);
1714 NSView* FlippedView()
1716 static NSView* view = [[RTCMFlippedView alloc] init];
1720 RenderTheme& RenderTheme::theme()
1722 DEFINE_STATIC_REF(RenderTheme, renderTheme, (RenderThemeChromiumMac::create()));
1723 return *renderTheme;
1726 PassRefPtr<RenderTheme> RenderThemeChromiumMac::create()
1728 return adoptRef(new RenderThemeChromiumMac);
1731 bool RenderThemeChromiumMac::usesTestModeFocusRingColor() const
1733 return LayoutTestSupport::isRunningLayoutTest();
1736 NSView* RenderThemeChromiumMac::documentViewFor(RenderObject*) const
1738 return FlippedView();
1741 // Updates the control tint (a.k.a. active state) of |cell| (from |o|). In the
1742 // Chromium port, the renderer runs as a background process and controls'
1743 // NSCell(s) lack a parent NSView. Therefore controls don't have their tint
1744 // color updated correctly when the application is activated/deactivated.
1745 // FocusController's setActive() is called when the application is
1746 // activated/deactivated, which causes a paint invalidation at which time this
1748 // This function should be called before drawing any NSCell-derived controls,
1749 // unless you're sure it isn't needed.
1750 void RenderThemeChromiumMac::updateActiveState(NSCell* cell, const RenderObject* o)
1752 NSControlTint oldTint = [cell controlTint];
1753 NSControlTint tint = isActive(o) ? [NSColor currentControlTint] :
1754 static_cast<NSControlTint>(NSClearControlTint);
1756 if (tint != oldTint)
1757 [cell setControlTint:tint];
1760 bool RenderThemeChromiumMac::shouldShowPlaceholderWhenFocused() const
1765 void RenderThemeChromiumMac::adjustMediaSliderThumbSize(RenderStyle* style) const
1767 RenderMediaControls::adjustMediaSliderThumbSize(style);
1770 bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1772 return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);
1775 bool RenderThemeChromiumMac::paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1777 return RenderMediaControls::paintMediaControlsPart(MediaOverlayPlayButton, object, paintInfo, rect);
1780 bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1782 return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect);
1785 bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1787 return RenderMediaControls::paintMediaControlsPart(MediaSlider, object, paintInfo, rect);
1790 String RenderThemeChromiumMac::extraFullScreenStyleSheet()
1792 // FIXME: Chromium may wish to style its default media controls differently in fullscreen.
1796 String RenderThemeChromiumMac::extraDefaultStyleSheet()
1798 return RenderTheme::extraDefaultStyleSheet() +
1799 String(themeChromiumCss, sizeof(themeChromiumCss)) +
1800 String(themeInputMultipleFieldsCss, sizeof(themeInputMultipleFieldsCss)) +
1801 String(themeMacCss, sizeof(themeMacCss));
1804 bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1809 bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1811 return RenderMediaControls::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
1814 bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1816 return RenderMediaControls::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
1819 bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1821 return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
1824 String RenderThemeChromiumMac::formatMediaControlsTime(float time) const
1826 return RenderMediaControls::formatMediaControlsTime(time);
1829 String RenderThemeChromiumMac::formatMediaControlsCurrentTime(float currentTime, float duration) const
1831 return RenderMediaControls::formatMediaControlsCurrentTime(currentTime, duration);
1834 bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1836 return RenderMediaControls::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect);
1839 bool RenderThemeChromiumMac::paintMediaToggleClosedCaptionsButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1841 return RenderMediaControls::paintMediaControlsPart(MediaShowClosedCaptionsButton, object, paintInfo, rect);
1844 bool RenderThemeChromiumMac::shouldUseFallbackTheme(RenderStyle* style) const
1846 ControlPart part = style->appearance();
1847 if (part == CheckboxPart || part == RadioPart)
1848 return style->effectiveZoom() != 1;
1852 } // namespace blink