~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/rendering/RenderThemeSafari.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007, 2008, 2009 Apple Inc.
 
3
 * Copyright (C) 2009 Kenneth Rohde Christiansen
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Library General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Library General Public License
 
16
 * along with this library; see the file COPYING.LIB.  If not, write to
 
17
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
18
 * Boston, MA 02110-1301, USA.
 
19
 *
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
#include "RenderThemeSafari.h"
 
24
#include "RenderThemeWin.h"
 
25
#include "Settings.h"
 
26
 
 
27
#if USE(SAFARI_THEME)
 
28
 
 
29
#include "CSSFontSelector.h"
 
30
#include "CSSValueKeywords.h"
 
31
#include "Document.h"
 
32
#include "Element.h"
 
33
#include "Frame.h"
 
34
#include "FrameView.h"
 
35
#include "GraphicsContextCG.h"
 
36
#include "HTMLInputElement.h"
 
37
#include "HTMLMediaElement.h"
 
38
#include "HTMLNames.h"
 
39
#include "PaintInfo.h"
 
40
#include "RenderMediaControls.h"
 
41
#include "RenderSlider.h"
 
42
#include "RenderView.h"
 
43
#include "SoftLinking.h"
 
44
#include "StyleResolver.h"
 
45
#include <CoreGraphics/CoreGraphics.h>
 
46
#include <wtf/RetainPtr.h>
 
47
 
 
48
using std::min;
 
49
 
 
50
// FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeMac. 
 
51
 
 
52
namespace WebCore {
 
53
 
 
54
using namespace HTMLNames;
 
55
using namespace SafariTheme;
 
56
 
 
57
enum {
 
58
    topMargin,
 
59
    rightMargin,
 
60
    bottomMargin,
 
61
    leftMargin
 
62
};
 
63
 
 
64
enum {
 
65
    topPadding,
 
66
    rightPadding,
 
67
    bottomPadding,
 
68
    leftPadding
 
69
};
 
70
 
 
71
PassRefPtr<RenderTheme> RenderThemeSafari::create()
 
72
{
 
73
    return adoptRef(new RenderThemeSafari);
 
74
}
 
75
 
 
76
PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
 
77
{
 
78
    static RenderTheme* safariTheme = RenderThemeSafari::create().leakRef();
 
79
    static RenderTheme* windowsTheme = RenderThemeWin::create().leakRef();
 
80
 
 
81
    // FIXME: This is called before Settings has been initialized by WebKit, so will return a
 
82
    // potentially wrong answer the very first time it's called (see
 
83
    // <https://bugs.webkit.org/show_bug.cgi?id=26493>).
 
84
    if (Settings::shouldPaintNativeControls()) {
 
85
        RenderTheme::setCustomFocusRingColor(safariTheme->platformFocusRingColor());
 
86
        return windowsTheme; // keep the reference of one.
 
87
    }
 
88
    return safariTheme; // keep the reference of one.
 
89
}
 
90
 
 
91
#ifdef DEBUG_ALL
 
92
SOFT_LINK_DEBUG_LIBRARY(SafariTheme)
 
93
#else
 
94
SOFT_LINK_LIBRARY(SafariTheme)
 
95
#endif
 
96
 
 
97
SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state), (part, context, rect, size, state))
 
98
#if defined(SAFARI_THEME_VERSION) && SAFARI_THEME_VERSION >= 2
 
99
SOFT_LINK(SafariTheme, STPaintProgressIndicator, void, APIENTRY, (ProgressIndicatorType type, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state, float value), (type, context, rect, size, state, value))
 
100
#endif
 
101
SOFT_LINK_OPTIONAL(SafariTheme, STCopyThemeColor, CGColorRef, APIENTRY, (unsigned color, SafariTheme::ThemeControlState));
 
102
 
 
103
static const unsigned stFocusRingColorID = 4;
 
104
 
 
105
static const unsigned aquaFocusRingColor = 0xFF7DADD9;
 
106
 
 
107
static RGBA32 makeRGBAFromCGColor(CGColorRef color)
 
108
{
 
109
    const CGFloat* components = CGColorGetComponents(color);
 
110
    return makeRGBA(255 * components[0], 255 * components[1], 255 * components[2], 255 * components[3]);
 
111
}
 
112
 
 
113
ThemeControlState RenderThemeSafari::determineState(RenderObject* o) const
 
114
{
 
115
    ThemeControlState result = 0;
 
116
    if (isActive(o))
 
117
        result |= SafariTheme::ActiveState;
 
118
    if (isEnabled(o) && !isReadOnlyControl(o))
 
119
        result |= SafariTheme::EnabledState;
 
120
    if (isPressed(o))
 
121
        result |= SafariTheme::PressedState;
 
122
    if (isChecked(o))
 
123
        result |= SafariTheme::CheckedState;
 
124
    if (isIndeterminate(o))
 
125
        result |= SafariTheme::IndeterminateCheckedState;
 
126
    if (isFocused(o))
 
127
        result |= SafariTheme::FocusedState;
 
128
    if (isDefault(o))
 
129
        result |= SafariTheme::DefaultState;
 
130
    return result;
 
131
}
 
132
 
 
133
static NSControlSize controlSizeFromRect(const IntRect& rect, const IntSize sizes[])
 
134
{
 
135
    if (sizes[NSRegularControlSize].height() == rect.height())
 
136
        return NSRegularControlSize;
 
137
    else if (sizes[NSMiniControlSize].height() == rect.height())
 
138
        return NSMiniControlSize;
 
139
    
 
140
    return NSSmallControlSize;
 
141
}
 
142
 
 
143
RenderThemeSafari::RenderThemeSafari()
 
144
{
 
145
}
 
146
 
 
147
RenderThemeSafari::~RenderThemeSafari()
 
148
{
 
149
}
 
150
 
 
151
Color RenderThemeSafari::platformActiveSelectionBackgroundColor() const
 
152
{
 
153
    return Color(181, 213, 255);
 
154
}
 
155
 
 
156
Color RenderThemeSafari::platformInactiveSelectionBackgroundColor() const
 
157
{
 
158
    return Color(212, 212, 212);
 
159
}
 
160
 
 
161
Color RenderThemeSafari::activeListBoxSelectionBackgroundColor() const
 
162
{
 
163
    // FIXME: This should probably just be a darker version of the platformActiveSelectionBackgroundColor
 
164
    return Color(56, 117, 215);
 
165
}
 
