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