2
* Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#include "ScrollbarThemeMac.h"
29
#include "ImageBuffer.h"
30
#include "GraphicsLayer.h"
31
#include "LocalCurrentGraphicsContext.h"
32
#include "NSScrollerImpDetails.h"
33
#include "PlatformMouseEvent.h"
34
#include "ScrollAnimatorMac.h"
35
#include "ScrollView.h"
36
#include "WebCoreSystemInterface.h"
37
#include <Carbon/Carbon.h>
38
#include <wtf/HashMap.h>
39
#include <wtf/StdLibExtras.h>
40
#include <wtf/TemporaryChange.h>
41
#include <wtf/UnusedParam.h>
43
// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow.
46
using namespace WebCore;
48
@interface NSColor (WebNSColorDetails)
49
+ (NSImage *)_linenPatternImage;
54
typedef HashMap<ScrollbarThemeClient*, RetainPtr<ScrollbarPainter> > ScrollbarPainterMap;
56
static ScrollbarPainterMap* scrollbarMap()
58
static ScrollbarPainterMap* map = new ScrollbarPainterMap;
64
@interface WebScrollbarPrefsObserver : NSObject
68
+ (void)registerAsObserver;
69
+ (void)appearancePrefsChanged:(NSNotification*)theNotification;
70
+ (void)behaviorPrefsChanged:(NSNotification*)theNotification;
74
@implementation WebScrollbarPrefsObserver
76
+ (void)appearancePrefsChanged:(NSNotification*)unusedNotification
78
UNUSED_PARAM(unusedNotification);
80
ScrollbarTheme* theme = ScrollbarTheme::theme();
81
if (theme->isMockTheme())
84
static_cast<ScrollbarThemeMac*>(ScrollbarTheme::theme())->preferencesChanged();
85
if (scrollbarMap()->isEmpty())
87
ScrollbarPainterMap::iterator end = scrollbarMap()->end();
88
for (ScrollbarPainterMap::iterator it = scrollbarMap()->begin(); it != end; ++it) {
89
it->key->styleChanged();
90
it->key->invalidate();
94
+ (void)behaviorPrefsChanged:(NSNotification*)unusedNotification
96
UNUSED_PARAM(unusedNotification);
98
ScrollbarTheme* theme = ScrollbarTheme::theme();
99
if (theme->isMockTheme())
102
static_cast<ScrollbarThemeMac*>(ScrollbarTheme::theme())->preferencesChanged();
105
+ (void)registerAsObserver
107
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(appearancePrefsChanged:) name:@"AppleAquaScrollBarVariantChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];
108
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(behaviorPrefsChanged:) name:@"AppleNoRedisplayAppearancePreferenceChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce];
115
#if !PLATFORM(CHROMIUM)
116
ScrollbarTheme* ScrollbarTheme::nativeTheme()
118
DEFINE_STATIC_LOCAL(ScrollbarThemeMac, theme, ());
123
// FIXME: Get these numbers from CoreUI.
124
static int cRealButtonLength[] = { 28, 21 };
125
static int cButtonHitInset[] = { 3, 2 };
126
// cRealButtonLength - cButtonInset
127
static int cButtonLength[] = { 14, 10 };
128
static int cScrollbarThickness[] = { 15, 11 };
129
static int cButtonInset[] = { 14, 11 };
130
static int cThumbMinLength[] = { 26, 20 };
132
static int cOuterButtonLength[] = { 16, 14 }; // The outer button in a double button pair is a bit bigger.
133
static int cOuterButtonOverlap = 2;
135
static float gInitialButtonDelay = 0.5f;
136
static float gAutoscrollButtonDelay = 0.05f;
137
static bool gJumpOnTrackClick = false;
139
static ScrollbarButtonsPlacement gButtonPlacement = ScrollbarButtonsDoubleEnd;
141
static bool supportsExpandedScrollbars()
143
// FIXME: This is temporary until all platforms that support ScrollbarPainter support this part of the API.
144
static bool globalSupportsExpandedScrollbars = [NSClassFromString(@"NSScrollerImp") instancesRespondToSelector:@selector(setExpanded:)];
145
return globalSupportsExpandedScrollbars;
148
static void updateArrowPlacement()
150
if (isScrollbarOverlayAPIAvailable())
153
NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"];
154
if ([buttonPlacement isEqualToString:@"Single"])
155
gButtonPlacement = ScrollbarButtonsSingle;
156
else if ([buttonPlacement isEqualToString:@"DoubleMin"])
157
gButtonPlacement = ScrollbarButtonsDoubleStart;
158
else if ([buttonPlacement isEqualToString:@"DoubleBoth"])
159
gButtonPlacement = ScrollbarButtonsDoubleBoth;
162
gButtonPlacement = ScrollbarButtonsDoubleEnd;
166
void ScrollbarThemeMac::registerScrollbar(ScrollbarThemeClient* scrollbar)
168
if (isScrollbarOverlayAPIAvailable()) {
169
bool isHorizontal = scrollbar->orientation() == HorizontalScrollbar;
170
ScrollbarPainter scrollbarPainter = [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:recommendedScrollerStyle() controlSize:(NSControlSize)scrollbar->controlSize() horizontal:isHorizontal replacingScrollerImp:nil];
171
scrollbarMap()->add(scrollbar, scrollbarPainter);
172
updateEnabledState(scrollbar);
173
updateScrollbarOverlayStyle(scrollbar);
175
scrollbarMap()->add(scrollbar, nil);
179
void ScrollbarThemeMac::unregisterScrollbar(ScrollbarThemeClient* scrollbar)
181
scrollbarMap()->remove(scrollbar);
184
void ScrollbarThemeMac::setNewPainterForScrollbar(ScrollbarThemeClient* scrollbar, ScrollbarPainter newPainter)
186
scrollbarMap()->set(scrollbar, newPainter);
187
updateEnabledState(scrollbar);
188
updateScrollbarOverlayStyle(scrollbar);
191
ScrollbarPainter ScrollbarThemeMac::painterForScrollbar(ScrollbarThemeClient* scrollbar)
193
return scrollbarMap()->get(scrollbar).get();
196
static bool g_isCurrentlyDrawingIntoLayer;
198
bool ScrollbarThemeMac::isCurrentlyDrawingIntoLayer()
200
return g_isCurrentlyDrawingIntoLayer;
203
void ScrollbarThemeMac::setIsCurrentlyDrawingIntoLayer(bool b)
205
g_isCurrentlyDrawingIntoLayer = b;
208
ScrollbarThemeMac::ScrollbarThemeMac()
210
static bool initialized;
213
gButtonPlacement = isScrollbarOverlayAPIAvailable() ? ScrollbarButtonsNone : ScrollbarButtonsDoubleEnd;
214
[WebScrollbarPrefsObserver registerAsObserver];
215
preferencesChanged();
219
ScrollbarThemeMac::~ScrollbarThemeMac()
223
void ScrollbarThemeMac::preferencesChanged()
225
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
226
[defaults synchronize];
227
updateArrowPlacement();
228
gInitialButtonDelay = [defaults floatForKey:@"NSScrollerButtonDelay"];
229
gAutoscrollButtonDelay = [defaults floatForKey:@"NSScrollerButtonPeriod"];
230
gJumpOnTrackClick = [defaults boolForKey:@"AppleScrollerPagingBehavior"];
233
int ScrollbarThemeMac::scrollbarThickness(ScrollbarControlSize controlSize)
235
if (isScrollbarOverlayAPIAvailable()) {
236
ScrollbarPainter scrollbarPainter = [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:recommendedScrollerStyle() controlSize:controlSize horizontal:NO replacingScrollerImp:nil];
237
if (supportsExpandedScrollbars())
238
[scrollbarPainter setExpanded:YES];
239
return [scrollbarPainter trackBoxWidth];
241
return cScrollbarThickness[controlSize];
244
bool ScrollbarThemeMac::usesOverlayScrollbars() const
246
if (isScrollbarOverlayAPIAvailable())
247
return recommendedScrollerStyle() == NSScrollerStyleOverlay;
252
void ScrollbarThemeMac::updateScrollbarOverlayStyle(ScrollbarThemeClient* scrollbar)
254
ScrollbarPainter painter = painterForScrollbar(scrollbar);
255
switch (scrollbar->scrollbarOverlayStyle()) {
256
case ScrollbarOverlayStyleDefault:
257
[painter setKnobStyle:NSScrollerKnobStyleDefault];
259
case ScrollbarOverlayStyleDark:
260
[painter setKnobStyle:NSScrollerKnobStyleDark];
262
case ScrollbarOverlayStyleLight:
263
[painter setKnobStyle:NSScrollerKnobStyleLight];
268
double ScrollbarThemeMac::initialAutoscrollTimerDelay()
270
return gInitialButtonDelay;
273
double ScrollbarThemeMac::autoscrollTimerDelay()
275
return gAutoscrollButtonDelay;
278
ScrollbarButtonsPlacement ScrollbarThemeMac::buttonsPlacement() const
280
return gButtonPlacement;
283
bool ScrollbarThemeMac::hasButtons(ScrollbarThemeClient* scrollbar)
285
return scrollbar->enabled() && buttonsPlacement() != ScrollbarButtonsNone
286
&& (scrollbar->orientation() == HorizontalScrollbar
288
: scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]);
291
bool ScrollbarThemeMac::hasThumb(ScrollbarThemeClient* scrollbar)
293
int minLengthForThumb;
294
if (isScrollbarOverlayAPIAvailable()) {
295
ScrollbarPainter painter = scrollbarMap()->get(scrollbar).get();
296
minLengthForThumb = [painter knobMinLength] + [painter trackOverlapEndInset] + [painter knobOverlapEndInset]
297
+ 2 * ([painter trackEndInset] + [painter knobEndInset]);
299
minLengthForThumb = 2 * cButtonInset[scrollbar->controlSize()] + cThumbMinLength[scrollbar->controlSize()] + 1;
300
return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ?
302
scrollbar->height()) >= minLengthForThumb;
305
static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start)
307
ASSERT(gButtonPlacement != ScrollbarButtonsNone);
309
IntRect paintRect(buttonRect);
310
if (orientation == HorizontalScrollbar) {
311
paintRect.setWidth(cRealButtonLength[controlSize]);
313
paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width()));
315
paintRect.setHeight(cRealButtonLength[controlSize]);
317
paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height()));
323
IntRect ScrollbarThemeMac::backButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool painting)
327
if (part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd))
330
if (part == BackButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsSingle))
333
int thickness = scrollbarThickness(scrollbar->controlSize());
334
bool outerButton = part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsDoubleBoth);
336
if (scrollbar->orientation() == HorizontalScrollbar)
337
result = IntRect(scrollbar->x(), scrollbar->y(), cOuterButtonLength[scrollbar->controlSize()] + (painting ? cOuterButtonOverlap : 0), thickness);
339
result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cOuterButtonLength[scrollbar->controlSize()] + (painting ? cOuterButtonOverlap : 0));
343
// Our repaint rect is slightly larger, since we are a button that is adjacent to the track.
344
if (scrollbar->orientation() == HorizontalScrollbar) {
345
int start = part == BackButtonStartPart ? scrollbar->x() : scrollbar->x() + scrollbar->width() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()];
346
result = IntRect(start, scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness);
348
int start = part == BackButtonStartPart ? scrollbar->y() : scrollbar->y() + scrollbar->height() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()];
349
result = IntRect(scrollbar->x(), start, thickness, cButtonLength[scrollbar->controlSize()]);
353
return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == BackButtonStartPart);
357
IntRect ScrollbarThemeMac::forwardButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool painting)
361
if (part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart))
364
if (part == ForwardButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsSingle))
367
int thickness = scrollbarThickness(scrollbar->controlSize());
368
int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()];
369
int buttonLength = cButtonLength[scrollbar->controlSize()];
371
bool outerButton = part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsDoubleBoth);
373
if (scrollbar->orientation() == HorizontalScrollbar) {
374
result = IntRect(scrollbar->x() + scrollbar->width() - outerButtonLength, scrollbar->y(), outerButtonLength, thickness);
376
result.inflateX(cOuterButtonOverlap);
378
result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - outerButtonLength, thickness, outerButtonLength);
380
result.inflateY(cOuterButtonOverlap);
385
if (scrollbar->orientation() == HorizontalScrollbar) {
386
int start = part == ForwardButtonEndPart ? scrollbar->x() + scrollbar->width() - buttonLength : scrollbar->x() + outerButtonLength;
387
result = IntRect(start, scrollbar->y(), buttonLength, thickness);
389
int start = part == ForwardButtonEndPart ? scrollbar->y() + scrollbar->height() - buttonLength : scrollbar->y() + outerButtonLength;
390
result = IntRect(scrollbar->x(), start, thickness, buttonLength);
393
return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == ForwardButtonStartPart);
397
IntRect ScrollbarThemeMac::trackRect(ScrollbarThemeClient* scrollbar, bool painting)
399
if (painting || !hasButtons(scrollbar))
400
return scrollbar->frameRect();
403
int thickness = scrollbarThickness(scrollbar->controlSize());
406
int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()];
407
int buttonLength = cButtonLength[scrollbar->controlSize()];
408
int doubleButtonLength = outerButtonLength + buttonLength;
409
switch (buttonsPlacement()) {
410
case ScrollbarButtonsSingle:
411
startWidth = buttonLength;
412
endWidth = buttonLength;
414
case ScrollbarButtonsDoubleStart:
415
startWidth = doubleButtonLength;
417
case ScrollbarButtonsDoubleEnd:
418
endWidth = doubleButtonLength;
420
case ScrollbarButtonsDoubleBoth:
421
startWidth = doubleButtonLength;
422
endWidth = doubleButtonLength;
428
int totalWidth = startWidth + endWidth;
429
if (scrollbar->orientation() == HorizontalScrollbar)
430
return IntRect(scrollbar->x() + startWidth, scrollbar->y(), scrollbar->width() - totalWidth, thickness);
431
return IntRect(scrollbar->x(), scrollbar->y() + startWidth, thickness, scrollbar->height() - totalWidth);
434
int ScrollbarThemeMac::minimumThumbLength(ScrollbarThemeClient* scrollbar)
436
if (isScrollbarOverlayAPIAvailable())
437
return [scrollbarMap()->get(scrollbar).get() knobMinLength];
439
return cThumbMinLength[scrollbar->controlSize()];
442
bool ScrollbarThemeMac::shouldCenterOnThumb(ScrollbarThemeClient*, const PlatformMouseEvent& evt)
444
if (evt.button() != LeftButton)
446
if (gJumpOnTrackClick)
447
return !evt.altKey();
451
bool ScrollbarThemeMac::shouldDragDocumentInsteadOfThumb(ScrollbarThemeClient*, const PlatformMouseEvent& event)
453
return event.altKey();
456
int ScrollbarThemeMac::scrollbarPartToHIPressedState(ScrollbarPart part)
459
case BackButtonStartPart:
460
return kThemeTopOutsideArrowPressed;
461
case BackButtonEndPart:
462
return kThemeTopOutsideArrowPressed; // This does not make much sense. For some reason the outside constant is required.
463
case ForwardButtonStartPart:
464
return kThemeTopInsideArrowPressed;
465
case ForwardButtonEndPart:
466
return kThemeBottomOutsideArrowPressed;
468
return kThemeThumbPressed;
474
void ScrollbarThemeMac::updateEnabledState(ScrollbarThemeClient* scrollbar)
476
if (isScrollbarOverlayAPIAvailable())
477
[scrollbarMap()->get(scrollbar).get() setEnabled:scrollbar->enabled()];
480
#if !PLATFORM(CHROMIUM)
481
static void scrollbarPainterPaint(ScrollbarPainter scrollbarPainter, bool enabled, double value, CGFloat proportion, CGRect frameRect)
483
[scrollbarPainter setEnabled:enabled];
484
[scrollbarPainter setBoundsSize: NSSizeFromCGSize(frameRect.size)];
485
[scrollbarPainter setDoubleValue:value];
486
[scrollbarPainter setKnobProportion:proportion];
488
// Use rectForPart: here; it will take the expansion transition progress into account.
489
NSRect trackRect = [scrollbarPainter rectForPart:NSScrollerKnobSlot];
490
[scrollbarPainter drawKnobSlotInRect:trackRect highlight:NO];
492
// If the scrollbar is not enabled, then there is nothing to scroll to, and we shouldn't
495
[scrollbarPainter drawKnob];
498
bool ScrollbarThemeMac::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* context, const IntRect& damageRect)
500
if (isScrollbarOverlayAPIAvailable()) {
504
if (scrollbar->currentPos() < 0) {
505
// Scrolled past the top.
507
overhang = -scrollbar->currentPos();
508
} else if (scrollbar->visibleSize() + scrollbar->currentPos() > scrollbar->totalSize()) {
509
// Scrolled past the bottom.
511
overhang = scrollbar->currentPos() + scrollbar->visibleSize() - scrollbar->totalSize();
513
// Within the bounds of the scrollable area.
514
int maximum = scrollbar->maximum();
516
value = scrollbar->currentPos() / maximum;
521
TemporaryChange<bool> isCurrentlyDrawingIntoLayer(g_isCurrentlyDrawingIntoLayer, context->isCALayerContext());
523
GraphicsContextStateSaver stateSaver(*context);
524
context->clip(damageRect);
525
context->translate(scrollbar->frameRect().x(), scrollbar->frameRect().y());
526
LocalCurrentGraphicsContext localContext(context);
527
scrollbarPainterPaint(scrollbarMap()->get(scrollbar).get(),
528
scrollbar->enabled(),
530
(static_cast<CGFloat>(scrollbar->visibleSize()) - overhang) / scrollbar->totalSize(),
531
scrollbar->frameRect());
536
HIThemeTrackDrawInfo trackInfo;
537
trackInfo.version = 0;
538
trackInfo.kind = scrollbar->controlSize() == RegularScrollbar ? kThemeMediumScrollBar : kThemeSmallScrollBar;
539
trackInfo.bounds = scrollbar->frameRect();
541
float maximum = 0.0f;
542
float position = 0.0f;
543
if (scrollbar->currentPos() < 0) {
544
// Scrolled past the top.
545
maximum = (scrollbar->totalSize() - scrollbar->currentPos()) - scrollbar->visibleSize();
547
} else if (scrollbar->visibleSize() + scrollbar->currentPos() > scrollbar->totalSize()) {
548
// Scrolled past the bottom.
549
maximum = scrollbar->currentPos();
552
// Within the bounds of the scrollable area.
553
maximum = scrollbar->maximum();
554
position = scrollbar->currentPos();
558
trackInfo.max = static_cast<int>(maximum);
559
trackInfo.value = static_cast<int>(position);
561
trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize();
562
trackInfo.attributes = 0;
563
if (scrollbar->orientation() == HorizontalScrollbar)
564
trackInfo.attributes |= kThemeTrackHorizontal;
566
if (!scrollbar->enabled())
567
trackInfo.enableState = kThemeTrackDisabled;
569
trackInfo.enableState = scrollbar->isScrollableAreaActive() ? kThemeTrackActive : kThemeTrackInactive;
571
if (hasThumb(scrollbar))
572
trackInfo.attributes |= kThemeTrackShowThumb;
573
else if (!hasButtons(scrollbar))
574
trackInfo.enableState = kThemeTrackNothingToScroll;
575
trackInfo.trackInfo.scrollbar.pressState = scrollbarPartToHIPressedState(scrollbar->pressedPart());
577
// The Aqua scrollbar is buggy when rotated and scaled. We will just draw into a bitmap if we detect a scale or rotation.
578
// FIXME: This workaround is unnecessary for integral scale factors.
579
bool canDrawDirectly = context->getCTM().isIdentityOrTranslationOrFlipped();
581
HIThemeDrawTrack(&trackInfo, 0, context->platformContext(), kHIThemeOrientationNormal);
583
trackInfo.bounds = IntRect(IntPoint(), scrollbar->frameRect().size());
585
IntRect bufferRect(scrollbar->frameRect());
586
bufferRect.intersect(damageRect);
588
OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferRect.size(), 1);
592
imageBuffer->context()->translate(scrollbar->frameRect().x() - bufferRect.x(), scrollbar->frameRect().y() - bufferRect.y());
593
HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal);
594
context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, bufferRect.location());
601
#if !PLATFORM(CHROMIUM) && USE(ACCELERATED_COMPOSITING) && ENABLE(RUBBER_BANDING)
602
static RetainPtr<CGColorRef> linenBackgroundColor()
604
NSImage *image = [NSColor _linenPatternImage];
605
CGImageRef cgImage = [image CGImageForProposedRect:NULL context:NULL hints:nil];
607
RetainPtr<CGPatternRef> pattern = adoptCF(wkCGPatternCreateWithImageAndTransform(cgImage, CGAffineTransformIdentity, wkPatternTilingNoDistortion));
608
RetainPtr<CGColorSpaceRef> colorSpace = adoptCF(CGColorSpaceCreatePattern(0));
610
const CGFloat alpha = 1.0;
611
return adoptCF(CGColorCreateWithPattern(colorSpace.get(), pattern.get(), &alpha));
614
void ScrollbarThemeMac::setUpOverhangAreasLayerContents(GraphicsLayer* graphicsLayer)
616
static CGColorRef cachedLinenBackgroundColor = linenBackgroundColor().leakRef();
618
// We operate on the CALayer directly here, since GraphicsLayer doesn't have the concept
619
// of pattern images, and we know that WebCore won't touch this layer.
620
graphicsLayer->platformLayer().backgroundColor = cachedLinenBackgroundColor;
623
void ScrollbarThemeMac::setUpContentShadowLayer(GraphicsLayer* graphicsLayer)
625
// We operate on the CALayer directly here, since GraphicsLayer doesn't have the concept
626
// of shadows, and we know that WebCore won't touch this layer.
627
CALayer *contentShadowLayer = graphicsLayer->platformLayer();
629
static const CGFloat shadowOpacity = 0.66;
630
static const CGFloat shadowRadius = 3;
632
// We only need to set these shadow properties once.
633
if (!contentShadowLayer.shadowOpacity) {
634
contentShadowLayer.shadowColor = CGColorGetConstantColor(kCGColorBlack);
635
contentShadowLayer.shadowOffset = CGSizeZero;
636
contentShadowLayer.shadowOpacity = shadowOpacity;
637
contentShadowLayer.shadowRadius = shadowRadius;
640
RetainPtr<CGPathRef> shadowPath = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, graphicsLayer->size().width(), graphicsLayer->size().height()), NULL));
641
contentShadowLayer.shadowPath = shadowPath.get();
646
} // namespace WebCore