166
 
 
167
Color RenderThemeSafari::platformFocusRingColor() const
 
168
{
 
169
    static Color focusRingColor;
 
170
 
 
171
    if (!focusRingColor.isValid()) {
 
172
        if (STCopyThemeColorPtr()) {
 
173
            RetainPtr<CGColorRef> color(AdoptCF, STCopyThemeColorPtr()(stFocusRingColorID, SafariTheme::ActiveState));
 
174
            focusRingColor = makeRGBAFromCGColor(color.get());
 
175
        }
 
176
        if (!focusRingColor.isValid())
 
177
            focusRingColor = aquaFocusRingColor;
 
178
    }
 
179
 
 
180
    return focusRingColor;
 
181
}
 
182
 
 
183
static float systemFontSizeForControlSize(NSControlSize controlSize)
 
184
{
 
185
    static float sizes[] = { 13.0f, 11.0f, 9.0f };
 
186
    
 
187
    return sizes[controlSize];
 
188
}
 
189
 
 
190
void RenderThemeSafari::systemFont(int propId, FontDescription& fontDescription) const
 
191
{
 
192
    static FontDescription systemFont;
 
193
    static FontDescription smallSystemFont;
 
194
    static FontDescription menuFont;
 
195
    static FontDescription labelFont;
 
196
    static FontDescription miniControlFont;
 
197
    static FontDescription smallControlFont;
 
198
    static FontDescription controlFont;
 
199
 
 
200
    FontDescription* cachedDesc;
 
201
    float fontSize = 0;
 
202
    switch (propId) {
 
203
        case CSSValueSmallCaption:
 
204
            cachedDesc = &smallSystemFont;
 
205
            if (!smallSystemFont.isAbsoluteSize())
 
206
                fontSize = systemFontSizeForControlSize(NSSmallControlSize);
 
207
            break;
 
208
        case CSSValueMenu:
 
209
            cachedDesc = &menuFont;
 
210
            if (!menuFont.isAbsoluteSize())
 
211
                fontSize = systemFontSizeForControlSize(NSRegularControlSize);
 
212
            break;
 
213
        case CSSValueStatusBar:
 
214
            cachedDesc = &labelFont;
 
215
            if (!labelFont.isAbsoluteSize())
 
216
                fontSize = 10.0f;
 
217
            break;
 
218
        case CSSValueWebkitMiniControl:
 
219
            cachedDesc = &miniControlFont;
 
220
            if (!miniControlFont.isAbsoluteSize())
 
221
                fontSize = systemFontSizeForControlSize(NSMiniControlSize);
 
222
            break;
 
223
        case CSSValueWebkitSmallControl:
 
224
            cachedDesc = &smallControlFont;
 
225
            if (!smallControlFont.isAbsoluteSize())
 
226
                fontSize = systemFontSizeForControlSize(NSSmallControlSize);
 
227
            break;
 
228
        case CSSValueWebkitControl:
 
229
            cachedDesc = &controlFont;
 
230
            if (!controlFont.isAbsoluteSize())
 
231
                fontSize = systemFontSizeForControlSize(NSRegularControlSize);
 
232
            break;
 
233
        default:
 
234
            cachedDesc = &systemFont;
 
235
            if (!systemFont.isAbsoluteSize())
 
236
                fontSize = 13.0f;
 
237
    }
 
238
 
 
239
    if (fontSize) {
 
240
        cachedDesc->setIsAbsoluteSize(true);
 
241
        cachedDesc->setGenericFamily(FontDescription::NoFamily);
 
242
        cachedDesc->firstFamily().setFamily("Lucida Grande");
 
243
        cachedDesc->setSpecifiedSize(fontSize);
 
244
        cachedDesc->setWeight(FontWeightNormal);
 
245
        cachedDesc->setItalic(false);
 
246
    }
 
247
    fontDescription = *cachedDesc;
 
248
}
 
249
 
 
250
bool RenderThemeSafari::isControlStyled(const RenderStyle* style, const BorderData& border,
 
251
                                     const FillLayer& background, const Color& backgroundColor) const
 
252
{
 
253
    // If we didn't find SafariTheme.dll we won't be able to paint any themed controls.
 
254
    if (!SafariThemeLibrary())
 
255
        return true;
 
256
 
 
257
    if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart)
 
258
        return style->border() != border;
 
259
    return RenderTheme::isControlStyled(style, border, background, backgroundColor);
 
260
}
 
261
 
 
262
void RenderThemeSafari::adjustRepaintRect(const RenderObject* o, IntRect& r)
 
263
{
 
264
    NSControlSize controlSize = controlSizeForFont(o->style());
 
265
 
 
266
    switch (o->style()->appearance()) {
 
267
        case CheckboxPart: {
 
268
            // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
 
269
            // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
 
270
            r = inflateRect(r, checkboxSizes()[controlSize], checkboxMargins(controlSize));
 
271
            break;
 
272
        }
 
273
        case RadioPart: {
 
274
            // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
 
275
            // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
 
276
            r = inflateRect(r, radioSizes()[controlSize], radioMargins(controlSize));
 
277
            break;
 
278
        }
 
279
        case PushButtonPart:
 
280
        case DefaultButtonPart:
 
281
        case ButtonPart: {
 
282
            // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
 
283
            // shadow" and the check.  We don't consider this part of the bounds of the control in WebKit.
 
284
            if (r.height() <= buttonSizes()[NSRegularControlSize].height())
 
285
                r = inflateRect(r, buttonSizes()[controlSize], buttonMargins(controlSize));
 
286
            break;
 
287
        }
 
288
        case MenulistPart: {
 
289
            r = inflateRect(r, popupButtonSizes()[controlSize], popupButtonMargins(controlSize));
 
290
            break;
 
291
        }
 
292
        default:
 
293
            break;
 
294
    }
 
295
}
 
296
 
 
297
IntRect RenderThemeSafari::inflateRect(const IntRect& r, const IntSize& size, const int* margins) const
 
298
{
 
299
    // Only do the inflation if the available width/height are too small.  Otherwise try to
 
300
    // fit the glow/check space into the available box's width/height.
 
301
    int widthDelta = r.width() - (size.width() + margins[leftMargin] + margins[rightMargin]);
 
302
    int heightDelta = r.height() - (size.height() + margins[topMargin] + margins[bottomMargin]);
 
303
    IntRect result(r);
 
304
    if (widthDelta < 0) {
 
305
        result.setX(result.x() - margins[leftMargin]);
 
306
        result.setWidth(result.width() - widthDelta);
 
307
    }
 
308
    if (heightDelta < 0) {
 
309
        result.setY(result.y() - margins[topMargin]);
 
310
        result.setHeight(result.height() - heightDelta);
 
311
    }
 
312
    return result;
 
313
}
 
