diff options
Diffstat (limited to 'WebCore/platform/chromium/ThemeChromiumMac.mm')
-rw-r--r-- | WebCore/platform/chromium/ThemeChromiumMac.mm | 844 |
1 files changed, 0 insertions, 844 deletions
diff --git a/WebCore/platform/chromium/ThemeChromiumMac.mm b/WebCore/platform/chromium/ThemeChromiumMac.mm deleted file mode 100644 index 5e457f3..0000000 --- a/WebCore/platform/chromium/ThemeChromiumMac.mm +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * Copyright (C) 2009 Google Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "ThemeChromiumMac.h" - -#import "BlockExceptions.h" -#import "GraphicsContext.h" -#import "LocalCurrentGraphicsContext.h" -#import "ScrollView.h" -#import "WebCoreSystemInterface.h" -#import <Carbon/Carbon.h> -#include <wtf/StdLibExtras.h> -#import <objc/runtime.h> - -using namespace std; - -// This file (and its associated .h file) is a clone of ThemeMac.mm. -// Because the original file is designed to run in-process inside a Cocoa view, -// we must maintain a fork. Please maintain this file by performing parallel -// changes to it. -// -// The only changes from ThemeMac should be: -// - The classname change from ThemeMac to ThemeChromiumMac. -// - The import of FlippedView() and its use as the parent view for cell -// rendering. -// - In updateStates() the code to update the cells' inactive state. -// - In paintButton() the code to save/restore the window's default button cell. -// - The Snow Leopard focus ring bug fix and its use around every call to -// -[NSButtonCell drawWithFrame:inView:]. -// -// For all other differences, if it was introduced in this file, then the -// maintainer forgot to include it in the list; otherwise it is an update that -// should have been applied to this file but was not. - -// FIXME: Default buttons really should be more like push buttons and not like buttons. - -// --- START fix for Snow Leopard focus ring bug --- - -// There is a bug in the Cocoa focus ring drawing code. The code calls +[NSView -// focusView] (to get the currently focused view) and then calls an NSRect- -// returning method on that view to obtain a clipping rect. However, if there is -// no focused view (as there won't be if the destination is a context), the rect -// returned from the method invocation on nil is garbage. -// -// The garbage fortunately does not clip the focus ring on Leopard, but -// unfortunately does so on Snow Leopard. Therefore, if a runtime test shows -// that focus ring drawing fails, we swizzle NSView to ensure it returns a valid -// view with a valid clipping rectangle. -// -// FIXME: After the referenced bug is fixed on all supported platforms, remove -// this code. -// -// References: -// <http://crbug.com/27493> -// <rdar://problem/7604051> (<http://openradar.appspot.com/7604051>) - -@interface TCMVisibleView : NSView - -@end - -@implementation TCMVisibleView - -- (struct CGRect)_focusRingVisibleRect -{ - return CGRectZero; -} - -- (id)_focusRingClipAncestor -{ - return self; -} - -@end - -@interface NSView (TCMInterposing) -+ (NSView *)TCMInterposing_focusView; -@end - -namespace FocusIndicationFix { - -bool currentOSHasSetFocusRingStyleInBitmapBug() -{ - UInt32 pixel = 0; - UInt32* pixelPlane = &pixel; - UInt32** pixelPlanes = &pixelPlane; - NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(UInt8**)pixelPlanes - pixelsWide:1 - pixelsHigh:1 - bitsPerSample:8 - samplesPerPixel:4 - hasAlpha:YES - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bitmapFormat:NSAlphaFirstBitmapFormat - bytesPerRow:4 - bitsPerPixel:32]; - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap]]; - NSSetFocusRingStyle(NSFocusRingOnly); - NSRectFill(NSMakeRect(0, 0, 1, 1)); - [NSGraphicsContext restoreGraphicsState]; - [bitmap release]; - - return !pixel; -} - -bool swizzleFocusView() -{ - if (!currentOSHasSetFocusRingStyleInBitmapBug()) - return false; - - Class nsview = [NSView class]; - Method m1 = class_getClassMethod(nsview, @selector(focusView)); - Method m2 = class_getClassMethod(nsview, @selector(TCMInterposing_focusView)); - if (m1 && m2) { - method_exchangeImplementations(m1, m2); - return true; - } - - return false; -} - -static bool interpose = false; - -// A class to restrict the amount of time spent messing with interposing. It -// only stacks one-deep. -class ScopedFixer { -public: - ScopedFixer() - { - static bool swizzled = swizzleFocusView(); - interpose = swizzled; - } - - ~ScopedFixer() - { - interpose = false; - } -}; - -} // namespace FocusIndicationFix - -@implementation NSView (TCMInterposing) - -+ (NSView *)TCMInterposing_focusView -{ - NSView *view = [self TCMInterposing_focusView]; // call original (was swizzled) - if (!view && FocusIndicationFix::interpose) { - static TCMVisibleView* fixedView = [[TCMVisibleView alloc] init]; - view = fixedView; - } - - return view; -} - -@end - -// --- END fix for Snow Leopard focus ring bug --- - -namespace WebCore { - -// Pick up utility function from RenderThemeChromiumMac. -extern NSView* FlippedView(); - -enum { - topMargin, - rightMargin, - bottomMargin, - leftMargin -}; - -Theme* platformTheme() -{ - DEFINE_STATIC_LOCAL(ThemeChromiumMac, themeMac, ()); - return &themeMac; -} - -// Helper functions used by a bunch of different control parts. - -static NSControlSize controlSizeForFont(const Font& font) -{ - int fontSize = font.pixelSize(); - if (fontSize >= 16) - return NSRegularControlSize; - if (fontSize >= 11) - return NSSmallControlSize; - return NSMiniControlSize; -} - -static LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) -{ - IntSize controlSize = sizes[nsControlSize]; - if (zoomFactor != 1.0f) - controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor); - LengthSize result = zoomedSize; - if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0) - result.setWidth(Length(controlSize.width(), Fixed)); - if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) - result.setHeight(Length(controlSize.height(), Fixed)); - return result; -} - -static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) -{ - return sizeFromNSControlSize(controlSizeForFont(font), zoomedSize, zoomFactor, sizes); -} - -static ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) -{ - if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) && - minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor)) - return NSRegularControlSize; - if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) && - minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor)) - return NSSmallControlSize; - return NSMiniControlSize; -} - -static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) -{ - ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor); - if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same. - [cell setControlSize:(NSControlSize)size]; -} - -static void updateStates(NSCell* cell, ControlStates states) -{ - // Hover state is not supported by Aqua. - - // Pressed state - bool oldPressed = [cell isHighlighted]; - bool pressed = states & PressedState; - if (pressed != oldPressed) - [cell setHighlighted:pressed]; - - // Enabled state - bool oldEnabled = [cell isEnabled]; - bool enabled = states & EnabledState; - if (enabled != oldEnabled) - [cell setEnabled:enabled]; - - // Focused state - bool oldFocused = [cell showsFirstResponder]; - bool focused = states & FocusState; - if (focused != oldFocused) - [cell setShowsFirstResponder:focused]; - - // Checked and Indeterminate - bool oldIndeterminate = [cell state] == NSMixedState; - bool indeterminate = (states & IndeterminateState); - bool checked = states & CheckedState; - bool oldChecked = [cell state] == NSOnState; - if (oldIndeterminate != indeterminate || checked != oldChecked) - [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)]; - - // Window Inactive state - NSControlTint oldTint = [cell controlTint]; - bool windowInactive = (states & WindowInactiveState); - NSControlTint tint = windowInactive ? static_cast<NSControlTint>(NSClearControlTint) - : [NSColor currentControlTint]; - if (tint != oldTint) - [cell setControlTint:tint]; -} - -static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states) -{ - if (states & ReadOnlyState) - return kThemeStateUnavailableInactive; - if (!(states & EnabledState)) - return kThemeStateUnavailableInactive; - - // Do not process PressedState if !EnabledState or ReadOnlyState. - if (states & PressedState) { - if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini) - return states & SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown; - return kThemeStatePressed; - } - return kThemeStateActive; -} - -static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor) -{ - // Only do the inflation if the available width/height are too small. Otherwise try to - // fit the glow/check space into the available box's width/height. - int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor); - int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor); - IntRect result(zoomedRect); - if (widthDelta < 0) { - result.setX(result.x() - margins[leftMargin] * zoomFactor); - result.setWidth(result.width() - widthDelta); - } - if (heightDelta < 0) { - result.setY(result.y() - margins[topMargin] * zoomFactor); - result.setHeight(result.height() - heightDelta); - } - return result; -} - -// Checkboxes - -static const IntSize* checkboxSizes() -{ - static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; - return sizes; -} - -static const int* checkboxMargins(NSControlSize controlSize) -{ - static const int margins[3][4] = - { - { 3, 4, 4, 2 }, - { 4, 3, 3, 3 }, - { 4, 3, 3, 3 }, - }; - return margins[controlSize]; -} - -static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) -{ - // If the width and height are both specified, then we have nothing to do. - if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) - return zoomedSize; - - // Use the font size to determine the intrinsic width of the control. - return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes()); -} - -static NSButtonCell *checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor) -{ - static NSButtonCell *checkboxCell; - if (!checkboxCell) { - checkboxCell = [[NSButtonCell alloc] init]; - [checkboxCell setButtonType:NSSwitchButton]; - [checkboxCell setTitle:nil]; - [checkboxCell setAllowsMixedState:YES]; - [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; - } - - // Set the control size based off the rectangle we're painting into. - setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor); - - // Update the various states we respond to. - updateStates(checkboxCell, states); - - return checkboxCell; -} - -// FIXME: Share more code with radio buttons. -static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS - - // Determine the width and height needed for the control and prepare the cell for painting. - NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor); - LocalCurrentGraphicsContext localContext(context); - - context->save(); - - NSControlSize controlSize = [checkboxCell controlSize]; - IntSize zoomedSize = checkboxSizes()[controlSize]; - zoomedSize.setWidth(zoomedSize.width() * zoomFactor); - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); - - if (zoomFactor != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomFactor); - inflatedRect.setHeight(inflatedRect.height() / zoomFactor); - context->translate(inflatedRect.x(), inflatedRect.y()); - context->scale(FloatSize(zoomFactor, zoomFactor)); - context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - { - FocusIndicationFix::ScopedFixer fix; - [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; - } - [checkboxCell setControlView:nil]; - - context->restore(); - - END_BLOCK_OBJC_EXCEPTIONS -} - -// Radio Buttons - -static const IntSize* radioSizes() -{ - static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; - return sizes; -} - -static const int* radioMargins(NSControlSize controlSize) -{ - static const int margins[3][4] = - { - { 2, 2, 4, 2 }, - { 3, 2, 3, 2 }, - { 1, 0, 2, 0 }, - }; - return margins[controlSize]; -} - -static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) -{ - // If the width and height are both specified, then we have nothing to do. - if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) - return zoomedSize; - - // Use the font size to determine the intrinsic width of the control. - return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes()); -} - -static NSButtonCell *radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor) -{ - static NSButtonCell *radioCell; - if (!radioCell) { - radioCell = [[NSButtonCell alloc] init]; - [radioCell setButtonType:NSRadioButton]; - [radioCell setTitle:nil]; - [radioCell setFocusRingType:NSFocusRingTypeExterior]; - } - - // Set the control size based off the rectangle we're painting into. - setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); - - // Update the various states we respond to. - updateStates(radioCell, states); - - return radioCell; -} - -static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) -{ - // Determine the width and height needed for the control and prepare the cell for painting. - NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor); - LocalCurrentGraphicsContext localContext(context); - - context->save(); - - NSControlSize controlSize = [radioCell controlSize]; - IntSize zoomedSize = radioSizes()[controlSize]; - zoomedSize.setWidth(zoomedSize.width() * zoomFactor); - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); - - if (zoomFactor != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomFactor); - inflatedRect.setHeight(inflatedRect.height() / zoomFactor); - context->translate(inflatedRect.x(), inflatedRect.y()); - context->scale(FloatSize(zoomFactor, zoomFactor)); - context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - - BEGIN_BLOCK_OBJC_EXCEPTIONS - { - FocusIndicationFix::ScopedFixer fix; - [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; - } - [radioCell setControlView:nil]; - END_BLOCK_OBJC_EXCEPTIONS - - context->restore(); -} - -// Buttons - -// Buttons really only constrain height. They respect width. -static const IntSize* buttonSizes() -{ - static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; - return sizes; -} - -#if ENABLE(DATALIST) -static const IntSize* listButtonSizes() -{ - static const IntSize sizes[3] = { IntSize(21, 21), IntSize(19, 18), IntSize(17, 16) }; - return sizes; -} -#endif - -static const int* buttonMargins(NSControlSize controlSize) -{ - static const int margins[3][4] = - { - { 4, 6, 7, 6 }, - { 4, 5, 6, 5 }, - { 0, 1, 1, 1 }, - }; - return margins[controlSize]; -} - -static void setupButtonCell(NSButtonCell *&buttonCell, ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) -{ - if (!buttonCell) { - buttonCell = [[NSButtonCell alloc] init]; - [buttonCell setTitle:nil]; - [buttonCell setButtonType:NSMomentaryPushInButton]; - if (states & DefaultState) - [buttonCell setKeyEquivalent:@"\r"]; - } - - // Set the control size based off the rectangle we're painting into. - const IntSize* sizes = buttonSizes(); -#if ENABLE(DATALIST) - if (part == ListButtonPart) { - [buttonCell setBezelStyle:NSRoundedDisclosureBezelStyle]; - sizes = listButtonSizes(); - } else -#endif - if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) { - // Use the square button - if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle) - [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle]; - } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle) - [buttonCell setBezelStyle:NSRoundedBezelStyle]; - - setControlSize(buttonCell, sizes, zoomedRect.size(), zoomFactor); - - // Update the various states we respond to. - updateStates(buttonCell, states); -} - -static NSButtonCell *button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) -{ - bool isDefault = states & DefaultState; - static NSButtonCell *cells[2]; - setupButtonCell(cells[isDefault], part, states, zoomedRect, zoomFactor); - return cells[isDefault]; -} - -static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS - - // Determine the width and height needed for the control and prepare the cell for painting. - NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); - LocalCurrentGraphicsContext localContext(context); - - NSControlSize controlSize = [buttonCell controlSize]; -#if ENABLE(DATALIST) - IntSize zoomedSize = (part == ListButtonPart ? listButtonSizes() : buttonSizes())[controlSize]; -#else - IntSize zoomedSize = buttonSizes()[controlSize]; -#endif - zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - IntRect inflatedRect = zoomedRect; - if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { - // Center the button within the available space. - if (inflatedRect.height() > zoomedSize.height()) { - inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2); - inflatedRect.setHeight(zoomedSize.height()); - } - - // Now inflate it to account for the shadow. - inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); - - if (zoomFactor != 1.0f) { - inflatedRect.setWidth(inflatedRect.width() / zoomFactor); - inflatedRect.setHeight(inflatedRect.height() / zoomFactor); - context->translate(inflatedRect.x(), inflatedRect.y()); - context->scale(FloatSize(zoomFactor, zoomFactor)); - context->translate(-inflatedRect.x(), -inflatedRect.y()); - } - } - - { - FocusIndicationFix::ScopedFixer fix; - [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; - } - [buttonCell setControlView:nil]; - - END_BLOCK_OBJC_EXCEPTIONS -} - -// Stepper - -static const IntSize* stepperSizes() -{ - static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) }; - return sizes; -} - -// We don't use controlSizeForFont() for steppers because the stepper height -// should be equal to or less than the corresponding text field height, -static NSControlSize stepperControlSizeForFont(const Font& font) -{ - int fontSize = font.pixelSize(); - if (fontSize >= 18) - return NSRegularControlSize; - if (fontSize >= 13) - return NSSmallControlSize; - return NSMiniControlSize; -} - -static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView*) -{ - // We don't use NSStepperCell because there are no ways to draw an - // NSStepperCell with the up button highlighted. - - HIThemeButtonDrawInfo drawInfo; - drawInfo.version = 0; - drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, states); - drawInfo.adornment = kThemeAdornmentDefault; - ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); - if (controlSize == NSSmallControlSize) - drawInfo.kind = kThemeIncDecButtonSmall; - else if (controlSize == NSMiniControlSize) - drawInfo.kind = kThemeIncDecButtonMini; - else - drawInfo.kind = kThemeIncDecButton; - - IntRect rect(zoomedRect); - context->save(); - if (zoomFactor != 1.0f) { - rect.setWidth(rect.width() / zoomFactor); - rect.setHeight(rect.height() / zoomFactor); - context->translate(rect.x(), rect.y()); - context->scale(FloatSize(zoomFactor, zoomFactor)); - context->translate(-rect.x(), -rect.y()); - } - CGRect bounds(rect); - // Adjust 'bounds' so that HIThemeDrawButton(bounds,...) draws exactly on 'rect'. - CGRect backgroundBounds; - HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds); - if (bounds.origin.x != backgroundBounds.origin.x) - bounds.origin.x += bounds.origin.x - backgroundBounds.origin.x; - if (bounds.origin.y != backgroundBounds.origin.y) - bounds.origin.y += bounds.origin.y - backgroundBounds.origin.y; - HIThemeDrawButton(&bounds, &drawInfo, context->platformContext(), kHIThemeOrientationNormal, 0); - context->restore(); -} - -// Theme overrides - -int ThemeChromiumMac::baselinePositionAdjustment(ControlPart part) const -{ - if (part == CheckboxPart || part == RadioPart) - return -2; - return Theme::baselinePositionAdjustment(part); -} - -FontDescription ThemeChromiumMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const -{ - switch (part) { - case PushButtonPart: { - FontDescription fontDescription; - fontDescription.setIsAbsoluteSize(true); - fontDescription.setGenericFamily(FontDescription::SerifFamily); - - NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]]; - fontDescription.firstFamily().setFamily([nsFont familyName]); - fontDescription.setComputedSize([nsFont pointSize] * zoomFactor); - fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor); - return fontDescription; - } - default: - return Theme::controlFont(part, font, zoomFactor); - } -} - -LengthSize ThemeChromiumMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const -{ - switch (part) { - case CheckboxPart: - return checkboxSize(font, zoomedSize, zoomFactor); - case RadioPart: - return radioSize(font, zoomedSize, zoomFactor); - case PushButtonPart: - // Height is reset to auto so that specified heights can be ignored. - return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes()); -#if ENABLE(DATALIST) - case ListButtonPart: - return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes()); -#endif - case InnerSpinButtonPart: - // We don't use inner spin buttons on Mac. - return LengthSize(Length(Fixed), Length(Fixed)); - case OuterSpinButtonPart: - if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) - return zoomedSize; - return sizeFromNSControlSize(stepperControlSizeForFont(font), zoomedSize, zoomFactor, stepperSizes()); - default: - return zoomedSize; - } -} - -LengthSize ThemeChromiumMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const -{ - switch (part) { - case SquareButtonPart: - case DefaultButtonPart: - case ButtonPart: - case ListButtonPart: - return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed)); - case InnerSpinButtonPart: - // We don't use inner spin buttons on Mac. - return LengthSize(Length(Fixed), Length(Fixed)); - case OuterSpinButtonPart: { - IntSize base = stepperSizes()[NSMiniControlSize]; - return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed), - Length(static_cast<int>(base.height() * zoomFactor), Fixed)); - } - default: - return Theme::minimumControlSize(part, font, zoomFactor); - } -} - -LengthBox ThemeChromiumMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const -{ - switch (part) { - case SquareButtonPart: - case DefaultButtonPart: - case ButtonPart: - case ListButtonPart: - return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value()); - default: - return Theme::controlBorder(part, font, zoomedBox, zoomFactor); - } -} - -LengthBox ThemeChromiumMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const -{ - switch (part) { - case PushButtonPart: { - // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large - // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is - // by definition constrained, since we select mini only for small cramped environments. - // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent - // padding. - const int padding = 8 * zoomFactor; - return LengthBox(0, padding, 0, padding); - } - default: - return Theme::controlPadding(part, font, zoomedBox, zoomFactor); - } -} - -void ThemeChromiumMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS - switch (part) { - case CheckboxPart: { - // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox - // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. - NSCell *cell = checkbox(states, zoomedRect, zoomFactor); - NSControlSize controlSize = [cell controlSize]; - IntSize zoomedSize = checkboxSizes()[controlSize]; - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - zoomedSize.setWidth(zoomedSize.width() * zoomFactor); - zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); - break; - } - case RadioPart: { - // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button - // shadow". We don't consider this part of the bounds of the control in WebKit. - NSCell *cell = radio(states, zoomedRect, zoomFactor); - NSControlSize controlSize = [cell controlSize]; - IntSize zoomedSize = radioSizes()[controlSize]; - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - zoomedSize.setWidth(zoomedSize.width() * zoomFactor); - zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); - break; - } - case PushButtonPart: - case DefaultButtonPart: - case ButtonPart: { - NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor); - NSControlSize controlSize = [cell controlSize]; - - // We inflate the rect as needed to account for the Aqua button's shadow. - if ([cell bezelStyle] == NSRoundedBezelStyle) { - IntSize zoomedSize = buttonSizes()[controlSize]; - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. - zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); - } - break; - } - case OuterSpinButtonPart: { - static const int stepperMargin[4] = { 0, 0, 0, 0 }; - ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); - IntSize zoomedSize = stepperSizes()[controlSize]; - zoomedSize.setHeight(zoomedSize.height() * zoomFactor); - zoomedSize.setWidth(zoomedSize.width() * zoomFactor); - zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor); - break; - } - default: - break; - } - END_BLOCK_OBJC_EXCEPTIONS -} - -void ThemeChromiumMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const -{ - switch (part) { - case CheckboxPart: - paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView); - break; - case RadioPart: - paintRadio(states, context, zoomedRect, zoomFactor, scrollView); - break; - case PushButtonPart: - case DefaultButtonPart: - case ButtonPart: - case SquareButtonPart: - case ListButtonPart: - paintButton(part, states, context, zoomedRect, zoomFactor, scrollView); - break; - case OuterSpinButtonPart: - paintStepper(states, context, zoomedRect, zoomFactor, scrollView); - break; - default: - break; - } -} - -} |