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/html/HTMLInputElement.h"
32 #import "core/html/HTMLMediaElement.h"
33 #import "core/html/HTMLMeterElement.h"
34 #import "core/html/TimeRanges.h"
35 #import "core/html/shadow/MediaControlElements.h"
36 #import "core/frame/FrameView.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"
59 #import <AvailabilityMacros.h>
60 #import <Carbon/Carbon.h>
61 #import <Cocoa/Cocoa.h>
63 #import <wtf/RetainPtr.h>
64 #import <wtf/StdLibExtras.h>
66 // The methods in this file are specific to the Mac OS X platform.
68 // We estimate the animation rate of a Mac OS X progress bar is 33 fps.
69 // Hard code the value here because we haven't found API for it.
70 const double progressAnimationFrameRate = 0.033;
72 // Mac OS X progress bar animation seems to have 256 frames.
73 const double progressAnimationNumFrames = 256;
75 @interface WebCoreRenderThemeNotificationObserver : NSObject
77 blink::RenderTheme *_theme;
80 - (id)initWithTheme:(blink::RenderTheme *)theme;
81 - (void)systemColorsDidChange:(NSNotification *)notification;
85 @implementation WebCoreRenderThemeNotificationObserver
87 - (id)initWithTheme:(blink::RenderTheme *)theme
89 if (!(self = [super init]))
96 - (void)systemColorsDidChange:(NSNotification *)unusedNotification
98 ASSERT_UNUSED(unusedNotification, [[unusedNotification name] isEqualToString:NSSystemColorsDidChangeNotification]);
99 _theme->platformColorsDidChange();
104 @interface NSTextFieldCell (WKDetails)
105 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
109 @interface WebCoreTextFieldCell : NSTextFieldCell
110 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus;
113 @implementation WebCoreTextFieldCell
114 - (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame inView:(NSView *)controlView includeFocus:(BOOL)includeFocus
116 // FIXME: This is a post-Lion-only workaround for <rdar://problem/11385461>. When that bug is resolved, we should remove this code.
117 CFMutableDictionaryRef coreUIDrawOptions = CFDictionaryCreateMutableCopy(NULL, 0, [super _coreUIDrawOptionsWithFrame:cellFrame inView:controlView includeFocus:includeFocus]);
118 CFDictionarySetValue(coreUIDrawOptions, @"borders only", kCFBooleanTrue);
119 return (CFDictionaryRef)[NSMakeCollectable(coreUIDrawOptions) autorelease];
123 @interface RTCMFlippedView : NSView
127 - (NSText *)currentEditor;
131 @implementation RTCMFlippedView
134 return [[NSGraphicsContext currentContext] isFlipped];
137 - (NSText *)currentEditor {
143 // Forward declare Mac SPIs.
145 void _NSDrawCarbonThemeBezel(NSRect frame, BOOL enabled, BOOL flipped);
146 // Request for public API: rdar://13787640
147 void _NSDrawCarbonThemeListBox(NSRect frame, BOOL enabled, BOOL flipped, BOOL always_yes);
152 using namespace HTMLNames;
168 RenderThemeChromiumMac::RenderThemeChromiumMac()
169 : m_notificationObserver(AdoptNS, [[WebCoreRenderThemeNotificationObserver alloc] initWithTheme:this])
171 [[NSNotificationCenter defaultCenter] addObserver:m_notificationObserver.get()
172 selector:@selector(systemColorsDidChange:)
173 name:NSSystemColorsDidChangeNotification
177 RenderThemeChromiumMac::~RenderThemeChromiumMac()
179 [[NSNotificationCenter defaultCenter] removeObserver:m_notificationObserver.get()];
182 Color RenderThemeChromiumMac::platformActiveSelectionBackgroundColor() const
184 NSColor* color = [[NSColor selectedTextBackgroundColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
185 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
188 Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const
190 NSColor* color = [[NSColor secondarySelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
191 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
194 Color RenderThemeChromiumMac::platformActiveSelectionForegroundColor() const
199 Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const
201 NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
202 return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
205 Color RenderThemeChromiumMac::platformActiveListBoxSelectionForegroundColor() const
210 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor() const
215 Color RenderThemeChromiumMac::platformFocusRingColor() const
217 static const RGBA32 oldAquaFocusRingColor = 0xFF7DADD9;
218 if (usesTestModeFocusRingColor())
219 return oldAquaFocusRingColor;
221 return systemColor(CSSValueWebkitFocusRingColor);
224 Color RenderThemeChromiumMac::platformInactiveListBoxSelectionBackgroundColor() const
226 return platformInactiveSelectionBackgroundColor();
229 static FontWeight toFontWeight(NSInteger appKitFontWeight)
231 ASSERT(appKitFontWeight > 0 && appKitFontWeight < 15);
232 if (appKitFontWeight > 14)
233 appKitFontWeight = 14;
234 else if (appKitFontWeight < 1)
235 appKitFontWeight = 1;
237 static FontWeight fontWeights[] = {
253 return fontWeights[appKitFontWeight - 1];
256 void RenderThemeChromiumMac::systemFont(CSSValueID cssValueId, FontDescription& fontDescription) const
258 DEFINE_STATIC_LOCAL(FontDescription, systemFont, ());
259 DEFINE_STATIC_LOCAL(FontDescription, smallSystemFont, ());
260 DEFINE_STATIC_LOCAL(FontDescription, menuFont, ());
261 DEFINE_STATIC_LOCAL(FontDescription, labelFont, ());
262 DEFINE_STATIC_LOCAL(FontDescription, miniControlFont, ());
263 DEFINE_STATIC_LOCAL(FontDescription, smallControlFont, ());
264 DEFINE_STATIC_LOCAL(FontDescription, controlFont, ());
266 FontDescription* cachedDesc;
268 switch (cssValueId) {
269 case CSSValueSmallCaption:
270 cachedDesc = &smallSystemFont;
271 if (!smallSystemFont.isAbsoluteSize())
272 font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
275 cachedDesc = &menuFont;
276 if (!menuFont.isAbsoluteSize())
277 font = [NSFont menuFontOfSize:[NSFont systemFontSize]];
279 case CSSValueStatusBar:
280 cachedDesc = &labelFont;
281 if (!labelFont.isAbsoluteSize())
282 font = [NSFont labelFontOfSize:[NSFont labelFontSize]];
284 case CSSValueWebkitMiniControl:
285 cachedDesc = &miniControlFont;
286 if (!miniControlFont.isAbsoluteSize())
287 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
289 case CSSValueWebkitSmallControl:
290 cachedDesc = &smallControlFont;
291 if (!smallControlFont.isAbsoluteSize())
292 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]];
294 case CSSValueWebkitControl:
295 cachedDesc = &controlFont;
296 if (!controlFont.isAbsoluteSize())
297 font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]];
300 cachedDesc = &systemFont;
301 if (!systemFont.isAbsoluteSize())
302 font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
306 NSFontManager *fontManager = [NSFontManager sharedFontManager];
307 cachedDesc->setIsAbsoluteSize(true);
308 cachedDesc->setGenericFamily(FontDescription::NoFamily);
309 cachedDesc->firstFamily().setFamily([font webCoreFamilyName]);
310 cachedDesc->setSpecifiedSize([font pointSize]);
311 cachedDesc->setWeight(toFontWeight([fontManager weightOfFont:font]));
312 cachedDesc->setStyle([fontManager traitsOfFont:font] & NSItalicFontMask ? FontStyleItalic : FontStyleNormal);
314 fontDescription = *cachedDesc;
317 static RGBA32 convertNSColorToColor(NSColor *color)
319 NSColor *colorInColorSpace = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
320 if (colorInColorSpace) {
321 static const double scaleFactor = nextafter(256.0, 0.0);
322 return makeRGB(static_cast<int>(scaleFactor * [colorInColorSpace redComponent]),
323 static_cast<int>(scaleFactor * [colorInColorSpace greenComponent]),
324 static_cast<int>(scaleFactor * [colorInColorSpace blueComponent]));
327 // This conversion above can fail if the NSColor in question is an NSPatternColor
328 // (as many system colors are). These colors are actually a repeating pattern
329 // not just a solid color. To work around this we simply draw a 1x1 image of
330 // the color and use that pixel's color. It might be better to use an average of
331 // the colors in the pattern instead.
332 NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
339 colorSpaceName:NSDeviceRGBColorSpace
343 [NSGraphicsContext saveGraphicsState];
344 [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]];
345 NSEraseRect(NSMakeRect(0, 0, 1, 1));
346 [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
347 [NSGraphicsContext restoreGraphicsState];
350 [offscreenRep getPixel:pixel atX:0 y:0];
352 [offscreenRep release];
354 return makeRGB(pixel[0], pixel[1], pixel[2]);
357 static RGBA32 menuBackgroundColor()
359 NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
366 colorSpaceName:NSDeviceRGBColorSpace
370 CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep] graphicsPort]);
371 CGRect rect = CGRectMake(0, 0, 1, 1);
372 HIThemeMenuDrawInfo drawInfo;
373 drawInfo.version = 0;
374 drawInfo.menuType = kThemeMenuTypePopUp;
375 HIThemeDrawMenuBackground(&rect, &drawInfo, context, kHIThemeOrientationInverted);
378 [offscreenRep getPixel:pixel atX:0 y:0];
380 [offscreenRep release];
382 return makeRGB(pixel[0], pixel[1], pixel[2]);
385 void RenderThemeChromiumMac::platformColorsDidChange()
387 m_systemColorCache.clear();
388 RenderTheme::platformColorsDidChange();
391 Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
394 HashMap<int, RGBA32>::iterator it = m_systemColorCache.find(cssValueId);
395 if (it != m_systemColorCache.end())
400 bool needsFallback = false;
401 switch (cssValueId) {
402 case CSSValueActiveborder:
403 color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
405 case CSSValueActivecaption:
406 color = convertNSColorToColor([NSColor windowFrameTextColor]);
408 case CSSValueAppworkspace:
409 color = convertNSColorToColor([NSColor headerColor]);
411 case CSSValueBackground:
412 // Use theme independent default
413 needsFallback = true;
415 case CSSValueButtonface:
416 // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
417 // We may want to change this to use the NSColor in future.
420 case CSSValueButtonhighlight:
421 color = convertNSColorToColor([NSColor controlHighlightColor]);
423 case CSSValueButtonshadow:
424 color = convertNSColorToColor([NSColor controlShadowColor]);
426 case CSSValueButtontext:
427 color = convertNSColorToColor([NSColor controlTextColor]);
429 case CSSValueCaptiontext:
430 color = convertNSColorToColor([NSColor textColor]);
432 case CSSValueGraytext:
433 color = convertNSColorToColor([NSColor disabledControlTextColor]);
435 case CSSValueHighlight:
436 color = convertNSColorToColor([NSColor selectedTextBackgroundColor]);
438 case CSSValueHighlighttext:
439 color = convertNSColorToColor([NSColor selectedTextColor]);
441 case CSSValueInactiveborder:
442 color = convertNSColorToColor([NSColor controlBackgroundColor]);
444 case CSSValueInactivecaption:
445 color = convertNSColorToColor([NSColor controlBackgroundColor]);
447 case CSSValueInactivecaptiontext:
448 color = convertNSColorToColor([NSColor textColor]);
450 case CSSValueInfobackground:
451 // There is no corresponding NSColor for this so we use a hard coded value.
454 case CSSValueInfotext:
455 color = convertNSColorToColor([NSColor textColor]);
458 color = menuBackgroundColor();
460 case CSSValueMenutext:
461 color = convertNSColorToColor([NSColor selectedMenuItemTextColor]);
463 case CSSValueScrollbar:
464 color = convertNSColorToColor([NSColor scrollBarColor]);
467 color = convertNSColorToColor([NSColor textColor]);
469 case CSSValueThreeddarkshadow:
470 color = convertNSColorToColor([NSColor controlDarkShadowColor]);
472 case CSSValueThreedshadow:
473 color = convertNSColorToColor([NSColor shadowColor]);
475 case CSSValueThreedface:
476 // We use this value instead of NSColor's controlColor to avoid website incompatibilities.
477 // We may want to change this to use the NSColor in future.
480 case CSSValueThreedhighlight:
481 color = convertNSColorToColor([NSColor highlightColor]);
483 case CSSValueThreedlightshadow:
484 color = convertNSColorToColor([NSColor controlLightHighlightColor]);
486 case CSSValueWebkitFocusRingColor:
487 color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
490 color = convertNSColorToColor([NSColor windowBackgroundColor]);
492 case CSSValueWindowframe:
493 color = convertNSColorToColor([NSColor windowFrameColor]);
495 case CSSValueWindowtext:
496 color = convertNSColorToColor([NSColor windowFrameTextColor]);
499 needsFallback = true;
504 color = RenderTheme::systemColor(cssValueId);
506 m_systemColorCache.set(cssValueId, color.rgb());
511 bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const CachedUAStyle* uaStyle) const
514 if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart)
515 return style->border() != uaStyle->border || style->boxShadow();
517 // FIXME: This is horrible, but there is not much else that can be done. Menu lists cannot draw properly when
518 // scaled. They can't really draw properly when transformed either. We can't detect the transform case at style
519 // adjustment time so that will just have to stay broken. We can however detect that we're zooming. If zooming
520 // is in effect we treat it like the control is styled.
521 if (style->appearance() == MenulistPart && style->effectiveZoom() != 1.0f)
523 // FIXME: NSSearchFieldCell doesn't work well when scaled.
524 if (style->appearance() == SearchFieldPart && style->effectiveZoom() != 1)
527 return RenderTheme::isControlStyled(style, uaStyle);
530 const int sliderThumbShadowBlur = 1;
532 void RenderThemeChromiumMac::adjustRepaintRect(const RenderObject* o, IntRect& r)
534 ControlPart part = o->style()->appearance();
541 case SquareButtonPart:
543 case InnerSpinButtonPart:
544 return RenderTheme::adjustRepaintRect(o, r);
550 float zoomLevel = o->style()->effectiveZoom();
552 if (part == MenulistPart) {
553 setPopupButtonCellState(o, r);
554 IntSize size = popupButtonSizes()[[popupButton() controlSize]];
555 size.setHeight(size.height() * zoomLevel);
556 size.setWidth(r.width());
557 r = inflateRect(r, size, popupButtonMargins(), zoomLevel);
558 } else if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
559 r.setHeight(r.height() + sliderThumbShadowBlur);
563 IntRect RenderThemeChromiumMac::inflateRect(const IntRect& r, const IntSize& size, const int* margins, float zoomLevel) const
565 // Only do the inflation if the available width/height are too small. Otherwise try to
566 // fit the glow/check space into the available box's width/height.
567 int widthDelta = r.width() - (size.width() + margins[leftMargin] * zoomLevel + margins[rightMargin] * zoomLevel);
568 int heightDelta = r.height() - (size.height() + margins[topMargin] * zoomLevel + margins[bottomMargin] * zoomLevel);
570 if (widthDelta < 0) {
571 result.setX(result.x() - margins[leftMargin] * zoomLevel);
572 result.setWidth(result.width() - widthDelta);
574 if (heightDelta < 0) {
575 result.setY(result.y() - margins[topMargin] * zoomLevel);
576 result.setHeight(result.height() - heightDelta);
581 FloatRect RenderThemeChromiumMac::convertToPaintingRect(const RenderObject* inputRenderer, const RenderObject* partRenderer, const FloatRect& inputRect, const IntRect& r) const
583 FloatRect partRect(inputRect);
585 // Compute an offset between the part renderer and the input renderer
586 FloatSize offsetFromInputRenderer;
587 const RenderObject* renderer = partRenderer;
588 while (renderer && renderer != inputRenderer) {
589 RenderObject* containingRenderer = renderer->container();
590 offsetFromInputRenderer -= roundedIntSize(renderer->offsetFromContainer(containingRenderer, LayoutPoint()));
591 renderer = containingRenderer;
593 // If the input renderer was not a container, something went wrong
594 ASSERT(renderer == inputRenderer);
595 // Move the rect into partRenderer's coords
596 partRect.move(offsetFromInputRenderer);
597 // Account for the local drawing offset (tx, ty)
598 partRect.move(r.x(), r.y());
603 void RenderThemeChromiumMac::updateCheckedState(NSCell* cell, const RenderObject* o)
605 bool oldIndeterminate = [cell state] == NSMixedState;
606 bool indeterminate = isIndeterminate(o);
607 bool checked = isChecked(o);
609 if (oldIndeterminate != indeterminate) {
610 [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
614 bool oldChecked = [cell state] == NSOnState;
615 if (checked != oldChecked)
616 [cell setState:checked ? NSOnState : NSOffState];
619 void RenderThemeChromiumMac::updateEnabledState(NSCell* cell, const RenderObject* o)
621 bool oldEnabled = [cell isEnabled];
622 bool enabled = isEnabled(o);
623 if (enabled != oldEnabled)
624 [cell setEnabled:enabled];
627 void RenderThemeChromiumMac::updateFocusedState(NSCell* cell, const RenderObject* o)
629 bool oldFocused = [cell showsFirstResponder];
630 bool focused = isFocused(o) && o->style()->outlineStyleIsAuto();
631 if (focused != oldFocused)
632 [cell setShowsFirstResponder:focused];
635 void RenderThemeChromiumMac::updatePressedState(NSCell* cell, const RenderObject* o)
637 bool oldPressed = [cell isHighlighted];
638 bool pressed = (o->node() && o->node()->active());
639 if (pressed != oldPressed)
640 [cell setHighlighted:pressed];
643 NSControlSize RenderThemeChromiumMac::controlSizeForFont(RenderStyle* style) const
645 int fontSize = style->fontSize();
647 return NSRegularControlSize;
649 return NSSmallControlSize;
650 return NSMiniControlSize;
653 // We don't use controlSizeForFont() for search field decorations because it needs to fit
654 // into the search field. The font size will already be modified by
655 // setFontFromControlSize() called on the search field.
656 static NSControlSize searchFieldControlSizeForFont(RenderStyle* style)
658 int fontSize = style->fontSize();
660 return NSRegularControlSize;
662 return NSSmallControlSize;
663 return NSMiniControlSize;
666 void RenderThemeChromiumMac::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize, float zoomLevel)
669 if (minSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomLevel) &&
670 minSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomLevel))
671 size = NSRegularControlSize;
672 else if (minSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomLevel) &&
673 minSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomLevel))
674 size = NSSmallControlSize;
676 size = NSMiniControlSize;
677 if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
678 [cell setControlSize:size];
681 IntSize RenderThemeChromiumMac::sizeForFont(RenderStyle* style, const IntSize* sizes) const
683 if (style->effectiveZoom() != 1.0f) {
684 IntSize result = sizes[controlSizeForFont(style)];
685 return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
687 return sizes[controlSizeForFont(style)];
690 IntSize RenderThemeChromiumMac::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const
692 if (style->effectiveZoom() != 1.0f) {
693 IntSize result = sizes[controlSizeForSystemFont(style)];
694 return IntSize(result.width() * style->effectiveZoom(), result.height() * style->effectiveZoom());
696 return sizes[controlSizeForSystemFont(style)];
699 void RenderThemeChromiumMac::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const
701 // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
702 IntSize size = sizeForFont(style, sizes);
703 if (style->width().isIntrinsicOrAuto() && size.width() > 0)
704 style->setWidth(Length(size.width(), Fixed));
705 if (style->height().isAuto() && size.height() > 0)
706 style->setHeight(Length(size.height(), Fixed));
709 void RenderThemeChromiumMac::setFontFromControlSize(RenderStyle* style, NSControlSize controlSize) const
711 FontDescription fontDescription;
712 fontDescription.setIsAbsoluteSize(true);
713 fontDescription.setGenericFamily(FontDescription::SerifFamily);
715 NSFont* font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSize]];
716 fontDescription.firstFamily().setFamily([font webCoreFamilyName]);
717 fontDescription.setComputedSize([font pointSize] * style->effectiveZoom());
718 fontDescription.setSpecifiedSize([font pointSize] * style->effectiveZoom());
721 style->setLineHeight(RenderStyle::initialLineHeight());
723 if (style->setFontDescription(fontDescription))
724 style->font().update(nullptr);
727 NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
729 float fontSize = style->fontSize();
730 float zoomLevel = style->effectiveZoom();
732 fontSize /= zoomLevel;
733 if (fontSize >= [NSFont systemFontSizeForControlSize:NSRegularControlSize])
734 return NSRegularControlSize;
735 if (fontSize >= [NSFont systemFontSizeForControlSize:NSSmallControlSize])
736 return NSSmallControlSize;
737 return NSMiniControlSize;
740 bool RenderThemeChromiumMac::paintTextField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
742 LocalCurrentGraphicsContext localContext(paintInfo.context);
744 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
745 bool useNSTextFieldCell = o->style()->hasAppearance()
746 && o->style()->visitedDependentColor(CSSPropertyBackgroundColor) == Color::white
747 && !o->style()->hasBackgroundImage();
749 // We do not use NSTextFieldCell to draw styled text fields on Lion and SnowLeopard because
750 // there are a number of bugs on those platforms that require NSTextFieldCell to be in charge
751 // of painting its own background. We need WebCore to paint styled backgrounds, so we'll use
752 // this AppKit SPI function instead.
753 if (!useNSTextFieldCell) {
754 _NSDrawCarbonThemeBezel(r, isEnabled(o) && !isReadOnlyControl(o), YES);
759 NSTextFieldCell *textField = this->textField();
761 GraphicsContextStateSaver stateSaver(*paintInfo.context);
763 [textField setEnabled:(isEnabled(o) && !isReadOnlyControl(o))];
764 [textField drawWithFrame:NSRect(r) inView:documentViewFor(o)];
766 [textField setControlView:nil];
771 bool RenderThemeChromiumMac::paintCapsLockIndicator(RenderObject*, const PaintInfo& paintInfo, const IntRect& r)
773 // This draws the caps lock indicator as it was done by WKDrawCapsLockIndicator.
774 LocalCurrentGraphicsContext localContext(paintInfo.context);
775 CGContextRef c = localContext.cgContext();
776 CGMutablePathRef shape = CGPathCreateMutable();
778 // To draw the caps lock indicator, draw the shape into a small
779 // square that is then scaled to the size of r.
780 const CGFloat kSquareSize = 17;
782 // Create a rounted square shape.
783 CGPathMoveToPoint(shape, NULL, 16.5, 4.5);
784 CGPathAddArc(shape, NULL, 12.5, 12.5, 4, 0, M_PI_2, false);
785 CGPathAddArc(shape, NULL, 4.5, 12.5, 4, M_PI_2, M_PI, false);
786 CGPathAddArc(shape, NULL, 4.5, 4.5, 4, M_PI, 3*M_PI/2, false);
787 CGPathAddArc(shape, NULL, 12.5, 4.5, 4, 3*M_PI/2, 0, false);
789 // Draw the arrow - note this is drawing in a flipped coordinate system, so the
790 // arrow is pointing down.
791 CGPathMoveToPoint(shape, NULL, 8.5, 2); // Tip point.
792 CGPathAddLineToPoint(shape, NULL, 4, 7);
793 CGPathAddLineToPoint(shape, NULL, 6.25, 7);
794 CGPathAddLineToPoint(shape, NULL, 6.25, 10.25);
795 CGPathAddLineToPoint(shape, NULL, 10.75, 10.25);
796 CGPathAddLineToPoint(shape, NULL, 10.75, 7);
797 CGPathAddLineToPoint(shape, NULL, 13, 7);
798 CGPathAddLineToPoint(shape, NULL, 8.5, 2);
800 // Draw the rectangle that underneath (or above in the flipped system) the arrow.
801 CGPathAddLineToPoint(shape, NULL, 10.75, 12);
802 CGPathAddLineToPoint(shape, NULL, 6.25, 12);
803 CGPathAddLineToPoint(shape, NULL, 6.25, 14.25);
804 CGPathAddLineToPoint(shape, NULL, 10.75, 14.25);
805 CGPathAddLineToPoint(shape, NULL, 10.75, 12);
807 // Scale and translate the shape.
809 CGFloat maxX = CGRectGetMaxX(cgr);
810 CGFloat minY = CGRectGetMinY(cgr);
811 CGFloat heightScale = r.height() / kSquareSize;
812 CGAffineTransform transform = CGAffineTransformMake(
813 heightScale, 0, // A B
814 0, heightScale, // C D
815 maxX - r.height(), minY); // Tx Ty
817 CGMutablePathRef paintPath = CGPathCreateMutable();
818 CGPathAddPath(paintPath, &transform, shape);
819 CGPathRelease(shape);
821 CGContextSetRGBFillColor(c, 0, 0, 0, 0.4);
822 CGContextBeginPath(c);
823 CGContextAddPath(c, paintPath);
824 CGContextFillPath(c);
825 CGPathRelease(paintPath);
830 bool RenderThemeChromiumMac::paintTextArea(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
832 LocalCurrentGraphicsContext localContext(paintInfo.context);
833 _NSDrawCarbonThemeListBox(r, isEnabled(o) && !isReadOnlyControl(o), YES, YES);
837 const int* RenderThemeChromiumMac::popupButtonMargins() const
839 static const int margins[3][4] =
845 return margins[[popupButton() controlSize]];
848 const IntSize* RenderThemeChromiumMac::popupButtonSizes() const
850 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
854 const int* RenderThemeChromiumMac::popupButtonPadding(NSControlSize size) const
856 static const int padding[3][4] =
862 return padding[size];
865 bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
867 LocalCurrentGraphicsContext localContext(paintInfo.context);
868 setPopupButtonCellState(o, r);
870 NSPopUpButtonCell* popupButton = this->popupButton();
872 float zoomLevel = o->style()->effectiveZoom();
873 IntSize size = popupButtonSizes()[[popupButton controlSize]];
874 size.setHeight(size.height() * zoomLevel);
875 size.setWidth(r.width());
877 // Now inflate it to account for the shadow.
878 IntRect inflatedRect = r;
879 if (r.width() >= minimumMenuListSize(o->style()))
880 inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(), zoomLevel);
882 GraphicsContextStateSaver stateSaver(*paintInfo.context);
884 // On Leopard, the cell will draw outside of the given rect, so we have to clip to the rect
885 paintInfo.context->clip(inflatedRect);
887 if (zoomLevel != 1.0f) {
888 inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
889 inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
890 paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
891 paintInfo.context->scale(zoomLevel, zoomLevel);
892 paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
895 NSView *view = documentViewFor(o);
896 [popupButton drawWithFrame:inflatedRect inView:view];
897 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
898 if (isFocused(o) && o->style()->outlineStyleIsAuto())
899 [popupButton _web_drawFocusRingWithFrame:inflatedRect inView:view];
901 [popupButton setControlView:nil];
906 IntSize RenderThemeChromiumMac::meterSizeForBounds(const RenderMeter* renderMeter, const IntRect& bounds) const
908 if (NoControlPart == renderMeter->style()->appearance())
909 return bounds.size();
911 NSLevelIndicatorCell* cell = levelIndicatorFor(renderMeter);
912 // Makes enough room for cell's intrinsic size.
913 NSSize cellSize = [cell cellSizeForBounds:IntRect(IntPoint(), bounds.size())];
914 return IntSize(bounds.width() < cellSize.width ? cellSize.width : bounds.width(),
915 bounds.height() < cellSize.height ? cellSize.height : bounds.height());
918 bool RenderThemeChromiumMac::paintMeter(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
920 if (!renderObject->isMeter())
923 LocalCurrentGraphicsContext localContext(paintInfo.context);
925 NSLevelIndicatorCell* cell = levelIndicatorFor(toRenderMeter(renderObject));
926 GraphicsContextStateSaver stateSaver(*paintInfo.context);
928 [cell drawWithFrame:rect inView:documentViewFor(renderObject)];
929 [cell setControlView:nil];
933 bool RenderThemeChromiumMac::supportsMeter(ControlPart part) const
936 case RelevancyLevelIndicatorPart:
937 case DiscreteCapacityLevelIndicatorPart:
938 case RatingLevelIndicatorPart:
940 case ContinuousCapacityLevelIndicatorPart:
947 NSLevelIndicatorStyle RenderThemeChromiumMac::levelIndicatorStyleFor(ControlPart part) const
950 case RelevancyLevelIndicatorPart:
951 return NSRelevancyLevelIndicatorStyle;
952 case DiscreteCapacityLevelIndicatorPart:
953 return NSDiscreteCapacityLevelIndicatorStyle;
954 case RatingLevelIndicatorPart:
955 return NSRatingLevelIndicatorStyle;
957 case ContinuousCapacityLevelIndicatorPart:
959 return NSContinuousCapacityLevelIndicatorStyle;
964 NSLevelIndicatorCell* RenderThemeChromiumMac::levelIndicatorFor(const RenderMeter* renderMeter) const
966 RenderStyle* style = renderMeter->style();
967 ASSERT(style->appearance() != NoControlPart);
969 if (!m_levelIndicator)
970 m_levelIndicator.adoptNS([[NSLevelIndicatorCell alloc] initWithLevelIndicatorStyle:NSContinuousCapacityLevelIndicatorStyle]);
971 NSLevelIndicatorCell* cell = m_levelIndicator.get();
973 HTMLMeterElement* element = renderMeter->meterElement();
974 double value = element->value();
976 // Because NSLevelIndicatorCell does not support optimum-in-the-middle type coloring,
977 // we explicitly control the color instead giving low and high value to NSLevelIndicatorCell as is.
978 switch (element->gaugeRegion()) {
979 case HTMLMeterElement::GaugeRegionOptimum:
980 // Make meter the green
981 [cell setWarningValue:value + 1];
982 [cell setCriticalValue:value + 2];
984 case HTMLMeterElement::GaugeRegionSuboptimal:
985 // Make the meter yellow
986 [cell setWarningValue:value - 1];
987 [cell setCriticalValue:value + 1];
989 case HTMLMeterElement::GaugeRegionEvenLessGood:
990 // Make the meter red
991 [cell setWarningValue:value - 2];
992 [cell setCriticalValue:value - 1];
996 [cell setLevelIndicatorStyle:levelIndicatorStyleFor(style->appearance())];
997 [cell setBaseWritingDirection:style->isLeftToRightDirection() ? NSWritingDirectionLeftToRight : NSWritingDirectionRightToLeft];
998 [cell setMinValue:element->min()];
999 [cell setMaxValue:element->max()];
1000 RetainPtr<NSNumber> valueObject = [NSNumber numberWithDouble:value];
1001 [cell setObjectValue:valueObject.get()];
1006 const IntSize* RenderThemeChromiumMac::progressBarSizes() const
1008 static const IntSize sizes[3] = { IntSize(0, 20), IntSize(0, 12), IntSize(0, 12) };
1012 const int* RenderThemeChromiumMac::progressBarMargins(NSControlSize controlSize) const
1014 static const int margins[3][4] =
1020 return margins[controlSize];
1023 int RenderThemeChromiumMac::minimumProgressBarHeight(RenderStyle* style) const
1025 return sizeForSystemFont(style, progressBarSizes()).height();
1028 double RenderThemeChromiumMac::animationRepeatIntervalForProgressBar(RenderProgress*) const
1030 return progressAnimationFrameRate;
1033 double RenderThemeChromiumMac::animationDurationForProgressBar(RenderProgress*) const
1035 return progressAnimationNumFrames * progressAnimationFrameRate;
1038 bool RenderThemeChromiumMac::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect)
1040 if (!renderObject->isProgress())
1043 float zoomLevel = renderObject->style()->effectiveZoom();
1044 int controlSize = controlSizeForFont(renderObject->style());
1045 IntSize size = progressBarSizes()[controlSize];
1046 size.setHeight(size.height() * zoomLevel);
1047 size.setWidth(rect.width());
1049 // Now inflate it to account for the shadow.
1050 IntRect inflatedRect = rect;
1051 if (rect.height() <= minimumProgressBarHeight(renderObject->style()))
1052 inflatedRect = inflateRect(inflatedRect, size, progressBarMargins(controlSize), zoomLevel);
1054 RenderProgress* renderProgress = toRenderProgress(renderObject);
1055 HIThemeTrackDrawInfo trackInfo;
1056 trackInfo.version = 0;
1057 if (controlSize == NSRegularControlSize)
1058 trackInfo.kind = renderProgress->position() < 0 ? kThemeLargeIndeterminateBar : kThemeLargeProgressBar;
1060 trackInfo.kind = renderProgress->position() < 0 ? kThemeMediumIndeterminateBar : kThemeMediumProgressBar;
1062 trackInfo.bounds = IntRect(IntPoint(), inflatedRect.size());
1064 trackInfo.max = std::numeric_limits<SInt32>::max();
1065 trackInfo.value = lround(renderProgress->position() * nextafter(trackInfo.max, 0));
1066 trackInfo.trackInfo.progress.phase = lround(renderProgress->animationProgress() * nextafter(progressAnimationNumFrames, 0));
1067 trackInfo.attributes = kThemeTrackHorizontal;
1068 trackInfo.enableState = isActive(renderObject) ? kThemeTrackActive : kThemeTrackInactive;
1069 trackInfo.reserved = 0;
1070 trackInfo.filler1 = 0;
1072 OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(inflatedRect.size());
1076 ContextContainer cgContextContainer(imageBuffer->context());
1077 CGContextRef cgContext = cgContextContainer.context();
1078 HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal);
1080 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1082 if (!renderProgress->style()->isLeftToRightDirection()) {
1083 paintInfo.context->translate(2 * inflatedRect.x() + inflatedRect.width(), 0);
1084 paintInfo.context->scale(-1, 1);
1087 paintInfo.context->drawImageBuffer(imageBuffer.get(),
1088 FloatRect(inflatedRect.location(), imageBuffer->size()));
1092 const float baseFontSize = 11.0f;
1093 const float baseArrowHeight = 4.0f;
1094 const float baseArrowWidth = 5.0f;
1095 const float baseSpaceBetweenArrows = 2.0f;
1096 const int arrowPaddingLeft = 6;
1097 const int arrowPaddingRight = 6;
1098 const int paddingBeforeSeparator = 4;
1099 const int baseBorderRadius = 5;
1100 const int styledPopupPaddingLeft = 8;
1101 const int styledPopupPaddingTop = 1;
1102 const int styledPopupPaddingBottom = 2;
1104 bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1106 IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
1107 r.y() + o->style()->borderTopWidth(),
1108 r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
1109 r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
1110 // 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
1111 float fontScale = std::min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
1112 float centerY = bounds.y() + bounds.height() / 2.0f;
1113 float arrowHeight = baseArrowHeight * fontScale;
1114 float arrowWidth = baseArrowWidth * fontScale;
1115 float leftEdge = bounds.maxX() - arrowPaddingRight * o->style()->effectiveZoom() - arrowWidth;
1116 float spaceBetweenArrows = baseSpaceBetweenArrows * fontScale;
1118 if (bounds.width() < arrowWidth + arrowPaddingLeft * o->style()->effectiveZoom())
1121 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1123 paintInfo.context->setFillColor(o->style()->visitedDependentColor(CSSPropertyColor));
1124 paintInfo.context->setStrokeStyle(NoStroke);
1126 FloatPoint arrow1[3];
1127 arrow1[0] = FloatPoint(leftEdge, centerY - spaceBetweenArrows / 2.0f);
1128 arrow1[1] = FloatPoint(leftEdge + arrowWidth, centerY - spaceBetweenArrows / 2.0f);
1129 arrow1[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY - spaceBetweenArrows / 2.0f - arrowHeight);
1131 // Draw the top arrow
1132 paintInfo.context->drawConvexPolygon(3, arrow1, true);
1134 FloatPoint arrow2[3];
1135 arrow2[0] = FloatPoint(leftEdge, centerY + spaceBetweenArrows / 2.0f);
1136 arrow2[1] = FloatPoint(leftEdge + arrowWidth, centerY + spaceBetweenArrows / 2.0f);
1137 arrow2[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + spaceBetweenArrows / 2.0f + arrowHeight);
1139 // Draw the bottom arrow
1140 paintInfo.context->drawConvexPolygon(3, arrow2, true);
1144 static const IntSize* menuListButtonSizes()
1146 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
1150 void RenderThemeChromiumMac::adjustMenuListStyle(RenderStyle* style, Element* e) const
1152 NSControlSize controlSize = controlSizeForFont(style);
1154 style->resetBorder();
1155 style->resetPadding();
1157 // Height is locked to auto.
1158 style->setHeight(Length(Auto));
1160 // White-space is locked to pre
1161 style->setWhiteSpace(PRE);
1163 // Set the foreground color to black or gray when we have the aqua look.
1164 // Cast to RGB32 is to work around a compiler bug.
1165 style->setColor(e && !e->isDisabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
1167 // Set the button's vertical size.
1168 setSizeFromFont(style, menuListButtonSizes());
1170 // 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
1171 // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
1172 // system font for the control size instead.
1173 setFontFromControlSize(style, controlSize);
1176 const int autofillPopupHorizontalPadding = 4;
1178 // These functions are called with MenuListPart or MenulistButtonPart appearance by RenderMenuList, or with TextFieldPart appearance by AutofillPopupMenuClient.
1179 // We assume only AutofillPopupMenuClient gives TexfieldPart appearance here.
1180 // We want to change only Autofill padding.
1181 // In the future, we have to separate Autofill popup window logic from WebKit to Chromium.
1182 int RenderThemeChromiumMac::popupInternalPaddingLeft(RenderStyle* style) const
1184 if (style->appearance() == TextFieldPart)
1185 return autofillPopupHorizontalPadding;
1187 if (style->appearance() == MenulistPart)
1188 return popupButtonPadding(controlSizeForFont(style))[leftPadding] * style->effectiveZoom();
1189 if (style->appearance() == MenulistButtonPart)
1190 return styledPopupPaddingLeft * style->effectiveZoom();
1194 int RenderThemeChromiumMac::popupInternalPaddingRight(RenderStyle* style) const
1196 if (style->appearance() == TextFieldPart)
1197 return autofillPopupHorizontalPadding;
1199 if (style->appearance() == MenulistPart)
1200 return popupButtonPadding(controlSizeForFont(style))[rightPadding] * style->effectiveZoom();
1201 if (style->appearance() == MenulistButtonPart) {
1202 float fontScale = style->fontSize() / baseFontSize;
1203 float arrowWidth = baseArrowWidth * fontScale;
1204 return static_cast<int>(ceilf(arrowWidth + (arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator) * style->effectiveZoom()));
1209 int RenderThemeChromiumMac::popupInternalPaddingTop(RenderStyle* style) const
1211 if (style->appearance() == MenulistPart)
1212 return popupButtonPadding(controlSizeForFont(style))[topPadding] * style->effectiveZoom();
1213 if (style->appearance() == MenulistButtonPart)
1214 return styledPopupPaddingTop * style->effectiveZoom();
1218 int RenderThemeChromiumMac::popupInternalPaddingBottom(RenderStyle* style) const
1220 if (style->appearance() == MenulistPart)
1221 return popupButtonPadding(controlSizeForFont(style))[bottomPadding] * style->effectiveZoom();
1222 if (style->appearance() == MenulistButtonPart)
1223 return styledPopupPaddingBottom * style->effectiveZoom();
1227 void RenderThemeChromiumMac::adjustMenuListButtonStyle(RenderStyle* style, Element*) const
1229 float fontScale = style->fontSize() / baseFontSize;
1231 style->resetPadding();
1232 style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
1234 const int minHeight = 15;
1235 style->setMinHeight(Length(minHeight, Fixed));
1237 style->setLineHeight(RenderStyle::initialLineHeight());
1240 void RenderThemeChromiumMac::setPopupButtonCellState(const RenderObject* o, const IntRect& r)
1242 NSPopUpButtonCell* popupButton = this->popupButton();
1244 // Set the control size based off the rectangle we're painting into.
1245 setControlSize(popupButton, popupButtonSizes(), r.size(), o->style()->effectiveZoom());
1247 // Update the various states we respond to.
1248 updateActiveState(popupButton, o);
1249 updateCheckedState(popupButton, o);
1250 updateEnabledState(popupButton, o);
1251 updatePressedState(popupButton, o);
1252 #if BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
1253 updateFocusedState(popupButton, o);
1257 const IntSize* RenderThemeChromiumMac::menuListSizes() const
1259 static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) };
1263 int RenderThemeChromiumMac::minimumMenuListSize(RenderStyle* style) const
1265 return sizeForSystemFont(style, menuListSizes()).width();
1268 const int sliderTrackWidth = 5;
1269 const int sliderTrackBorderWidth = 1;
1271 bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1273 paintSliderTicks(o, paintInfo, r);
1275 float zoomLevel = o->style()->effectiveZoom();
1276 FloatRect unzoomedRect = r;
1278 if (o->style()->appearance() == SliderHorizontalPart || o->style()->appearance() == MediaSliderPart) {
1279 unzoomedRect.setY(ceilf(unzoomedRect.y() + unzoomedRect.height() / 2 - zoomLevel * sliderTrackWidth / 2));
1280 unzoomedRect.setHeight(zoomLevel * sliderTrackWidth);
1281 } else if (o->style()->appearance() == SliderVerticalPart) {
1282 unzoomedRect.setX(ceilf(unzoomedRect.x() + unzoomedRect.width() / 2 - zoomLevel * sliderTrackWidth / 2));
1283 unzoomedRect.setWidth(zoomLevel * sliderTrackWidth);
1286 if (zoomLevel != 1) {
1287 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1288 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1291 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1292 if (zoomLevel != 1) {
1293 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1294 paintInfo.context->scale(zoomLevel, zoomLevel);
1295 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1298 Color fillColor(205, 205, 205);
1299 Color borderGradientTopColor(109, 109, 109);
1300 Color borderGradientBottomColor(181, 181, 181);
1301 Color shadowColor(0, 0, 0, 118);
1303 if (!isEnabled(o)) {
1304 Color tintColor(255, 255, 255, 128);
1305 fillColor = fillColor.blend(tintColor);
1306 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1307 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1308 shadowColor = shadowColor.blend(tintColor);
1313 tintColor = Color(255, 255, 255, 128);
1315 bool isVerticalSlider = o->style()->appearance() == SliderVerticalPart;
1317 int fillRadiusSize = (sliderTrackWidth - sliderTrackBorderWidth) / 2;
1318 IntSize fillRadius(fillRadiusSize, fillRadiusSize);
1319 IntRect fillBounds = enclosedIntRect(unzoomedRect);
1320 RoundedRect fillRect(fillBounds, fillRadius, fillRadius, fillRadius, fillRadius);
1321 paintInfo.context->fillRoundedRect(fillRect, fillColor);
1323 IntSize shadowOffset(isVerticalSlider ? 1 : 0,
1324 isVerticalSlider ? 0 : 1);
1326 int shadowSpread = 0;
1327 paintInfo.context->save();
1328 paintInfo.context->drawInnerShadow(fillRect, shadowColor, shadowOffset, shadowBlur, shadowSpread);
1329 paintInfo.context->restore();
1331 RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(),
1332 isVerticalSlider ? fillBounds.maxXMinYCorner() : fillBounds.minXMaxYCorner());
1333 borderGradient->addColorStop(0.0, borderGradientTopColor);
1334 borderGradient->addColorStop(1.0, borderGradientBottomColor);
1336 FloatRect borderRect(unzoomedRect);
1337 borderRect.inflate(-sliderTrackBorderWidth / 2.0);
1338 float borderRadiusSize = (isVerticalSlider ? borderRect.width() : borderRect.height()) / 2;
1339 FloatSize borderRadius(borderRadiusSize, borderRadiusSize);
1340 borderPath.addRoundedRect(borderRect, borderRadius, borderRadius, borderRadius, borderRadius);
1341 paintInfo.context->setStrokeGradient(borderGradient);
1342 paintInfo.context->setStrokeThickness(sliderTrackBorderWidth);
1343 paintInfo.context->strokePath(borderPath);
1347 const int sliderThumbWidth = 15;
1348 const int sliderThumbHeight = 15;
1349 const int sliderThumbBorderWidth = 1;
1351 bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1353 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1354 float zoomLevel = o->style()->effectiveZoom();
1356 FloatRect unzoomedRect(r.x(), r.y(), sliderThumbWidth, sliderThumbHeight);
1357 if (zoomLevel != 1.0f) {
1358 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1359 paintInfo.context->scale(zoomLevel, zoomLevel);
1360 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1363 Color fillGradientTopColor(250, 250, 250);
1364 Color fillGradientUpperMiddleColor(244, 244, 244);
1365 Color fillGradientLowerMiddleColor(236, 236, 236);
1366 Color fillGradientBottomColor(238, 238, 238);
1367 Color borderGradientTopColor(151, 151, 151);
1368 Color borderGradientBottomColor(128, 128, 128);
1369 Color shadowColor(0, 0, 0, 36);
1371 if (!isEnabled(o)) {
1372 Color tintColor(255, 255, 255, 128);
1373 fillGradientTopColor = fillGradientTopColor.blend(tintColor);
1374 fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
1375 fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
1376 fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
1377 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1378 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1379 shadowColor = shadowColor.blend(tintColor);
1380 } else if (isPressed(o)) {
1381 Color tintColor(0, 0, 0, 32);
1382 fillGradientTopColor = fillGradientTopColor.blend(tintColor);
1383 fillGradientUpperMiddleColor = fillGradientUpperMiddleColor.blend(tintColor);
1384 fillGradientLowerMiddleColor = fillGradientLowerMiddleColor.blend(tintColor);
1385 fillGradientBottomColor = fillGradientBottomColor.blend(tintColor);
1386 borderGradientTopColor = borderGradientTopColor.blend(tintColor);
1387 borderGradientBottomColor = borderGradientBottomColor.blend(tintColor);
1388 shadowColor = shadowColor.blend(tintColor);
1391 FloatRect borderBounds = unzoomedRect;
1392 borderBounds.inflate(sliderThumbBorderWidth / 2.0);
1394 borderBounds.inflate(-sliderThumbBorderWidth);
1395 FloatSize shadowOffset(0, 1);
1396 paintInfo.context->setShadow(shadowOffset, sliderThumbShadowBlur, shadowColor);
1397 paintInfo.context->setFillColor(Color::black);
1398 paintInfo.context->fillEllipse(borderBounds);
1399 paintInfo.context->clearShadow();
1401 IntRect fillBounds = enclosedIntRect(unzoomedRect);
1402 RefPtr<Gradient> fillGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
1403 fillGradient->addColorStop(0.0, fillGradientTopColor);
1404 fillGradient->addColorStop(0.52, fillGradientUpperMiddleColor);
1405 fillGradient->addColorStop(0.52, fillGradientLowerMiddleColor);
1406 fillGradient->addColorStop(1.0, fillGradientBottomColor);
1407 paintInfo.context->setFillGradient(fillGradient);
1408 paintInfo.context->fillEllipse(borderBounds);
1410 RefPtr<Gradient> borderGradient = Gradient::create(fillBounds.minXMinYCorner(), fillBounds.minXMaxYCorner());
1411 borderGradient->addColorStop(0.0, borderGradientTopColor);
1412 borderGradient->addColorStop(1.0, borderGradientBottomColor);
1413 paintInfo.context->setStrokeGradient(borderGradient);
1414 paintInfo.context->setStrokeThickness(sliderThumbBorderWidth);
1415 paintInfo.context->strokeEllipse(borderBounds);
1419 borderPath.addEllipse(borderBounds);
1420 paintInfo.context->drawFocusRing(borderPath, 5, -2, focusRingColor());
1426 bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1428 LocalCurrentGraphicsContext localContext(paintInfo.context);
1430 NSSearchFieldCell* search = this->search();
1431 setSearchCellState(o, r);
1432 [search setControlSize:searchFieldControlSizeForFont(o->style())];
1434 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1436 float zoomLevel = o->style()->effectiveZoom();
1438 IntRect unzoomedRect = r;
1440 if (zoomLevel != 1.0f) {
1441 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1442 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1443 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1444 paintInfo.context->scale(zoomLevel, zoomLevel);
1445 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1448 // Set the search button to nil before drawing. Then reset it so we can draw it later.
1449 [search setSearchButtonCell:nil];
1451 [search drawWithFrame:NSRect(unzoomedRect) inView:documentViewFor(o)];
1453 [search setControlView:nil];
1454 [search resetSearchButtonCell];
1459 void RenderThemeChromiumMac::setSearchCellState(RenderObject* o, const IntRect&)
1461 NSSearchFieldCell* search = this->search();
1463 // Update the various states we respond to.
1464 updateActiveState(search, o);
1465 updateEnabledState(search, o);
1466 updateFocusedState(search, o);
1469 const IntSize* RenderThemeChromiumMac::searchFieldSizes() const
1471 static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 15) };
1475 static const int* searchFieldHorizontalPaddings()
1477 static const int sizes[3] = { 3, 2, 1 };
1481 void RenderThemeChromiumMac::setSearchFieldSize(RenderStyle* style) const
1483 // If the width and height are both specified, then we have nothing to do.
1484 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
1487 // Use the font size to determine the intrinsic width of the control.
1488 setSizeFromFont(style, searchFieldSizes());
1491 const int searchFieldBorderWidth = 2;
1492 void RenderThemeChromiumMac::adjustSearchFieldStyle(RenderStyle* style, Element*) const
1495 style->resetBorder();
1496 const short borderWidth = searchFieldBorderWidth * style->effectiveZoom();
1497 style->setBorderLeftWidth(borderWidth);
1498 style->setBorderLeftStyle(INSET);
1499 style->setBorderRightWidth(borderWidth);
1500 style->setBorderRightStyle(INSET);
1501 style->setBorderBottomWidth(borderWidth);
1502 style->setBorderBottomStyle(INSET);
1503 style->setBorderTopWidth(borderWidth);
1504 style->setBorderTopStyle(INSET);
1507 style->setHeight(Length(Auto));
1508 setSearchFieldSize(style);
1510 NSControlSize controlSize = controlSizeForFont(style);
1512 // Override padding size to match AppKit text positioning.
1513 const int verticalPadding = 1 * style->effectiveZoom();
1514 const int horizontalPadding = searchFieldHorizontalPaddings()[controlSize] * style->effectiveZoom();
1515 style->setPaddingLeft(Length(horizontalPadding, Fixed));
1516 style->setPaddingRight(Length(horizontalPadding, Fixed));
1517 style->setPaddingTop(Length(verticalPadding, Fixed));
1518 style->setPaddingBottom(Length(verticalPadding, Fixed));
1520 setFontFromControlSize(style, controlSize);
1522 style->setBoxShadow(nullptr);
1525 bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1529 Element* input = o->node()->shadowHost();
1531 input = toElement(o->node());
1533 if (!input->renderer()->isBox())
1536 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1538 float zoomLevel = o->style()->effectiveZoom();
1539 FloatRect unzoomedRect(r);
1540 if (zoomLevel != 1.0f) {
1541 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1542 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1543 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1544 paintInfo.context->scale(zoomLevel, zoomLevel);
1545 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1548 Color fillColor(200, 200, 200);
1551 Color tintColor(0, 0, 0, 32);
1552 fillColor = fillColor.blend(tintColor);
1555 float centerX = unzoomedRect.x() + unzoomedRect.width() / 2;
1556 float centerY = unzoomedRect.y() + unzoomedRect.height() / 2;
1557 // The line width is 3px on a regular sized, high DPI NSCancelButtonCell
1558 // (which is 28px wide).
1559 float lineWidth = unzoomedRect.width() * 3 / 28;
1560 // The line length is 16px on a regular sized, high DPI NSCancelButtonCell.
1561 float lineLength = unzoomedRect.width() * 16 / 28;
1564 FloatSize lineRectRadius(lineWidth / 2, lineWidth / 2);
1565 xPath.addRoundedRect(FloatRect(-lineLength / 2, -lineWidth / 2, lineLength, lineWidth),
1566 lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
1567 xPath.addRoundedRect(FloatRect(-lineWidth / 2, -lineLength / 2, lineWidth, lineLength),
1568 lineRectRadius, lineRectRadius, lineRectRadius, lineRectRadius);
1570 paintInfo.context->translate(centerX, centerY);
1571 paintInfo.context->rotate(deg2rad(45.0));
1572 paintInfo.context->clipOut(xPath);
1573 paintInfo.context->rotate(deg2rad(-45.0));
1574 paintInfo.context->translate(-centerX, -centerY);
1576 paintInfo.context->setFillColor(fillColor);
1577 paintInfo.context->fillEllipse(unzoomedRect);
1582 const IntSize* RenderThemeChromiumMac::cancelButtonSizes() const
1584 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(11, 11), IntSize(9, 9) };
1588 void RenderThemeChromiumMac::adjustSearchFieldCancelButtonStyle(RenderStyle* style, Element*) const
1590 IntSize size = sizeForSystemFont(style, cancelButtonSizes());
1591 style->setWidth(Length(size.width(), Fixed));
1592 style->setHeight(Length(size.height(), Fixed));
1593 style->setBoxShadow(nullptr);
1596 const IntSize* RenderThemeChromiumMac::resultsButtonSizes() const
1598 static const IntSize sizes[3] = { IntSize(15, 14), IntSize(16, 13), IntSize(14, 11) };
1602 void RenderThemeChromiumMac::adjustSearchFieldDecorationStyle(RenderStyle* style, Element*) const
1604 NSControlSize controlSize = controlSizeForSystemFont(style);
1605 IntSize searchFieldSize = searchFieldSizes()[controlSize];
1606 int width = searchFieldSize.height() / 2 - searchFieldBorderWidth - searchFieldHorizontalPaddings()[controlSize];
1607 style->setWidth(Length(width, Fixed));
1608 style->setHeight(Length(0, Fixed));
1609 style->setBoxShadow(nullptr);
1612 bool RenderThemeChromiumMac::paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&)
1617 void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(RenderStyle* style, Element*) const
1619 IntSize size = sizeForSystemFont(style, resultsButtonSizes());
1620 style->setWidth(Length(size.width(), Fixed));
1621 style->setHeight(Length(size.height(), Fixed));
1622 style->setBoxShadow(nullptr);
1625 bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
1629 Node* input = o->node()->shadowHost();
1632 if (!input->renderer()->isBox())
1635 GraphicsContextStateSaver stateSaver(*paintInfo.context);
1637 float zoomLevel = o->style()->effectiveZoom();
1638 FloatRect unzoomedRect(r);
1639 if (zoomLevel != 1) {
1640 unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
1641 unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
1642 paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
1643 paintInfo.context->scale(zoomLevel, zoomLevel);
1644 paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
1647 LocalCurrentGraphicsContext localContext(paintInfo.context);
1649 NSSearchFieldCell* search = this->search();
1650 setSearchCellState(input->renderer(), r);
1651 [search setControlSize:searchFieldControlSizeForFont(o->style())];
1652 if ([search searchMenuTemplate] != nil)
1653 [search setSearchMenuTemplate:nil];
1655 updateActiveState([search searchButtonCell], o);
1657 [[search searchButtonCell] drawWithFrame:unzoomedRect inView:documentViewFor(o)];
1658 [[search searchButtonCell] setControlView:nil];
1662 IntSize RenderThemeChromiumMac::sliderTickSize() const
1664 return IntSize(1, 3);
1667 int RenderThemeChromiumMac::sliderTickOffsetFromTrackCenter() const
1672 void RenderThemeChromiumMac::adjustSliderThumbSize(RenderStyle* style, Element*) const
1674 float zoomLevel = style->effectiveZoom();
1675 if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
1676 style->setWidth(Length(static_cast<int>(sliderThumbWidth * zoomLevel), Fixed));
1677 style->setHeight(Length(static_cast<int>(sliderThumbHeight * zoomLevel), Fixed));
1680 adjustMediaSliderThumbSize(style);
1683 NSPopUpButtonCell* RenderThemeChromiumMac::popupButton() const
1685 if (!m_popupButton) {
1686 m_popupButton.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]);
1687 [m_popupButton.get() setUsesItemFromMenu:NO];
1688 [m_popupButton.get() setFocusRingType:NSFocusRingTypeExterior];
1691 return m_popupButton.get();
1694 NSSearchFieldCell* RenderThemeChromiumMac::search() const
1697 m_search.adoptNS([[NSSearchFieldCell alloc] initTextCell:@""]);
1698 [m_search.get() setBezelStyle:NSTextFieldRoundedBezel];
1699 [m_search.get() setBezeled:YES];
1700 [m_search.get() setEditable:YES];
1701 [m_search.get() setFocusRingType:NSFocusRingTypeExterior];
1702 SEL sel = @selector(setCenteredLook:);
1703 if ([m_search.get() respondsToSelector:sel]) {
1704 BOOL boolValue = NO;
1705 NSMethodSignature* signature = [NSSearchFieldCell instanceMethodSignatureForSelector:sel];
1706 NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
1707 [invocation setTarget:m_search.get()];
1708 [invocation setSelector:sel];
1709 [invocation setArgument:&boolValue atIndex:2];
1710 [invocation invoke];
1714 return m_search.get();
1717 NSMenu* RenderThemeChromiumMac::searchMenuTemplate() const
1719 if (!m_searchMenuTemplate)
1720 m_searchMenuTemplate.adoptNS([[NSMenu alloc] initWithTitle:@""]);
1722 return m_searchMenuTemplate.get();
1725 NSTextFieldCell* RenderThemeChromiumMac::textField() const
1728 m_textField.adoptNS([[WebCoreTextFieldCell alloc] initTextCell:@""]);
1729 [m_textField.get() setBezeled:YES];
1730 [m_textField.get() setEditable:YES];
1731 [m_textField.get() setFocusRingType:NSFocusRingTypeExterior];
1732 #if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
1733 [m_textField.get() setDrawsBackground:YES];
1734 [m_textField.get() setBackgroundColor:[NSColor whiteColor]];
1736 // Post-Lion, WebCore can be in charge of paintinng the background thanks to
1737 // the workaround in place for <rdar://problem/11385461>, which is implemented
1738 // above as _coreUIDrawOptionsWithFrame.
1739 [m_textField.get() setDrawsBackground:NO];
1743 return m_textField.get();
1746 String RenderThemeChromiumMac::fileListNameForWidth(Locale& locale, const FileList* fileList, const Font& font, int width) const
1751 String strToTruncate;
1752 if (fileList->isEmpty()) {
1753 strToTruncate = locale.queryString(WebLocalizedString::FileButtonNoFileSelectedLabel);
1754 } else if (fileList->length() == 1) {
1755 File* file = fileList->item(0);
1756 if (file->userVisibility() == File::IsUserVisible)
1757 strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(fileList->item(0)->path())];
1759 strToTruncate = file->name();
1761 // FIXME: Localization of fileList->length().
1762 return StringTruncator::rightTruncate(locale.queryString(WebLocalizedString::MultipleFileUploadText, String::number(fileList->length())), width, font);
1765 return StringTruncator::centerTruncate(strToTruncate, width, font);
1768 NSView* FlippedView()
1770 static NSView* view = [[RTCMFlippedView alloc] init];
1774 RenderTheme& RenderTheme::theme()
1776 DEFINE_STATIC_REF(RenderTheme, renderTheme, (RenderThemeChromiumMac::create()));
1777 return *renderTheme;
1780 PassRefPtr<RenderTheme> RenderThemeChromiumMac::create()
1782 return adoptRef(new RenderThemeChromiumMac);
1785 bool RenderThemeChromiumMac::usesTestModeFocusRingColor() const
1787 return LayoutTestSupport::isRunningLayoutTest();
1790 NSView* RenderThemeChromiumMac::documentViewFor(RenderObject*) const
1792 return FlippedView();
1795 // Updates the control tint (a.k.a. active state) of |cell| (from |o|).
1796 // In the Chromium port, the renderer runs as a background process and controls'
1797 // NSCell(s) lack a parent NSView. Therefore controls don't have their tint
1798 // color updated correctly when the application is activated/deactivated.
1799 // FocusController's setActive() is called when the application is
1800 // activated/deactivated, which causes a repaint at which time this code is
1802 // This function should be called before drawing any NSCell-derived controls,
1803 // unless you're sure it isn't needed.
1804 void RenderThemeChromiumMac::updateActiveState(NSCell* cell, const RenderObject* o)
1806 NSControlTint oldTint = [cell controlTint];
1807 NSControlTint tint = isActive(o) ? [NSColor currentControlTint] :
1808 static_cast<NSControlTint>(NSClearControlTint);
1810 if (tint != oldTint)
1811 [cell setControlTint:tint];
1814 bool RenderThemeChromiumMac::shouldShowPlaceholderWhenFocused() const
1819 void RenderThemeChromiumMac::adjustMediaSliderThumbSize(RenderStyle* style) const
1821 RenderMediaControls::adjustMediaSliderThumbSize(style);
1824 bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1826 return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);
1829 bool RenderThemeChromiumMac::paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1831 return RenderMediaControls::paintMediaControlsPart(MediaOverlayPlayButton, object, paintInfo, rect);
1834 bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1836 return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect);
1839 bool RenderThemeChromiumMac::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1841 return RenderMediaControls::paintMediaControlsPart(MediaSlider, object, paintInfo, rect);
1844 String RenderThemeChromiumMac::extraFullScreenStyleSheet()
1846 // FIXME: Chromium may wish to style its default media controls differently in fullscreen.
1850 String RenderThemeChromiumMac::extraDefaultStyleSheet()
1852 return RenderTheme::extraDefaultStyleSheet() +
1853 String(themeChromiumCss, sizeof(themeChromiumCss)) +
1854 String(themeInputMultipleFieldsCss, sizeof(themeInputMultipleFieldsCss)) +
1855 String(themeMacCss, sizeof(themeMacCss));
1858 bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1863 bool RenderThemeChromiumMac::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1865 return RenderMediaControls::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect);
1868 bool RenderThemeChromiumMac::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1870 return RenderMediaControls::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect);
1873 bool RenderThemeChromiumMac::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1875 return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect);
1878 String RenderThemeChromiumMac::formatMediaControlsTime(float time) const
1880 return RenderMediaControls::formatMediaControlsTime(time);
1883 String RenderThemeChromiumMac::formatMediaControlsCurrentTime(float currentTime, float duration) const
1885 return RenderMediaControls::formatMediaControlsCurrentTime(currentTime, duration);
1888 bool RenderThemeChromiumMac::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1890 return RenderMediaControls::paintMediaControlsPart(MediaEnterFullscreenButton, object, paintInfo, rect);
1893 bool RenderThemeChromiumMac::paintMediaToggleClosedCaptionsButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
1895 return RenderMediaControls::paintMediaControlsPart(MediaShowClosedCaptionsButton, object, paintInfo, rect);
1898 bool RenderThemeChromiumMac::shouldUseFallbackTheme(RenderStyle* style) const
1900 ControlPart part = style->appearance();
1901 if (part == CheckboxPart || part == RadioPart)
1902 return style->effectiveZoom() != 1;
1906 } // namespace blink