314
 
 
315
int RenderThemeSafari::baselinePosition(const RenderObject* o) const
 
316
{
 
317
    if (!o->isBox())
 
318
        return 0;
 
319
 
 
320
    if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart) {
 
321
        const RenderBox* box = toRenderBox(o);
 
322
        return box->marginTop() + box->height() - 2; // The baseline is 2px up from the bottom of the checkbox/radio in AppKit.
 
323
    }
 
324
 
 
325
    return RenderTheme::baselinePosition(o);
 
326
}
 
327
 
 
328
bool RenderThemeSafari::controlSupportsTints(const RenderObject* o) const
 
329
{
 
330
    if (!isEnabled(o))
 
331
        return false;
 
332
 
 
333
    // Checkboxes only have tint when checked.
 
334
    if (o->style()->appearance() == CheckboxPart)
 
335
        return isChecked(o);
 
336
 
 
337
    // For now assume other controls have tint if enabled.
 
338
    return true;
 
339
}
 
340
 
 
341
NSControlSize RenderThemeSafari::controlSizeForFont(RenderStyle* style) const
 
342
{
 
343
    int fontSize = style->fontSize();
 
344
    if (fontSize >= 16)
 
345
        return NSRegularControlSize;
 
346
    if (fontSize >= 11)
 
347
        return NSSmallControlSize;
 
348
    return NSMiniControlSize;
 
349
}
 
350
/*
 
351
void RenderThemeSafari::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize)
 
352
{
 
353
    NSControlSize size;
 
354
    if (minSize.width() >= sizes[NSRegularControlSize].width() &&
 
355
        minSize.height() >= sizes[NSRegularControlSize].height())
 
356
        size = NSRegularControlSize;
 
357
    else if (minSize.width() >= sizes[NSSmallControlSize].width() &&
 
358
             minSize.height() >= sizes[NSSmallControlSize].height())
 
359
        size = NSSmallControlSize;
 
360
    else
 
361
        size = NSMiniControlSize;
 
362
    if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
 
363
        [cell setControlSize:size];
 
364
}
 
365
*/
 
366
IntSize RenderThemeSafari::sizeForFont(RenderStyle* style, const IntSize* sizes) const
 
367
{
 
368
    return sizes[controlSizeForFont(style)];
 
369
}
 
370
 
 
371
IntSize RenderThemeSafari::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const
 
372
{
 
373
    return sizes[controlSizeForSystemFont(style)];
 
374
}
 
375
 
 
376
void RenderThemeSafari::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const
 
377
{
 
378
    // FIXME: Check is flawed, since it doesn't take min-width/max-width into account.
 
379
    IntSize size = sizeForFont(style, sizes);
 
380
    if (style->width().isIntrinsicOrAuto() && size.width() > 0)
 
381
        style->setWidth(Length(size.width(), Fixed));
 
382
    if (style->height().isAuto() && size.height() > 0)
 
383
        style->setHeight(Length(size.height(), Fixed));
 
384
}
 
385
 
 
386
void RenderThemeSafari::setFontFromControlSize(StyleResolver* styleResolver, RenderStyle* style, NSControlSize controlSize) const
 
387
{
 
388
    FontDescription fontDescription;
 
389
    fontDescription.setIsAbsoluteSize(true);
 
390
    fontDescription.setGenericFamily(FontDescription::SerifFamily);
 
391
 
 
392
    float fontSize = systemFontSizeForControlSize(controlSize);
 
393
    fontDescription.firstFamily().setFamily("Lucida Grande");
 
394
    fontDescription.setComputedSize(fontSize);
 
395
    fontDescription.setSpecifiedSize(fontSize);
 
396
 
 
397
    // Reset line height
 
398
    style->setLineHeight(RenderStyle::initialLineHeight());
 
399
 
 
400
    if (style->setFontDescription(fontDescription))
 
401
        style->font().update(styleResolver->fontSelector());
 
402
}
 
403
 
 
404
NSControlSize RenderThemeSafari::controlSizeForSystemFont(RenderStyle* style) const
 
405
{
 
406
    int fontSize = style->fontSize();
 
407
    if (fontSize >= 13)
 
408
        return NSRegularControlSize;
 
409
    if (fontSize >= 11)
 
410
        return NSSmallControlSize;
 
411
    return NSMiniControlSize;
 
412
}
 
413
 
 
414
bool RenderThemeSafari::paintCheckbox(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
415
{
 
416
    ASSERT(SafariThemeLibrary());
 
417
 
 
418
    NSControlSize controlSize = controlSizeForFont(o->style());
 
419
 
 
420
    IntRect inflatedRect = inflateRect(r, checkboxSizes()[controlSize], checkboxMargins(controlSize));  
 
421
    paintThemePart(SafariTheme::CheckboxPart, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o));
 
422
 
 
423
    return false;
 
424
}
 
425
 
 
426
const IntSize* RenderThemeSafari::checkboxSizes() const
 
427
{
 
428
    static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) };
 
429
    return sizes;
 
430
}
 
431
 
 
432
const int* RenderThemeSafari::checkboxMargins(NSControlSize controlSize) const
 
433
{
 
434
    static const int margins[3][4] =
 
435
    {
 
436
        { 2, 2, 2, 2 },
 
437
        { 2, 2, 2, 1 },
 
438
        { 1, 0, 0, 0 },
 
439
    };
 
440
    return margins[controlSize];
 
441
}
 
442
 
 
443
void RenderThemeSafari::setCheckboxSize(RenderStyle* style) const
 
444
{
 
445
    // If the width and height are both specified, then we have nothing to do.
 
446
    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
 
447
        return;
 
448
 
 
449
    // Use the font size to determine the intrinsic width of the control.
 
450
    setSizeFromFont(style, checkboxSizes());
 
451
}
 
452
 
 
453
bool RenderThemeSafari::paintRadio(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
454
{
 
455
    ASSERT(SafariThemeLibrary());
 
456
 
 
457
    NSControlSize controlSize = controlSizeForFont(o->style());
 
458
 
 
459
    IntRect inflatedRect = inflateRect(r, radioSizes()[controlSize], radioMargins(controlSize));    
 
460
    paintThemePart(RadioButtonPart, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o));
 
461
 
 
462
    return false;
 
463
}
 
