26928accb1a2784490ade8e3b578f5efc1f8bb56
[WebKit-https.git] / Source / WebCore / platform / blackberry / RenderThemeBlackBerry.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc.
3  * Copyright (C) 2009 Google Inc.
4  * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "config.h"
22 #include "RenderThemeBlackBerry.h"
23
24 #include "CSSValueKeywords.h"
25 #include "Frame.h"
26 #include "HTMLMediaElement.h"
27 #include "HostWindow.h"
28 #include "MediaControlElements.h"
29 #include "MediaPlayerPrivateBlackBerry.h"
30 #include "Page.h"
31 #include "PaintInfo.h"
32 #include "RenderFullScreen.h"
33 #include "RenderProgress.h"
34 #include "RenderSlider.h"
35 #include "RenderView.h"
36 #include "UserAgentStyleSheets.h"
37
38 namespace WebCore {
39
40 // Sizes (unit px)
41 const unsigned smallRadius = 1;
42 const unsigned largeRadius = 3;
43 const unsigned lineWidth = 1;
44 const float marginSize = 4;
45 const float mediaControlsHeight = 32;
46 const float mediaSliderThumbWidth = 40;
47 const float mediaSliderThumbHeight = 13;
48 const float mediaSliderThumbRadius = 5;
49 const float sliderThumbWidth = 15;
50 const float sliderThumbHeight = 25;
51
52 // Checkbox check scalers
53 const float checkboxLeftX = 7 / 40.0;
54 const float checkboxLeftY = 1 / 2.0;
55 const float checkboxMiddleX = 19 / 50.0;
56 const float checkboxMiddleY = 7 / 25.0;
57 const float checkboxRightX = 33 / 40.0;
58 const float checkboxRightY = 1 / 5.0;
59 const float checkboxStrokeThickness = 6.5;
60
61 // Radio button scaler
62 const float radioButtonCheckStateScaler = 7 / 30.0;
63
64 // Multipliers
65 const unsigned paddingDivisor = 5;
66 const unsigned fullScreenEnlargementFactor = 2;
67 const float scaleFactorThreshold = 2.0;
68
69 // Colors
70 const RGBA32 caretBottom = 0xff2163bf;
71 const RGBA32 caretTop = 0xff69a5fa;
72
73 const RGBA32 regularBottom = 0xffdcdee4;
74 const RGBA32 regularTop = 0xfff7f2ee;
75 const RGBA32 hoverBottom = 0xffb5d3fc;
76 const RGBA32 hoverTop = 0xffcceaff;
77 const RGBA32 depressedBottom = 0xff3388ff;
78 const RGBA32 depressedTop = 0xff66a0f2;
79 const RGBA32 disabledBottom = 0xffe7e7e7;
80 const RGBA32 disabledTop = 0xffefefef;
81
82 const RGBA32 regularBottomOutline = 0xff6e7073;
83 const RGBA32 regularTopOutline = 0xffb9b8b8;
84 const RGBA32 hoverBottomOutline = 0xff2163bf;
85 const RGBA32 hoverTopOutline = 0xff69befa;
86 const RGBA32 depressedBottomOutline = 0xff0c3d81;
87 const RGBA32 depressedTopOutline = 0xff1d4d70;
88 const RGBA32 disabledOutline = 0xffd5d9de;
89
90 const RGBA32 progressRegularBottom = caretTop;
91 const RGBA32 progressRegularTop = caretBottom;
92
93 const RGBA32 rangeSliderRegularBottom = 0xfff6f2ee;
94 const RGBA32 rangeSliderRegularTop = 0xffdee0e5;
95 const RGBA32 rangeSliderRollBottom = 0xffc9e8fe;
96 const RGBA32 rangeSliderRollTop = 0xffb5d3fc;
97
98 const RGBA32 rangeSliderRegularBottomOutline = 0xffb9babd;
99 const RGBA32 rangeSliderRegularTopOutline = 0xffb7b7b7;
100 const RGBA32 rangeSliderRollBottomOutline = 0xff67abe0;
101 const RGBA32 rangeSliderRollTopOutline = 0xff69adf9;
102
103 const RGBA32 dragRegularLight = 0xfffdfdfd;
104 const RGBA32 dragRegularDark = 0xffbababa;
105 const RGBA32 dragRollLight = 0xfff2f2f2;
106 const RGBA32 dragRollDark = 0xff69a8ff;
107
108 const RGBA32 selection = 0xff2b8fff;
109
110 const RGBA32 blackPen = Color::black;
111 const RGBA32 focusRingPen = 0xffa3c8fe;
112
113 float RenderThemeBlackBerry::defaultFontSize = 16;
114
115 // We aim to match IE here.
116 // -IE uses a font based on the encoding as the default font for form controls.
117 // -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT),
118 // which returns MS Shell Dlg)
119 // -Safari uses Lucida Grande.
120 //
121 // FIXME: The only case where we know we don't match IE is for ANSI encodings.
122 // IE uses MS Shell Dlg there, which we render incorrectly at certain pixel
123 // sizes (e.g. 15px). So we just use Arial for now.
124 const String& RenderThemeBlackBerry::defaultGUIFont()
125 {
126     DEFINE_STATIC_LOCAL(String, fontFace, ("Arial"));
127     return fontFace;
128 }
129
130 static PassRefPtr<Gradient> createLinearGradient(RGBA32 top, RGBA32 bottom, const IntPoint& a, const IntPoint& b)
131 {
132     RefPtr<Gradient> gradient = Gradient::create(a, b);
133     gradient->addColorStop(0.0, Color(top));
134     gradient->addColorStop(1.0, Color(bottom));
135     return gradient.release();
136 }
137
138 static Path roundedRectForBorder(RenderObject* object, const IntRect& rect)
139 {
140     RenderStyle* style = object->style();
141     LengthSize topLeftRadius = style->borderTopLeftRadius();
142     LengthSize topRightRadius = style->borderTopRightRadius();
143     LengthSize bottomLeftRadius = style->borderBottomLeftRadius();
144     LengthSize bottomRightRadius = style->borderBottomRightRadius();
145
146     Path roundedRect;
147     roundedRect.addRoundedRect(rect, IntSize(topLeftRadius.width().value(), topLeftRadius.height().value()),
148                                      IntSize(topRightRadius.width().value(), topRightRadius.height().value()),
149                                      IntSize(bottomLeftRadius.width().value(), bottomLeftRadius.height().value()),
150                                      IntSize(bottomRightRadius.width().value(), bottomRightRadius.height().value()));
151     return roundedRect;
152 }
153
154 static RenderSlider* determineRenderSlider(RenderObject* object)
155 {
156     ASSERT(object->isSliderThumb());
157     // The RenderSlider is an ancestor of the slider thumb.
158     while (object && !object->isSlider())
159         object = object->parent();
160     return toRenderSlider(object);
161 }
162
163 static float determineFullScreenMultiplier(Element* element)
164 {
165     float fullScreenMultiplier = 1.0;
166 #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO)
167     if (element && element->document()->webkitIsFullScreen() && element->document()->webkitCurrentFullScreenElement() == toParentMediaElement(element)) {
168         if (element->document()->page()->deviceScaleFactor() < scaleFactorThreshold)
169             fullScreenMultiplier = fullScreenEnlargementFactor;
170
171         // The way the BlackBerry port implements the FULLSCREEN_API for media elements
172         // might result in the controls being oversized, proportionally to the current page
173         // scale. That happens because the fullscreen element gets sized to be as big as the
174         // viewport size, and the viewport size might get outstretched to fit to the screen dimensions.
175         // To fix that, lets strips out the Page scale factor from the media controls multiplier.
176         float scaleFactor = element->document()->view()->hostWindow()->platformPageClient()->currentZoomFactor();
177         static ViewportArguments defaultViewportArguments;
178         float scaleFactorFudge = 1 / element->document()->page()->deviceScaleFactor();
179         fullScreenMultiplier /= scaleFactor * scaleFactorFudge;
180     }
181 #endif
182     return fullScreenMultiplier;
183 }
184
185 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
186 {
187     static RenderTheme* theme = RenderThemeBlackBerry::create().leakRef();
188     return theme;
189 }
190
191 PassRefPtr<RenderTheme> RenderThemeBlackBerry::create()
192 {
193     return adoptRef(new RenderThemeBlackBerry());
194 }
195
196 RenderThemeBlackBerry::RenderThemeBlackBerry()
197 {
198 }
199
200 RenderThemeBlackBerry::~RenderThemeBlackBerry()
201 {
202 }
203
204 String RenderThemeBlackBerry::extraDefaultStyleSheet()
205 {
206     return String(themeBlackBerryUserAgentStyleSheet, sizeof(themeBlackBerryUserAgentStyleSheet));
207 }
208
209 #if ENABLE(VIDEO)
210 String RenderThemeBlackBerry::extraMediaControlsStyleSheet()
211 {
212     return String(mediaControlsBlackBerryUserAgentStyleSheet, sizeof(mediaControlsBlackBerryUserAgentStyleSheet));
213 }
214
215 String RenderThemeBlackBerry::formatMediaControlsRemainingTime(float, float duration) const
216 {
217     // This is a workaround to make the appearance of media time controller in
218     // in-page mode the same as in fullscreen mode.
219     return formatMediaControlsTime(duration);
220 }
221 #endif
222
223 double RenderThemeBlackBerry::caretBlinkInterval() const
224 {
225     return 0; // Turn off caret blinking.
226 }
227
228 void RenderThemeBlackBerry::systemFont(int propId, FontDescription& fontDescription) const
229 {
230     float fontSize = defaultFontSize;
231
232     if (propId == CSSValueWebkitMiniControl || propId ==  CSSValueWebkitSmallControl || propId == CSSValueWebkitControl) {
233         // Why 2 points smaller? Because that's what Gecko does. Note that we
234         // are assuming a 96dpi screen, which is the default value we use on Windows.
235         static const float pointsPerInch = 72.0f;
236         static const float pixelsPerInch = 96.0f;
237         fontSize -= (2.0f / pointsPerInch) * pixelsPerInch;
238     }
239
240     fontDescription.firstFamily().setFamily(defaultGUIFont());
241     fontDescription.setSpecifiedSize(fontSize);
242     fontDescription.setIsAbsoluteSize(true);
243     fontDescription.setGenericFamily(FontDescription::NoFamily);
244     fontDescription.setWeight(FontWeightNormal);
245     fontDescription.setItalic(false);
246 }
247
248 void RenderThemeBlackBerry::setButtonStyle(RenderStyle* style) const
249 {
250     Length vertPadding(int(style->fontSize() / paddingDivisor), Fixed);
251     style->setPaddingTop(vertPadding);
252     style->setPaddingBottom(vertPadding);
253 }
254
255 void RenderThemeBlackBerry::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
256 {
257     setButtonStyle(style);
258     style->setCursor(CURSOR_WEBKIT_GRAB);
259 }
260
261 void RenderThemeBlackBerry::adjustTextAreaStyle(StyleResolver*, RenderStyle* style, Element*) const
262 {
263     setButtonStyle(style);
264 }
265
266 bool RenderThemeBlackBerry::paintTextArea(RenderObject* object, const PaintInfo& info, const IntRect& rect)
267 {
268     return paintTextFieldOrTextAreaOrSearchField(object, info, rect);
269 }
270
271 void RenderThemeBlackBerry::adjustTextFieldStyle(StyleResolver*, RenderStyle* style, Element*) const
272 {
273     setButtonStyle(style);
274 }
275
276 bool RenderThemeBlackBerry::paintTextFieldOrTextAreaOrSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
277 {
278     ASSERT(info.context);
279     GraphicsContext* context = info.context;
280
281     context->save();
282     context->setStrokeStyle(SolidStroke);
283     context->setStrokeThickness(lineWidth);
284     if (!isEnabled(object))
285         context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
286     else if (isPressed(object))
287         info.context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
288     else if (isHovered(object) || isFocused(object))
289         context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
290     else
291         context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
292
293     Path textFieldRoundedRectangle = roundedRectForBorder(object, rect);
294     if (object->style()->appearance() == SearchFieldPart) {
295         // We force the fill color to White so as to match the background color of the search cancel button graphic.
296         context->setFillColor(Color::white, ColorSpaceDeviceRGB);
297         context->fillPath(textFieldRoundedRectangle);
298         context->strokePath(textFieldRoundedRectangle);
299     } else
300         context->strokePath(textFieldRoundedRectangle);
301     context->restore();
302     return false;
303 }
304
305 bool RenderThemeBlackBerry::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
306 {
307     return paintTextFieldOrTextAreaOrSearchField(object, info, rect);
308 }
309
310 void RenderThemeBlackBerry::adjustSearchFieldStyle(StyleResolver*, RenderStyle* style, Element*) const
311 {
312     setButtonStyle(style);
313 }
314
315 void RenderThemeBlackBerry::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
316 {
317     static const float defaultControlFontPixelSize = 13;
318     static const float defaultCancelButtonSize = 9;
319     static const float minCancelButtonSize = 5;
320     static const float maxCancelButtonSize = 21;
321
322     // Scale the button size based on the font size
323     float fontScale = style->fontSize() / defaultControlFontPixelSize;
324     int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
325     Length length(cancelButtonSize, Fixed);
326     style->setWidth(length);
327     style->setHeight(length);
328 }
329
330 bool RenderThemeBlackBerry::paintSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
331 {
332     return paintTextFieldOrTextAreaOrSearchField(object, info, rect);
333 }
334
335 bool RenderThemeBlackBerry::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
336 {
337     ASSERT(object->parent());
338     if (!object->parent() || !object->parent()->isBox())
339         return false;
340
341     RenderBox* parentRenderBox = toRenderBox(object->parent());
342
343     IntRect parentBox = parentRenderBox->absoluteContentBox();
344     IntRect bounds = rect;
345     // Make sure the scaled button stays square and fits in its parent's box.
346     bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
347     bounds.setWidth(bounds.height());
348
349     // Put the button in the middle vertically, and round up the value.
350     // So if it has to be one pixel off-center, it would be one pixel closer
351     // to the bottom of the field. This would look better with the text.
352     bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
353
354     static Image* cancelImage = Image::loadPlatformResource("searchCancel").leakRef();
355     static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").leakRef();
356     paintInfo.context->drawImage(isPressed(object) ? cancelPressedImage : cancelImage, object->style()->colorSpace(), bounds);
357     return false;
358 }
359
360 void RenderThemeBlackBerry::adjustMenuListButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
361 {
362     // These seem to be reasonable padding values from observation.
363     const int paddingLeft = 8;
364     const int paddingRight = 4;
365
366     const int minHeight = style->fontSize() * 2;
367
368     style->resetPadding();
369     style->setHeight(Length(Auto));
370
371     style->setPaddingRight(Length(minHeight + paddingRight, Fixed));
372     style->setPaddingLeft(Length(paddingLeft, Fixed));
373     style->setCursor(CURSOR_WEBKIT_GRAB);
374 }
375
376 void RenderThemeBlackBerry::calculateButtonSize(RenderStyle* style) const
377 {
378     int size = style->fontSize();
379     Length length(size, Fixed);
380     if (style->appearance() == CheckboxPart || style->appearance() == RadioPart) {
381         style->setWidth(length);
382         style->setHeight(length);
383         return;
384     }
385
386     // If the width and height are both specified, then we have nothing to do.
387     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
388         return;
389
390     if (style->width().isIntrinsicOrAuto())
391         style->setWidth(length);
392
393     if (style->height().isAuto())
394         style->setHeight(length);
395 }
396
397 bool RenderThemeBlackBerry::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect)
398 {
399     return paintButton(object, info, rect);
400 }
401
402 void RenderThemeBlackBerry::setCheckboxSize(RenderStyle* style) const
403 {
404     calculateButtonSize(style);
405 }
406
407 bool RenderThemeBlackBerry::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect)
408 {
409     return paintButton(object, info, rect);
410 }
411
412 void RenderThemeBlackBerry::setRadioSize(RenderStyle* style) const
413 {
414     calculateButtonSize(style);
415 }
416
417 // If this function returns false, WebCore assumes the button is fully decorated
418 bool RenderThemeBlackBerry::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
419 {
420     ASSERT(info.context);
421     info.context->save();
422
423     info.context->setStrokeStyle(SolidStroke);
424     info.context->setStrokeThickness(lineWidth);
425
426     Color check(blackPen);
427     if (!isEnabled(object)) {
428         info.context->setFillGradient(createLinearGradient(disabledTop, disabledBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
429         info.context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
430     } else if (isPressed(object)) {
431         info.context->setFillGradient(createLinearGradient(depressedTop, depressedBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
432         info.context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
433     } else if (isHovered(object)) {
434         info.context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
435         info.context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
436     } else {
437         info.context->setFillGradient(createLinearGradient(regularTop, regularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
438         info.context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
439     }
440
441     ControlPart part = object->style()->appearance();
442     switch (part) {
443     case CheckboxPart: {
444         FloatSize smallCorner(smallRadius, smallRadius);
445         Path path;
446         path.addRoundedRect(rect, smallCorner);
447         info.context->fillPath(path);
448         info.context->strokePath(path);
449
450         if (isChecked(object)) {
451             Path checkPath;
452             IntRect rect2 = rect;
453             rect2.inflate(-1);
454             checkPath.moveTo(FloatPoint(rect2.x() + rect2.width() * checkboxLeftX, rect2.y() + rect2.height() * checkboxLeftY));
455             checkPath.addLineTo(FloatPoint(rect2.x() + rect2.width() * checkboxMiddleX, rect2.maxY() - rect2.height() * checkboxMiddleY));
456             checkPath.addLineTo(FloatPoint(rect2.x() + rect2.width() * checkboxRightX, rect2.y() + rect2.height() * checkboxRightY));
457             info.context->setLineCap(RoundCap);
458             info.context->setStrokeColor(blackPen, ColorSpaceDeviceRGB);
459             info.context->setStrokeThickness(rect2.width() / checkboxStrokeThickness);
460             info.context->fillPath(checkPath);
461             info.context->strokePath(checkPath);
462         }
463         break;
464     }
465     case RadioPart:
466         info.context->drawEllipse(rect);
467         if (isChecked(object)) {
468             IntRect rect2 = rect;
469             rect2.inflate(-rect.width() * radioButtonCheckStateScaler);
470             info.context->setFillColor(check, ColorSpaceDeviceRGB);
471             info.context->setStrokeColor(check, ColorSpaceDeviceRGB);
472             info.context->drawEllipse(rect2);
473         }
474         break;
475     case ButtonPart:
476     case PushButtonPart: {
477         FloatSize largeCorner(largeRadius, largeRadius);
478         Path path;
479         path.addRoundedRect(rect, largeCorner);
480         info.context->fillPath(path);
481         info.context->strokePath(path);
482         break;
483     }
484     case SquareButtonPart: {
485         Path path;
486         path.addRect(rect);
487         info.context->fillPath(path);
488         info.context->strokePath(path);
489         break;
490     }
491     default:
492         info.context->restore();
493         return true;
494     }
495
496     info.context->restore();
497     return false;
498 }
499
500 void RenderThemeBlackBerry::adjustMenuListStyle(StyleResolver* css, RenderStyle* style, Element* element) const
501 {
502     adjustMenuListButtonStyle(css, style, element);
503 }
504
505 void RenderThemeBlackBerry::adjustCheckboxStyle(StyleResolver*, RenderStyle* style, Element*) const
506 {
507     setCheckboxSize(style);
508     style->setBoxShadow(nullptr);
509     Length margin(marginSize, Fixed);
510     style->setMarginBottom(margin);
511     style->setMarginRight(margin);
512     style->setCursor(CURSOR_WEBKIT_GRAB);
513 }
514
515 void RenderThemeBlackBerry::adjustRadioStyle(StyleResolver*, RenderStyle* style, Element*) const
516 {
517     setRadioSize(style);
518     style->setBoxShadow(nullptr);
519     Length margin(marginSize, Fixed);
520     style->setMarginBottom(margin);
521     style->setMarginRight(margin);
522     style->setCursor(CURSOR_WEBKIT_GRAB);
523 }
524
525 void RenderThemeBlackBerry::paintMenuListButtonGradientAndArrow(GraphicsContext* context, RenderObject* object, IntRect buttonRect, const Path& clipPath)
526 {
527     ASSERT(context);
528     context->save();
529     if (!isEnabled(object))
530         context->setFillGradient(createLinearGradient(disabledTop, disabledBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
531     else if (isPressed(object))
532         context->setFillGradient(createLinearGradient(depressedTop, depressedBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
533     else if (isHovered(object))
534         context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
535     else
536         context->setFillGradient(createLinearGradient(regularTop, regularBottom, buttonRect.maxXMinYCorner(), buttonRect.maxXMaxYCorner()));
537
538     // 1. Paint the background of the button.
539     context->clip(clipPath);
540     context->drawRect(buttonRect);
541     context->restore();
542
543     // 2. Paint the button arrow.
544     buttonRect.inflate(-buttonRect.width() / 3);
545     buttonRect.move(0, buttonRect.height() * 7 / 20);
546     Path path;
547     path.moveTo(FloatPoint(buttonRect.x(), buttonRect.y()));
548     path.addLineTo(FloatPoint(buttonRect.x() + buttonRect.width(), buttonRect.y()));
549     path.addLineTo(FloatPoint(buttonRect.x() + buttonRect.width() / 2.0, buttonRect.y() + buttonRect.height() / 2.0));
550     path.closeSubpath();
551
552     context->save();
553     context->setStrokeStyle(SolidStroke);
554     context->setStrokeThickness(lineWidth);
555     context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
556     context->setFillColor(Color::black, ColorSpaceDeviceRGB);
557     context->setLineJoin(BevelJoin);
558     context->fillPath(path);
559     context->restore();
560 }
561
562 static IntRect computeMenuListArrowButtonRect(const IntRect& rect)
563 {
564     // FIXME: The menu list arrow button should have a minimum and maximum width (to ensure usability) or
565     // scale with respect to the font size used in the menu list control or some combination of both.
566     return IntRect(IntPoint(rect.maxX() - rect.height(), rect.y()), IntSize(rect.height(), rect.height()));
567 }
568
569 static void paintMenuListBackground(GraphicsContext* context, const Path& menuListPath, const Color& backgroundColor)
570 {
571     ASSERT(context);
572     context->save();
573     context->setFillColor(backgroundColor, ColorSpaceDeviceRGB);
574     context->fillPath(menuListPath);
575     context->restore();
576 }
577
578 bool RenderThemeBlackBerry::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
579 {
580     // Note, this method is not called if the menu list explicitly specifies either a border or background color.
581     // Instead, RenderThemeBlackBerry::paintMenuListButton is called. Therefore, when this method is called, we don't
582     // have to adjust rect with respect to the border dimensions.
583
584     ASSERT(info.context);
585     GraphicsContext* context = info.context;
586
587     Path menuListRoundedRectangle = roundedRectForBorder(object, rect);
588
589     // 1. Paint the background of the entire control.
590     paintMenuListBackground(context, menuListRoundedRectangle, Color::white);
591
592     // 2. Paint the background of the button and its arrow.
593     IntRect arrowButtonRectangle = computeMenuListArrowButtonRect(rect);
594     paintMenuListButtonGradientAndArrow(context, object, arrowButtonRectangle, menuListRoundedRectangle);
595
596     // 4. Stroke an outline around the entire control.
597     context->save();
598     context->setStrokeStyle(SolidStroke);
599     context->setStrokeThickness(lineWidth);
600     if (!isEnabled(object))
601         context->setStrokeColor(disabledOutline, ColorSpaceDeviceRGB);
602     else if (isPressed(object))
603         context->setStrokeGradient(createLinearGradient(depressedTopOutline, depressedBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
604     else if (isHovered(object))
605         context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
606     else
607         context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
608
609     context->strokePath(menuListRoundedRectangle);
610     context->restore();
611     return false;
612 }
613
614 bool RenderThemeBlackBerry::paintMenuListButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
615 {
616     // Note, this method is only called if the menu list explicitly specifies either a border or background color.
617     // Otherwise, RenderThemeBlackBerry::paintMenuList is called. We need to fit the arrow button with the border box
618     // of the menu-list so as to not occlude the custom border.
619
620     // We compute menuListRoundedRectangle with respect to the dimensions of the entire menu-list control (i.e. rect) and
621     // its border radius so that we clip the contour of the arrow button (when we paint it below) to match the contour of
622     // the control.
623     Path menuListRoundedRectangle = roundedRectForBorder(object, rect);
624
625     // 1. Paint the background of the entire control.
626     Color fillColor = object->style()->visitedDependentColor(CSSPropertyBackgroundColor);
627     if (!fillColor.isValid())
628         fillColor = Color::white;
629     paintMenuListBackground(info.context, menuListRoundedRectangle, fillColor);
630
631     // 2. Paint the background of the button and its arrow.
632     IntRect bounds = IntRect(rect.x() + object->style()->borderLeftWidth(),
633                          rect.y() + object->style()->borderTopWidth(),
634                          rect.width() - object->style()->borderLeftWidth() - object->style()->borderRightWidth(),
635                          rect.height() - object->style()->borderTopWidth() - object->style()->borderBottomWidth());
636
637     IntRect arrowButtonRectangle = computeMenuListArrowButtonRect(bounds); // Fit the arrow button within the border box of the menu-list.
638     paintMenuListButtonGradientAndArrow(info.context, object, arrowButtonRectangle, menuListRoundedRectangle);
639     return false;
640 }
641
642 void RenderThemeBlackBerry::adjustSliderThumbSize(RenderStyle* style, Element* element) const
643 {
644     float fullScreenMultiplier = 1;
645     ControlPart part = style->appearance();
646
647     if (part == MediaSliderThumbPart || part == MediaVolumeSliderThumbPart) {
648         RenderSlider* slider = determineRenderSlider(element->renderer());
649         if (slider)
650             fullScreenMultiplier = determineFullScreenMultiplier(toElement(slider->node()));
651     }
652
653     if (part == MediaVolumeSliderThumbPart || part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
654         style->setWidth(Length((part == SliderThumbVerticalPart ? sliderThumbHeight : sliderThumbWidth) * fullScreenMultiplier, Fixed));
655         style->setHeight(Length((part == SliderThumbVerticalPart ? sliderThumbWidth : sliderThumbHeight) * fullScreenMultiplier, Fixed));
656     } else if (part == MediaSliderThumbPart) {
657         style->setWidth(Length(mediaSliderThumbWidth * fullScreenMultiplier, Fixed));
658         style->setHeight(Length(mediaSliderThumbHeight * fullScreenMultiplier, Fixed));
659     }
660 }
661
662 bool RenderThemeBlackBerry::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
663 {
664     const static int SliderTrackHeight = 5;
665     IntRect rect2;
666     if (object->style()->appearance() == SliderHorizontalPart) {
667         rect2.setHeight(SliderTrackHeight);
668         rect2.setWidth(rect.width());
669         rect2.setX(rect.x());
670         rect2.setY(rect.y() + (rect.height() - SliderTrackHeight) / 2);
671     } else {
672         rect2.setHeight(rect.height());
673         rect2.setWidth(SliderTrackHeight);
674         rect2.setX(rect.x() + (rect.width() - SliderTrackHeight) / 2);
675         rect2.setY(rect.y());
676     }
677     return paintSliderTrackRect(object, info, rect2);
678 }
679
680 bool RenderThemeBlackBerry::paintSliderTrackRect(RenderObject* object, const PaintInfo& info, const IntRect& rect)
681 {
682     return paintSliderTrackRect(object, info, rect, rangeSliderRegularTopOutline, rangeSliderRegularBottomOutline,
683                 rangeSliderRegularTop, rangeSliderRegularBottom);
684 }
685
686 bool RenderThemeBlackBerry::paintSliderTrackRect(RenderObject* object, const PaintInfo& info, const IntRect& rect,
687         RGBA32 strokeColorStart, RGBA32 strokeColorEnd, RGBA32 fillColorStart, RGBA32 fillColorEnd)
688 {
689     FloatSize smallCorner(smallRadius, smallRadius);
690
691     info.context->save();
692     info.context->setStrokeStyle(SolidStroke);
693     info.context->setStrokeThickness(lineWidth);
694
695     info.context->setStrokeGradient(createLinearGradient(strokeColorStart, strokeColorEnd, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
696     info.context->setFillGradient(createLinearGradient(fillColorStart, fillColorEnd, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
697
698     Path path;
699     path.addRoundedRect(rect, smallCorner);
700     info.context->fillPath(path);
701
702     info.context->restore();
703     return false;
704 }
705
706 bool RenderThemeBlackBerry::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
707 {
708     FloatSize largeCorner(largeRadius, largeRadius);
709
710     info.context->save();
711     info.context->setStrokeStyle(SolidStroke);
712     info.context->setStrokeThickness(lineWidth);
713
714     if (isPressed(object) || isHovered(object)) {
715         info.context->setStrokeGradient(createLinearGradient(hoverTopOutline, hoverBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
716         info.context->setFillGradient(createLinearGradient(hoverTop, hoverBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
717     } else {
718         info.context->setStrokeGradient(createLinearGradient(regularTopOutline, regularBottomOutline, rect.maxXMinYCorner(), rect. maxXMaxYCorner()));
719         info.context->setFillGradient(createLinearGradient(regularTop, regularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
720     }
721
722     Path path;
723     path.addRoundedRect(rect, largeCorner);
724     info.context->fillPath(path);
725
726     bool isVertical = rect.width() > rect.height();
727     IntPoint startPoint(rect.x() + (isVertical ? 5 : 2), rect.y() + (isVertical ? 2 : 5));
728     IntPoint endPoint(rect.x() + (isVertical ? 20 : 2), rect.y() + (isVertical ? 2 : 20));
729     const int lineOffset = 2;
730     const int shadowOffset = 1;
731
732     for (int i = 0; i < 3; i++) {
733         if (isVertical) {
734             startPoint.setY(startPoint.y() + lineOffset);
735             endPoint.setY(endPoint.y() + lineOffset);
736         } else {
737             startPoint.setX(startPoint.x() + lineOffset);
738             endPoint.setX(endPoint.x() + lineOffset);
739         }
740         if (isPressed(object) || isHovered(object))
741             info.context->setStrokeColor(dragRollLight, ColorSpaceDeviceRGB);
742         else
743             info.context->setStrokeColor(dragRegularLight, ColorSpaceDeviceRGB);
744         info.context->drawLine(startPoint, endPoint);
745
746         if (isVertical) {
747             startPoint.setY(startPoint.y() + shadowOffset);
748             endPoint.setY(endPoint.y() + shadowOffset);
749         } else {
750             startPoint.setX(startPoint.x() + shadowOffset);
751             endPoint.setX(endPoint.x() + shadowOffset);
752         }
753         if (isPressed(object) || isHovered(object))
754             info.context->setStrokeColor(dragRollDark, ColorSpaceDeviceRGB);
755         else
756             info.context->setStrokeColor(dragRegularDark, ColorSpaceDeviceRGB);
757         info.context->drawLine(startPoint, endPoint);
758     }
759     info.context->restore();
760     return false;
761 }
762
763 void RenderThemeBlackBerry::adjustMediaControlStyle(StyleResolver*, RenderStyle* style, Element* element) const
764 {
765     float fullScreenMultiplier = determineFullScreenMultiplier(element);
766
767     // We use multiples of mediaControlsHeight to make all objects scale evenly
768     Length controlsHeight(mediaControlsHeight * fullScreenMultiplier, Fixed);
769     Length timeWidth(mediaControlsHeight * 3 / 2 * fullScreenMultiplier, Fixed);
770     Length volumeHeight(mediaControlsHeight * 4 * fullScreenMultiplier, Fixed);
771     Length padding(mediaControlsHeight / 8 * fullScreenMultiplier, Fixed);
772     float fontSize = mediaControlsHeight / 2 * fullScreenMultiplier;
773
774     switch (style->appearance()) {
775     case MediaPlayButtonPart:
776     case MediaEnterFullscreenButtonPart:
777     case MediaExitFullscreenButtonPart:
778     case MediaMuteButtonPart:
779         style->setWidth(controlsHeight);
780         style->setHeight(controlsHeight);
781         break;
782     case MediaCurrentTimePart:
783     case MediaTimeRemainingPart:
784         style->setWidth(timeWidth);
785         style->setHeight(controlsHeight);
786         style->setPaddingRight(padding);
787         style->setBlendedFontSize(fontSize);
788         break;
789     case MediaVolumeSliderContainerPart:
790         style->setWidth(controlsHeight);
791         style->setHeight(volumeHeight);
792         style->setBottom(controlsHeight);
793         break;
794     default:
795         break;
796     }
797 }
798
799 void RenderThemeBlackBerry::adjustSliderTrackStyle(StyleResolver*, RenderStyle* style, Element* element) const
800 {
801     float fullScreenMultiplier = determineFullScreenMultiplier(element);
802
803     // We use multiples of mediaControlsHeight to make all objects scale evenly
804     Length controlsHeight(mediaControlsHeight * fullScreenMultiplier, Fixed);
805     Length volumeHeight(mediaControlsHeight * 4 * fullScreenMultiplier, Fixed);
806     switch (style->appearance()) {
807     case MediaSliderPart:
808         style->setHeight(controlsHeight);
809         break;
810     case MediaVolumeSliderPart:
811         style->setWidth(controlsHeight);
812         style->setHeight(volumeHeight);
813         break;
814     case MediaFullScreenVolumeSliderPart:
815     default:
816         break;
817     }
818 }
819
820 static bool paintMediaButton(GraphicsContext* context, const IntRect& rect, Image* image)
821 {
822     context->drawImage(image, ColorSpaceDeviceRGB, rect);
823     return false;
824 }
825
826 bool RenderThemeBlackBerry::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
827 {
828 #if ENABLE(VIDEO)
829     HTMLMediaElement* mediaElement = toParentMediaElement(object);
830
831     if (!mediaElement)
832         return false;
833
834     static Image* mediaPlay = Image::loadPlatformResource("play").leakRef();
835     static Image* mediaPause = Image::loadPlatformResource("pause").leakRef();
836
837     return paintMediaButton(paintInfo.context, rect, mediaElement->canPlay() ? mediaPlay : mediaPause);
838 #else
839     UNUSED_PARAM(object);
840     UNUSED_PARAM(paintInfo);
841     UNUSED_PARAM(rect);
842     return false;
843 #endif
844 }
845
846 bool RenderThemeBlackBerry::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
847 {
848 #if ENABLE(VIDEO)
849     HTMLMediaElement* mediaElement = toParentMediaElement(object);
850
851     if (!mediaElement)
852         return false;
853
854     static Image* mediaMute = Image::loadPlatformResource("speaker").leakRef();
855     static Image* mediaUnmute = Image::loadPlatformResource("speaker_mute").leakRef();
856
857     return paintMediaButton(paintInfo.context, rect, mediaElement->muted() || !mediaElement->volume() ? mediaUnmute : mediaMute);
858 #else
859     UNUSED_PARAM(object);
860     UNUSED_PARAM(paintInfo);
861     UNUSED_PARAM(rect);
862     return false;
863 #endif
864 }
865
866 bool RenderThemeBlackBerry::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
867 {
868 #if ENABLE(VIDEO)
869     HTMLMediaElement* mediaElement = toParentMediaElement(object);
870     if (!mediaElement)
871         return false;
872
873     static Image* mediaEnterFullscreen = Image::loadPlatformResource("fullscreen").leakRef();
874     static Image* mediaExitFullscreen = Image::loadPlatformResource("exit_fullscreen").leakRef();
875
876     Image* buttonImage = mediaEnterFullscreen;
877 #if ENABLE(FULLSCREEN_API)
878     if (mediaElement->document()->webkitIsFullScreen() && mediaElement->document()->webkitCurrentFullScreenElement() == mediaElement)
879         buttonImage = mediaExitFullscreen;
880 #endif
881     return paintMediaButton(paintInfo.context, rect, buttonImage);
882 #else
883     UNUSED_PARAM(object);
884     UNUSED_PARAM(paintInfo);
885     UNUSED_PARAM(rect);
886     return false;
887 #endif
888 }
889
890 bool RenderThemeBlackBerry::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
891 {
892 #if ENABLE(VIDEO)
893     HTMLMediaElement* mediaElement = toParentMediaElement(object);
894     if (!mediaElement)
895         return false;
896
897     float fullScreenMultiplier = determineFullScreenMultiplier(mediaElement);
898     float loaded = 0;
899     // FIXME: replace loaded with commented out one when buffer bug is fixed (see comment in
900     // MediaPlayerPrivateMMrenderer::percentLoaded).
901     // loaded = mediaElement->percentLoaded();
902     if (mediaElement->player() && mediaElement->player()->implementation())
903         loaded = static_cast<MediaPlayerPrivate *>(mediaElement->player()->implementation())->percentLoaded();
904     float position = mediaElement->duration() > 0 ? (mediaElement->currentTime() / mediaElement->duration()) : 0;
905
906     int x = ceil(rect.x() + 2 * fullScreenMultiplier - fullScreenMultiplier / 2);
907     int y = ceil(rect.y() + 14 * fullScreenMultiplier + fullScreenMultiplier / 2);
908     int w = ceil(rect.width() - 4 * fullScreenMultiplier + fullScreenMultiplier / 2);
909     int h = ceil(2 * fullScreenMultiplier);
910     IntRect rect2(x, y, w, h);
911
912     int wPlayed = ceil(w * position);
913     int wLoaded = ceil((w - mediaSliderThumbWidth * fullScreenMultiplier) * loaded + mediaSliderThumbWidth * fullScreenMultiplier);
914
915     IntRect played(x, y, wPlayed, h);
916     IntRect buffered(x, y, wLoaded, h);
917
918     // This is to paint main slider bar.
919     bool result = paintSliderTrackRect(object, paintInfo, rect2);
920
921     if (loaded > 0 || position > 0) {
922         // This is to paint buffered bar.
923         paintSliderTrackRect(object, paintInfo, buffered, Color::darkGray, Color::darkGray, Color::darkGray, Color::darkGray);
924
925         // This is to paint played part of bar (left of slider thumb) using selection color.
926         paintSliderTrackRect(object, paintInfo, played, selection, selection, selection, selection);
927     }
928     return result;
929
930 #else
931     UNUSED_PARAM(object);
932     UNUSED_PARAM(paintInfo);
933     UNUSED_PARAM(rect);
934     return false;
935 #endif
936 }
937
938 bool RenderThemeBlackBerry::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
939 {
940 #if ENABLE(VIDEO)
941     RenderSlider* slider = determineRenderSlider(object);
942     if (!slider)
943         return false;
944
945     float fullScreenMultiplier = determineFullScreenMultiplier(toElement(slider->node()));
946
947     paintInfo.context->save();
948     Path mediaThumbRoundedRectangle;
949     mediaThumbRoundedRectangle.addRoundedRect(rect, FloatSize(mediaSliderThumbRadius * fullScreenMultiplier, mediaSliderThumbRadius * fullScreenMultiplier));
950     paintInfo.context->setStrokeStyle(SolidStroke);
951     paintInfo.context->setStrokeThickness(0.5);
952     paintInfo.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
953
954     if (isPressed(object) || isHovered(object) || slider->inDragMode()) {
955         paintInfo.context->setFillGradient(createLinearGradient(selection, Color(selection).dark().rgb(),
956                 rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
957     } else {
958         paintInfo.context->setFillGradient(createLinearGradient(Color::white, Color(Color::white).dark().rgb(),
959                 rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
960     }
961     paintInfo.context->fillPath(mediaThumbRoundedRectangle);
962     paintInfo.context->restore();
963
964     return true;
965 #else
966     UNUSED_PARAM(object);
967     UNUSED_PARAM(paintInfo);
968     UNUSED_PARAM(rect);
969     return false;
970 #endif
971 }
972
973 bool RenderThemeBlackBerry::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
974 {
975 #if ENABLE(VIDEO)
976     float pad = rect.width() * 0.45;
977     float x = rect.x() + pad;
978     float y = rect.y() + pad;
979     float width = rect.width() * 0.1;
980     float height = rect.height() - (2.0 * pad);
981
982     IntRect rect2(x, y, width, height);
983
984     return paintSliderTrackRect(object, paintInfo, rect2);
985 #else
986     UNUSED_PARAM(object);
987     UNUSED_PARAM(paintInfo);
988     UNUSED_PARAM(rect);
989     return false;
990 #endif
991 }
992
993 bool RenderThemeBlackBerry::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
994 {
995 #if ENABLE(VIDEO)
996     static Image* mediaVolumeThumb = Image::loadPlatformResource("volume_thumb").leakRef();
997
998     return paintMediaButton(paintInfo.context, rect, mediaVolumeThumb);
999 #else
1000     UNUSED_PARAM(object);
1001     UNUSED_PARAM(paintInfo);
1002     UNUSED_PARAM(rect);
1003     return false;
1004 #endif
1005 }
1006
1007 Color RenderThemeBlackBerry::platformFocusRingColor() const
1008 {
1009     return focusRingPen;
1010 }
1011
1012 #if ENABLE(TOUCH_EVENTS)
1013 Color RenderThemeBlackBerry::platformTapHighlightColor() const
1014 {
1015     return Color(0, 168, 223, 50);
1016 }
1017 #endif
1018
1019 Color RenderThemeBlackBerry::platformActiveSelectionBackgroundColor() const
1020 {
1021     return Color(0, 168, 223, 50);
1022 }
1023
1024 double RenderThemeBlackBerry::animationRepeatIntervalForProgressBar(RenderProgress* renderProgress) const
1025 {
1026     return renderProgress->isDeterminate() ? 0.0 : 0.1;
1027 }
1028
1029 double RenderThemeBlackBerry::animationDurationForProgressBar(RenderProgress* renderProgress) const
1030 {
1031     return renderProgress->isDeterminate() ? 0.0 : 2.0;
1032 }
1033
1034 bool RenderThemeBlackBerry::paintProgressBar(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1035 {
1036     if (!object->isProgress())
1037         return true;
1038
1039     RenderProgress* renderProgress = toRenderProgress(object);
1040
1041     FloatSize smallCorner(smallRadius, smallRadius);
1042
1043     info.context->save();
1044     info.context->setStrokeStyle(SolidStroke);
1045     info.context->setStrokeThickness(lineWidth);
1046
1047     info.context->setStrokeGradient(createLinearGradient(rangeSliderRegularTopOutline, rangeSliderRegularBottomOutline, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
1048     info.context->setFillGradient(createLinearGradient(rangeSliderRegularTop, rangeSliderRegularBottom, rect.maxXMinYCorner(), rect.maxXMaxYCorner()));
1049
1050     Path path;
1051     path.addRoundedRect(rect, smallCorner);
1052     info.context->fillPath(path);
1053
1054     IntRect rect2 = rect;
1055     rect2.setX(rect2.x() + 1);
1056     rect2.setHeight(rect2.height() - 2);
1057     rect2.setY(rect2.y() + 1);
1058     info.context->setStrokeStyle(NoStroke);
1059     info.context->setStrokeThickness(0);
1060     if (renderProgress->isDeterminate()) {
1061         rect2.setWidth(rect2.width() * renderProgress->position() - 2);
1062         info.context->setFillGradient(createLinearGradient(progressRegularTop, progressRegularBottom, rect2.maxXMinYCorner(), rect2.maxXMaxYCorner()));
1063     } else {
1064         // Animating
1065         rect2.setWidth(rect2.width() - 2);
1066         RefPtr<Gradient> gradient = Gradient::create(rect2.minXMaxYCorner(), rect2.maxXMaxYCorner());
1067         gradient->addColorStop(0.0, Color(progressRegularBottom));
1068         gradient->addColorStop(renderProgress->animationProgress(), Color(progressRegularTop));
1069         gradient->addColorStop(1.0, Color(progressRegularBottom));
1070         info.context->setFillGradient(gradient);
1071     }
1072     Path path2;
1073     path2.addRoundedRect(rect2, smallCorner);
1074     info.context->fillPath(path2);
1075
1076     info.context->restore();
1077     return false;
1078 }
1079
1080 Color RenderThemeBlackBerry::platformActiveTextSearchHighlightColor() const
1081 {
1082     return Color(255, 150, 50); // Orange.
1083 }
1084
1085 Color RenderThemeBlackBerry::platformInactiveTextSearchHighlightColor() const
1086 {
1087     return Color(255, 255, 0); // Yellow.
1088 }
1089
1090 } // namespace WebCore