464
 
 
465
const IntSize* RenderThemeSafari::radioSizes() const
 
466
{
 
467
    static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) };
 
468
    return sizes;
 
469
}
 
470
 
 
471
const int* RenderThemeSafari::radioMargins(NSControlSize controlSize) const
 
472
{
 
473
    static const int margins[3][4] =
 
474
    {
 
475
        { 1, 2, 2, 2 },
 
476
        { 0, 1, 2, 1 },
 
477
        { 0, 0, 1, 0 },
 
478
     };
 
479
    return margins[controlSize];
 
480
}
 
481
 
 
482
void RenderThemeSafari::setRadioSize(RenderStyle* style) const
 
483
{
 
484
    // If the width and height are both specified, then we have nothing to do.
 
485
    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
 
486
        return;
 
487
 
 
488
    // Use the font size to determine the intrinsic width of the control.
 
489
    setSizeFromFont(style, radioSizes());
 
490
}
 
491
 
 
492
void RenderThemeSafari::setButtonPaddingFromControlSize(RenderStyle* style, NSControlSize size) const
 
493
{
 
494
    // Just use 8px.  AppKit wants to use 11px for mini buttons, but that padding is just too large
 
495
    // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is
 
496
    // by definition constrained, since we select mini only for small cramped environments.
 
497
    // This also guarantees the HTML4 <button> will match our rendering by default, since we're using a consistent
 
498
    // padding.
 
499
    const int padding = 8;
 
500
    style->setPaddingLeft(Length(padding, Fixed));
 
501
    style->setPaddingRight(Length(padding, Fixed));
 
502
    style->setPaddingTop(Length(0, Fixed));
 
503
    style->setPaddingBottom(Length(0, Fixed));
 
504
}
 
505
 
 
506
void RenderThemeSafari::adjustButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
 
507
{
 
508
    // There are three appearance constants for buttons.
 
509
    // (1) Push-button is the constant for the default Aqua system button.  Push buttons will not scale vertically and will not allow
 
510
    // custom fonts or colors.  <input>s use this constant.  This button will allow custom colors and font weights/variants but won't
 
511
    // scale vertically.
 
512
    // (2) square-button is the constant for the square button.  This button will allow custom fonts and colors and will scale vertically.
 
513
    // (3) Button is the constant that means "pick the best button as appropriate."  <button>s use this constant.  This button will
 
514
    // also scale vertically and allow custom fonts and colors.  It will attempt to use Aqua if possible and will make this determination
 
515
    // solely on the rectangle of the control.
 
516
 
 
517
    // Determine our control size based off our font.
 
518
    NSControlSize controlSize = controlSizeForFont(style);
 
519
 
 
520
    if (style->appearance() == PushButtonPart) {
 
521
        // Ditch the border.
 
522
        style->resetBorder();
 
523
 
 
524
        // Height is locked to auto.
 
525
        style->setHeight(Length(Auto));
 
526
 
 
527
        // White-space is locked to pre
 
528
        style->setWhiteSpace(PRE);
 
529
 
 
530
        // Set the button's vertical size.
 
531
        setButtonSize(style);
 
532
 
 
533
        // Add in the padding that we'd like to use.
 
534
        setButtonPaddingFromControlSize(style, controlSize);
 
535
 
 
536
        // 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
 
537
        // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
 
538
        // system font for the control size instead.
 
539
        setFontFromControlSize(styleResolver, style, controlSize);
 
540
    } else {
 
541
        // Set a min-height so that we can't get smaller than the mini button.
 
542
        style->setMinHeight(Length(15, Fixed));
 
543
 
 
544
        // Reset the top and bottom borders.
 
545
        style->resetBorderTop();
 
546
        style->resetBorderBottom();
 
547
    }
 
548
}
 
549
 
 
550
const IntSize* RenderThemeSafari::buttonSizes() const
 
551
{
 
552
    static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
 
553
    return sizes;
 
554
}
 
555
 
 
556
const int* RenderThemeSafari::buttonMargins(NSControlSize controlSize) const
 
557
{
 
558
    static const int margins[3][4] =
 
559
    {
 
560
        { 4, 6, 7, 6 },
 
561
        { 4, 5, 6, 5 },
 
562
        { 0, 1, 1, 1 },
 
563
    };
 
564
    return margins[controlSize];
 
565
}
 
566
 
 
567
void RenderThemeSafari::setButtonSize(RenderStyle* style) const
 
568
{
 
569
    // If the width and height are both specified, then we have nothing to do.
 
570
    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
 
571
        return;
 
572
 
 
573
    // Use the font size to determine the intrinsic width of the control.
 
574
    setSizeFromFont(style, buttonSizes());
 
575
}
 
576
 
 
577
bool RenderThemeSafari::paintButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
578
{
 
579
    ASSERT(SafariThemeLibrary());
 
580
 
 
581
    // We inflate the rect as needed to account for padding included in the cell to accommodate the button
 
582
    // shadow.  We don't consider this part of the bounds of the control in WebKit.
 
583
 
 
584
    NSControlSize controlSize = controlSizeFromRect(r, buttonSizes());
 
585
    IntRect inflatedRect = r;
 
586
 
 
587
    ThemePart part;
 
588
    if (r.height() <= buttonSizes()[NSRegularControlSize].height()) {
 
589
        // Push button
 
590
        part = SafariTheme::PushButtonPart;
 
591
 
 
592
        IntSize size = buttonSizes()[controlSize];
 
593
        size.setWidth(r.width());
 
594
 
 
595
        // Center the button within the available space.
 
596
        if (inflatedRect.height() > size.height()) {
 
597
            inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - size.height()) / 2);
 
598
            inflatedRect.setHeight(size.height());
 
599
        }
 
600
 
 
601
        // Now inflate it to account for the shadow.
 
602
        inflatedRect = inflateRect(inflatedRect, size, buttonMargins(controlSize));
 
603
    } else
 
604
        part = SafariTheme::SquareButtonPart;
 
605
 
 
606
    paintThemePart(part, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o));
 
607
    return false;
 
608
}
 
609
 
 
610
bool RenderThemeSafari::paintTextField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
611
{
 
612
    ASSERT(SafariThemeLibrary());
 
613
 
 
614
    paintThemePart(SafariTheme::TextFieldPart, paintInfo.context->platformContext(), r, (NSControlSize)0, determineState(o) & ~FocusedState);
 
615
    return false;
 
616
}
 
617
 
 
618
void RenderThemeSafari::adjustTextFieldStyle(StyleResolver*, RenderStyle*, Element*) const
 
619
{
 
620
}
 
621
 
 
622
bool RenderThemeSafari::paintCapsLockIndicator(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
623
{    
 
624
#if defined(SAFARI_THEME_VERSION) && SAFARI_THEME_VERSION >= 1
 
625
    ASSERT(SafariThemeLibrary());
 
626
 
 
627
    if (paintInfo.context->paintingDisabled())
 
628
        return true;
 
629
 
 
630
    paintThemePart(CapsLockPart, paintInfo.context->platformContext(), r, (NSControlSize)0, (ThemeControlState)0);
 
631
 
 
632
    return false;
 
633
#else
 
634
    return true;
 
635
#endif
 
636
}
 
637
 
 
638
bool RenderThemeSafari::paintTextArea(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
639
{
 
640
    ASSERT(SafariThemeLibrary());
 
641
 
 
642
    paintThemePart(SafariTheme::TextAreaPart, paintInfo.context->platformContext(), r, (NSControlSize)0, determineState(o) & ~FocusedState);
 
643
    return false;
 
644
}
 
645
 
 
646
void RenderThemeSafari::adjustTextAreaStyle(StyleResolver*, RenderStyle*, Element*) const
 
647
{
 
648
}
 
649
 
 
650
const int* RenderThemeSafari::popupButtonMargins(NSControlSize size) const
 
651
{
 
652
    static const int margins[3][4] =
 
653
    {
 
654
        { 2, 3, 3, 3 },
 
655
        { 1, 3, 3, 3 },
 
656
        { 0, 1, 0, 1 }
 
657
    };
 
658
    return margins[size];
 
659
}
 
660
 
 
661
const IntSize* RenderThemeSafari::popupButtonSizes() const
 
662
{
 
663
    static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
 
664
    return sizes;
 
665
}
 
666
 
 
667
const int* RenderThemeSafari::popupButtonPadding(NSControlSize size) const
 
668
{
 
669
    static const int padding[3][4] =
 
670
    {
 
671
        { 2, 26, 3, 8 },
 
672
        { 2, 23, 3, 8 },
 
673
        { 2, 22, 3, 10 }
 
674
    };
 
675
    return padding[size];
 
676
}
 
677
 
 
678
bool RenderThemeSafari::paintMenuList(RenderObject* o, const PaintInfo& info, const IntRect& r)
 
679
{
 
680
    ASSERT(SafariThemeLibrary());
 
681
 
 
682
    NSControlSize controlSize = controlSizeFromRect(r, popupButtonSizes());
 
683
    IntRect inflatedRect = r;
 
684
    IntSize size = popupButtonSizes()[controlSize];
 
685
    size.setWidth(r.width());
 
686
 
 
687
    // Now inflate it to account for the shadow.
 
688
    if (r.width() >= minimumMenuListSize(o->style()))
 
689
        inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(controlSize));
 
690
 
 
691
    paintThemePart(DropDownButtonPart, info.context->platformContext(), inflatedRect, controlSize, determineState(o));
 
692
 
 
693
    return false;
 
694
}
 
695
 
 
696
const float baseFontSize = 11.0f;
 
697
const float baseArrowHeight = 5.0f;
 
698
const float baseArrowWidth = 7.0f;
 
699
const int arrowPaddingLeft = 5;
 
700
const int arrowPaddingRight = 5;
 
701
const int paddingBeforeSeparator = 4;
 
702
const int baseBorderRadius = 5;
 
703
const int styledPopupPaddingLeft = 8;
 
704
const int styledPopupPaddingTop = 1;
 
705
const int styledPopupPaddingBottom = 2;
 
706
 
 
707
static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData)
 
708
{
 
709
    static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f };
 
710
    static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f };
 
711
    float a = inData[0];
 
712
    int i = 0;
 
713
    for (i = 0; i < 4; i++)
 
714
        outData[i] = (1.0f - a) * dark[i] + a * light[i];
 
715
}
 
716
 
 
717
static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData)
 
718
{
 
719
    static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
 
720
    static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f };
 
721
    float a = inData[0];
 
722
    int i = 0;
 
723
    for (i = 0; i < 4; i++)
 
724
        outData[i] = (1.0f - a) * dark[i] + a * light[i];
 
725
}
 
726
 
 
727
static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData)
 
728
{
 
729
    static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f };
 
730
    static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
 
731
    float a = inData[0];
 
732
    int i = 0;
 
733
    for (i = 0; i < 4; i++)
 
734
        outData[i] = (1.0f - a) * dark[i] + a * light[i];
 
735
}
 
736
 
 
737
static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData)
 
738
{
 
739
    static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f };
 
740
    static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f };
 
741
    float a = inData[0];
 
742
    int i = 0;
 
743
    for (i = 0; i < 4; i++)
 
744
        outData[i] = (1.0f - a) * dark[i] + a * light[i];
 
745
}
 
746
 
 
747
void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
748
{
 
749
    if (r.isEmpty())
 
750
        return;
 
751
 
 
752
    CGContextRef context = paintInfo.context->platformContext();
 
753
 
 
754
    paintInfo.context->save();
 
755
 
 
756
    RoundedRect bound = o->style()->getRoundedBorderFor(r);
 
757
    int radius = bound.radii().topLeft().width();
 
758
 
 
759
    CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
 
760
 
 
761
    FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
 
762
    struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
 
763
    RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
 
764
    RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
 
765
 
 
766
    FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
 
767
    struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
 
768
    RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
 
769
    RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(),  bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
 
770
 
 
771
    struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
 
772
    RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
 
773
    RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
 
774
 
 
775
    RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
 
776
 
 
777
    RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(),  r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
 
778
    paintInfo.context->save();
 
779
    CGContextClipToRect(context, bound.rect());
 
780
    paintInfo.context->addRoundedRectClip(bound);
 
781
    CGContextDrawShading(context, mainShading.get());
 
782
    paintInfo.context->restore();
 
783
 
 
784
    paintInfo.context->save();
 
785
    CGContextClipToRect(context, topGradient);
 
786
    paintInfo.context->addRoundedRectClip(RoundedRect(enclosingIntRect(topGradient), bound.radii().topLeft(), bound.radii().topRight(), IntSize(), IntSize()));
 
787
    CGContextDrawShading(context, topShading.get());
 
788
    paintInfo.context->restore();
 
789
 
 
790
    if (!bottomGradient.isEmpty()) {
 
791
        paintInfo.context->save();
 
792
        CGContextClipToRect(context, bottomGradient);
 
793
        paintInfo.context->addRoundedRectClip(RoundedRect(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bound.radii().bottomLeft(), bound.radii().bottomRight()));
 
794
        CGContextDrawShading(context, bottomShading.get());
 
795
        paintInfo.context->restore();
 
796
    }
 
797
 
 
798
    paintInfo.context->save();
 
799
    CGContextClipToRect(context, bound.rect());
 
800
    paintInfo.context->addRoundedRectClip(bound);
 
801
    CGContextDrawShading(context, leftShading.get());
 
802
    CGContextDrawShading(context, rightShading.get());
 
803
    paintInfo.context->restore();
 
804
 
 
805
    paintInfo.context->restore();
 
806
}
 
807
 
 
808
bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
809
{
 
810
    IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
 
811
                             r.y() + o->style()->borderTopWidth(),
 
812
                             r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
 
813
                             r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
 
814
    // Draw the gradients to give the styled popup menu a button appearance
 
815
    paintMenuListButtonGradients(o, paintInfo, bounds);
 
816
    
 
817
    // Since we actually know the size of the control here, we restrict the font scale to make sure the arrow will fit vertically in the bounds
 
818
    float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / baseArrowHeight);
 
819
    float centerY = bounds.y() + bounds.height() / 2.0f;
 
820
    float arrowHeight = baseArrowHeight * fontScale;
 
821
    float arrowWidth = baseArrowWidth * fontScale;
 
822
    float leftEdge = bounds.maxX() - arrowPaddingRight - arrowWidth;
 
823
 
 
824
    if (bounds.width() < arrowWidth + arrowPaddingLeft)
 
825
        return false;
 
826
 
 
827
    paintInfo.context->save();
 
828
 
 
829
    paintInfo.context->setFillColor(o->style()->visitedDependentColor(CSSPropertyColor), ColorSpaceDeviceRGB);
 
830
    paintInfo.context->setStrokeColor(NoStroke, ColorSpaceDeviceRGB);
 
831
 
 
832
    FloatPoint arrow[3];
 
833
    arrow[0] = FloatPoint(leftEdge, centerY - arrowHeight / 2.0f);
 
834
    arrow[1] = FloatPoint(leftEdge + arrowWidth, centerY - arrowHeight / 2.0f);
 
835
    arrow[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + arrowHeight / 2.0f);
 
836
 
 
837
    // Draw the arrow
 
838
    paintInfo.context->drawConvexPolygon(3, arrow, true);
 
839
 
 
840
    Color leftSeparatorColor(0, 0, 0, 40);
 
841
    Color rightSeparatorColor(255, 255, 255, 40);
 
842
    
 
843
    // FIXME: Should the separator thickness and space be scaled up by fontScale?
 
844
    int separatorSpace = 2;
 
845
    int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft); // FIXME: Round?
 
846
 
 
847
    // Draw the separator to the left of the arrows
 
848
    paintInfo.context->setStrokeThickness(1.0f);
 
849
    paintInfo.context->setStrokeStyle(SolidStroke);
 
850
    paintInfo.context->setStrokeColor(leftSeparatorColor, ColorSpaceDeviceRGB);
 
851
    paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
 
852
                                IntPoint(leftEdgeOfSeparator, bounds.maxY()));
 
853
 
 
854
    paintInfo.context->setStrokeColor(rightSeparatorColor, ColorSpaceDeviceRGB);
 
855
    paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
 
856
                                IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
 
857
 
 
858
    paintInfo.context->restore();
 
859
    return false;
 
860
}
 
861
 
 
862
void RenderThemeSafari::adjustMenuListStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
 
863
{
 
864
    NSControlSize controlSize = controlSizeForFont(style);
 
865
 
 
866
    style->resetBorder();
 
867
    style->resetPadding();
 
868
    
 
869
    // Height is locked to auto.
 
870
    style->setHeight(Length(Auto));
 
871
 
 
872
    // White-space is locked to pre
 
873
    style->setWhiteSpace(PRE);
 
874
 
 
875
    // Set the foreground color to black or gray when we have the aqua look.
 
876
    // Cast to RGB32 is to work around a compiler bug.
 
877
    style->setColor(e && e->isEnabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray);
 
878
 
 
879
    // Set the button's vertical size.
 
880
    setButtonSize(style);
 
881
 
 
882
    // 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
 
883
    // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate
 
884
    // system font for the control size instead.
 
885
    setFontFromControlSize(styleResolver, style, controlSize);
 
886
}
 
887
 
 
888
int RenderThemeSafari::popupInternalPaddingLeft(RenderStyle* style) const
 
889
{
 
890
    if (style->appearance() == MenulistPart)
 
891
        return popupButtonPadding(controlSizeForFont(style))[leftPadding];
 
892
    if (style->appearance() == MenulistButtonPart)
 
893
        return styledPopupPaddingLeft;
 
894
    return 0;
 
895
}
 
896
 
 
897
int RenderThemeSafari::popupInternalPaddingRight(RenderStyle* style) const
 
898
{
 
899
    if (style->appearance() == MenulistPart)
 
900
        return popupButtonPadding(controlSizeForFont(style))[rightPadding];
 
901
    if (style->appearance() == MenulistButtonPart) {
 
902
        float fontScale = style->fontSize() / baseFontSize;
 
903
        float arrowWidth = baseArrowWidth * fontScale;
 
904
        return static_cast<int>(ceilf(arrowWidth + arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator));
 
905
    }
 
906
    return 0;
 
907
}
 
908
 
 
909
int RenderThemeSafari::popupInternalPaddingTop(RenderStyle* style) const
 
910
{
 
911
    if (style->appearance() == MenulistPart)
 
912
        return popupButtonPadding(controlSizeForFont(style))[topPadding];
 
913
    if (style->appearance() == MenulistButtonPart)
 
914
        return styledPopupPaddingTop;
 
915
    return 0;
 
916
}
 
917
 
 
918
int RenderThemeSafari::popupInternalPaddingBottom(RenderStyle* style) const
 
919
{
 
920
    if (style->appearance() == MenulistPart)
 
921
        return popupButtonPadding(controlSizeForFont(style))[bottomPadding];
 
922
    if (style->appearance() == MenulistButtonPart)
 
923
        return styledPopupPaddingBottom;
 
924
    return 0;
 
925
}
 
926
 
 
927
void RenderThemeSafari::adjustMenuListButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
 
928
{
 
929
    float fontScale = style->fontSize() / baseFontSize;
 
930
    
 
931
    style->resetPadding();
 
932
    style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up?
 
933
 
 
934
    const int minHeight = 15;
 
935
    style->setMinHeight(Length(minHeight, Fixed));
 
936
    
 
937
    style->setLineHeight(RenderStyle::initialLineHeight());
 
938
}
 
939
 
 
940
const IntSize* RenderThemeSafari::menuListSizes() const
 
941
{
 
942
    static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) };
 
943
    return sizes;
 
944
}
 
945
 
 
946
int RenderThemeSafari::minimumMenuListSize(RenderStyle* style) const
 
947
{
 
948
    return sizeForSystemFont(style, menuListSizes()).width();
 
949
}
 
950
 
 
951
const int trackWidth = 5;
 
952
const int trackRadius = 2;
 
953
 
 
954
bool RenderThemeSafari::paintSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
955
{
 
956
    IntSize radius(trackRadius, trackRadius);
 
957
    RoundedRect bounds(r, radius, radius, radius, radius);
 
958
 
 
959
    if (o->style()->appearance() ==  SliderHorizontalPart)
 
960
        bounds.setRect(IntRect(r.x(),
 
961
                               r.y() + r.height() / 2 - trackWidth / 2,
 
962
                               r.width(),
 
963
                               trackWidth));
 
964
    else if (o->style()->appearance() == SliderVerticalPart)
 
965
        bounds.setRect(IntRect(r.x() + r.width() / 2 - trackWidth / 2,
 
966
                               r.y(),
 
967
                               trackWidth, 
 
968
                               r.height()));
 
969
 
 
970
    CGContextRef context = paintInfo.context->platformContext();
 
971
    CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
 
972
 
 
973
    paintInfo.context->save();
 
974
    CGContextClipToRect(context, bounds.rect());
 
975
 
 
976
    struct CGFunctionCallbacks mainCallbacks = { 0, TrackGradientInterpolate, NULL };
 
977
    RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
 
978
    RetainPtr<CGShadingRef> mainShading;
 
979
    if (o->style()->appearance() == SliderVerticalPart)
 
980
        mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(),  bounds.rect().maxY()), CGPointMake(bounds.rect().maxX(), bounds.rect().maxY()), mainFunction.get(), false, false));
 
981
    else
 
982
        mainShading.adoptCF(CGShadingCreateAxial(cspace, CGPointMake(bounds.rect().x(),  bounds.rect().y()), CGPointMake(bounds.rect().x(), bounds.rect().maxY()), mainFunction.get(), false, false));
 
983
 
 
984
    paintInfo.context->addRoundedRectClip(bounds);
 
985
    CGContextDrawShading(context, mainShading.get());
 
986
    paintInfo.context->restore();
 
987
    
 
988
    return false;
 
989
}
 
990
 
 
991
void RenderThemeSafari::adjustSliderThumbStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const 
 
992
 
993
    RenderTheme::adjustSliderThumbStyle(styleResolver, style, e);
 
994
    style->setBoxShadow(nullptr); 
 
995
 
996
 
 
997
const float verticalSliderHeightPadding = 0.1f;
 
998
 
 
999
bool RenderThemeSafari::paintSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1000
{
 
1001
    ASSERT(SafariThemeLibrary());
 
1002
    paintThemePart(SliderThumbPart, paintInfo.context->platformContext(), r, NSSmallControlSize, determineState(o));
 
1003
    return false;
 
1004
}
 
1005
 
 
1006
const int sliderThumbWidth = 15;
 
1007
const int sliderThumbHeight = 15;
 
1008
 
 
1009
void RenderThemeSafari::adjustSliderThumbSize(RenderStyle* style, Element*) const
 
1010
{
 
1011
    if (style->appearance() == SliderThumbHorizontalPart || style->appearance() == SliderThumbVerticalPart) {
 
1012
        style->setWidth(Length(sliderThumbWidth, Fixed));
 
1013
        style->setHeight(Length(sliderThumbHeight, Fixed));
 
1014
    } 
 
1015
#if ENABLE(VIDEO)
 
1016
    else if (style->appearance() == MediaSliderThumbPart) 
 
1017
        RenderMediaControls::adjustMediaSliderThumbSize(style);
 
1018
#endif
 
1019
}
 
1020
 
 
1021
bool RenderThemeSafari::paintSearchField(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1022
{
 
1023
    ASSERT(SafariThemeLibrary());
 
1024
 
 
1025
    paintThemePart(SafariTheme::SearchFieldPart, paintInfo.context->platformContext(), r, controlSizeFromRect(r, searchFieldSizes()), determineState(o));
 
1026
    return false;
 
1027
}
 
1028
 
 
1029
const IntSize* RenderThemeSafari::searchFieldSizes() const
 
1030
{
 
1031
    static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 15) };
 
1032
    return sizes;
 
1033
}
 
1034
 
 
1035
void RenderThemeSafari::setSearchFieldSize(RenderStyle* style) const
 
1036
{
 
1037
    // If the width and height are both specified, then we have nothing to do.
 
1038
    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
 
1039
        return;
 
1040
    
 
1041
    // Use the font size to determine the intrinsic width of the control.
 
1042
    setSizeFromFont(style, searchFieldSizes());
 
1043
}
 
1044
 
 
1045
void RenderThemeSafari::adjustSearchFieldStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
 
1046
{
 
1047
    // Override border.
 
1048
    style->resetBorder();
 
1049
    const short borderWidth = 2;
 
1050
    style->setBorderLeftWidth(borderWidth);
 
1051
    style->setBorderLeftStyle(INSET);
 
1052
    style->setBorderRightWidth(borderWidth);
 
1053
    style->setBorderRightStyle(INSET);
 
1054
    style->setBorderBottomWidth(borderWidth);
 
1055
    style->setBorderBottomStyle(INSET);
 
1056
    style->setBorderTopWidth(borderWidth);
 
1057
    style->setBorderTopStyle(INSET);    
 
1058
    
 
1059
    // Override height.
 
1060
    style->setHeight(Length(Auto));
 
1061
    setSearchFieldSize(style);
 
1062
    
 
1063
    // Override padding size to match AppKit text positioning.
 
1064
    const int padding = 1;
 
1065
    style->setPaddingLeft(Length(padding, Fixed));
 
1066
    style->setPaddingRight(Length(padding, Fixed));
 
1067
    style->setPaddingTop(Length(padding, Fixed));
 
1068
    style->setPaddingBottom(Length(padding, Fixed));
 
1069
    
 
1070
    NSControlSize controlSize = controlSizeForFont(style);
 
1071
    setFontFromControlSize(styleResolver, style, controlSize);
 
1072
}
 
1073
 
 
1074
bool RenderThemeSafari::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect&)
 
1075
{
 
1076
    ASSERT(SafariThemeLibrary());
 
1077
 
 
1078
    Node* input = o->node()->shadowHost();
 
1079
    if (!input)
 
1080
        input = o->node();
 
1081
    RenderObject* renderer = input->renderer();
 
1082
    ASSERT(renderer);
 
1083
 
 
1084
    IntRect searchRect = renderer->absoluteBoundingBoxRectIgnoringTransforms();
 
1085
 
 
1086
    paintThemePart(SafariTheme::SearchFieldCancelButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o));
 
1087
    return false;
 
1088
}
 
1089
 
 
1090
const IntSize* RenderThemeSafari::cancelButtonSizes() const
 
1091
{
 
1092
    static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(13, 9) };
 
1093
    return sizes;
 
1094
}
 
1095
 
 
1096
void RenderThemeSafari::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
 
1097
{
 
1098
    IntSize size = sizeForSystemFont(style, cancelButtonSizes());
 
1099
    style->setWidth(Length(size.width(), Fixed));
 
1100
    style->setHeight(Length(size.height(), Fixed));
 
1101
}
 
1102
 
 
1103
const IntSize* RenderThemeSafari::resultsButtonSizes() const
 
1104
{
 
1105
    static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(17, 9) };
 
1106
    return sizes;
 
1107
}
 
1108
 
 
1109
const int emptyResultsOffset = 9;
 
1110
void RenderThemeSafari::adjustSearchFieldDecorationStyle(StyleResolver*, RenderStyle* style, Element*) const
 
1111
{
 
1112
    IntSize size = sizeForSystemFont(style, resultsButtonSizes());
 
1113
    style->setWidth(Length(size.width() - emptyResultsOffset, Fixed));
 
1114
    style->setHeight(Length(size.height(), Fixed));
 
1115
}
 
1116
 
 
1117
bool RenderThemeSafari::paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&)
 
1118
{
 
1119
    return false;
 
1120
}
 
1121
 
 
1122
void RenderThemeSafari::adjustSearchFieldResultsDecorationStyle(StyleResolver*, RenderStyle* style, Element*) const
 
1123
{
 
1124
    IntSize size = sizeForSystemFont(style, resultsButtonSizes());
 
1125
    style->setWidth(Length(size.width(), Fixed));
 
1126
    style->setHeight(Length(size.height(), Fixed));
 
1127
}
 
1128
 
 
1129
bool RenderThemeSafari::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect&)
 
1130
{
 
1131
    ASSERT(SafariThemeLibrary());
 
1132
 
 
1133
    Node* input = o->node()->shadowHost();
 
1134
    if (!input)
 
1135
        input = o->node();
 
1136
    RenderObject* renderer = input->renderer();
 
1137
    ASSERT(renderer);
 
1138
 
 
1139
    IntRect searchRect = renderer->absoluteBoundingBoxRectIgnoringTransforms();
 
1140
 
 
1141
    paintThemePart(SafariTheme::SearchFieldResultsDecorationPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o));
 
1142
    return false;
 
1143
}
 
1144
 
 
1145
const int resultsArrowWidth = 5;
 
1146
void RenderThemeSafari::adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
 
1147
{
 
1148
    IntSize size = sizeForSystemFont(style, resultsButtonSizes());
 
1149
    style->setWidth(Length(size.width() + resultsArrowWidth, Fixed));
 
1150
    style->setHeight(Length(size.height(), Fixed));
 
1151
}
 
1152
 
 
1153
bool RenderThemeSafari::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect&)
 
1154
{
 
1155
    ASSERT(SafariThemeLibrary());
 
1156
 
 
1157
    Node* input = o->node()->shadowHost();
 
1158
    if (!input)
 
1159
        input = o->node();
 
1160
    RenderObject* renderer = input->renderer();
 
1161
    ASSERT(renderer);
 
1162
 
 
1163
    IntRect searchRect = renderer->absoluteBoundingBoxRectIgnoringTransforms();
 
1164
 
 
1165
    paintThemePart(SafariTheme::SearchFieldResultsButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o));
 
1166
    return false;
 
1167
}
 
1168
#if ENABLE(VIDEO)
 
1169
bool RenderThemeSafari::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1170
{
 
1171
    return RenderMediaControls::paintMediaControlsPart(MediaEnterFullscreenButton, o, paintInfo, r);
 
1172
}
 
1173
 
 
1174
bool RenderThemeSafari::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1175
{
 
1176
    return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, o, paintInfo, r);
 
1177
}
 
1178
 
 
1179
bool RenderThemeSafari::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1180
{
 
1181
    return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, o, paintInfo, r);
 
1182
}
 
1183
 
 
1184
bool RenderThemeSafari::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1185
{
 
1186
    return RenderMediaControls::paintMediaControlsPart(MediaSeekBackButton, o, paintInfo, r);
 
1187
}
 
1188
 
 
1189
bool RenderThemeSafari::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1190
{
 
1191
    return RenderMediaControls::paintMediaControlsPart(MediaSeekForwardButton, o, paintInfo, r);
 
1192
}
 
1193
 
 
1194
bool RenderThemeSafari::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1195
{
 
1196
    return RenderMediaControls::paintMediaControlsPart(MediaSlider, o, paintInfo, r);
 
1197
}
 
1198
 
 
1199
bool RenderThemeSafari::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 
1200
{
 
1201
    return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, o, paintInfo, r);
 
1202
}
 
1203
#endif
 
1204
 
 
1205
} // namespace WebCore
 
1206
 
 
1207
#endif // #if USE(SAFARI_THEME)