1/*
2 * This file is part of the WebKit project.
3 *
4 * Copyright (C) 2006, 2007 Apple Computer, Inc.
5 * Copyright (C) 2007-2009 Torch Mobile, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "RenderThemeWinCE.h"
26
27#include "CSSStyleSheet.h"
28#include "CSSValueKeywords.h"
29#include "Document.h"
30#include "GraphicsContext.h"
31#if ENABLE(VIDEO)
32#include "HTMLMediaElement.h"
33#endif
34#include "NotImplemented.h"
35#include "PaintInfo.h"
36
37#include <windows.h>
38
39/*
40 * The following constants are used to determine how a widget is drawn using
41 * Windows' Theme API. For more information on theme parts and states see
42 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
43 */
44#define THEME_COLOR 204
45#define THEME_FONT  210
46
47// Generic state constants
48#define TS_NORMAL    1
49#define TS_HOVER     2
50#define TS_ACTIVE    3
51#define TS_DISABLED  4
52#define TS_FOCUSED   5
53
54// Button constants
55#define BP_BUTTON    1
56#define BP_RADIO     2
57#define BP_CHECKBOX  3
58
59// Textfield constants
60#define TFP_TEXTFIELD 1
61#define TFS_READONLY  6
62
63typedef HANDLE (WINAPI*openThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList);
64typedef HRESULT (WINAPI*closeThemeDataPtr)(HANDLE hTheme);
65typedef HRESULT (WINAPI*drawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId,
66                                          int iStateId, const RECT *pRect,
67                                          const RECT* pClipRect);
68typedef HRESULT (WINAPI*drawThemeEdgePtr)(HANDLE hTheme, HDC hdc, int iPartId,
69                                          int iStateId, const RECT *pRect,
70                                          unsigned uEdge, unsigned uFlags,
71                                          const RECT* pClipRect);
72typedef HRESULT (WINAPI*getThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId,
73                                          int iStateId, const RECT* pRect,
74                                          RECT* pContentRect);
75typedef HRESULT (WINAPI*getThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId,
76                                       int iStateId, RECT* prc, int ts,
77                                       SIZE* psz);
78typedef HRESULT (WINAPI*getThemeSysFontPtr)(HANDLE hTheme, int iFontId, OUT LOGFONT* pFont);
79typedef HRESULT (WINAPI*getThemeColorPtr)(HANDLE hTheme, HDC hdc, int iPartId,
80                                   int iStateId, int iPropId, OUT COLORREF* pFont);
81
82namespace WebCore {
83
84static const int dropDownButtonWidth = 17;
85static const int trackWidth = 4;
86
87PassRefPtr<RenderTheme> RenderThemeWinCE::create()
88{
89    return adoptRef(new RenderThemeWinCE);
90}
91
92PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
93{
94    static RenderTheme* winceTheme = RenderThemeWinCE::create().releaseRef();
95    return winceTheme;
96}
97
98RenderThemeWinCE::RenderThemeWinCE()
99{
100}
101
102RenderThemeWinCE::~RenderThemeWinCE()
103{
104}
105
106Color RenderThemeWinCE::platformActiveSelectionBackgroundColor() const
107{
108    COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
109    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
110}
111
112Color RenderThemeWinCE::platformInactiveSelectionBackgroundColor() const
113{
114    COLORREF color = GetSysColor(COLOR_GRAYTEXT);
115    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
116}
117
118Color RenderThemeWinCE::platformActiveSelectionForegroundColor() const
119{
120    COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
121    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
122}
123
124Color RenderThemeWinCE::platformInactiveSelectionForegroundColor() const
125{
126    return Color::white;
127}
128
129bool RenderThemeWinCE::supportsFocus(ControlPart appearance) const
130{
131    switch (appearance) {
132    case PushButtonPart:
133    case ButtonPart:
134    case TextFieldPart:
135    case TextAreaPart:
136        return true;
137    default:
138        return false;
139    }
140
141    return false;
142}
143
144bool RenderThemeWinCE::supportsFocusRing(const RenderStyle *style) const
145{
146    return supportsFocus(style->appearance());
147}
148
149unsigned RenderThemeWinCE::determineClassicState(RenderObject* o)
150{
151    unsigned result = 0;
152    if (!isEnabled(o) || isReadOnlyControl(o))
153        result = DFCS_INACTIVE;
154    else if (isPressed(o)) // Active supersedes hover
155        result = DFCS_PUSHED;
156
157    if (isChecked(o))
158        result |= DFCS_CHECKED;
159    return result;
160}
161
162ThemeData RenderThemeWinCE::getThemeData(RenderObject* o)
163{
164    ThemeData result;
165    switch (o->style()->appearance()) {
166    case PushButtonPart:
167    case ButtonPart:
168        result.m_part = BP_BUTTON;
169        result.m_classicState = DFCS_BUTTONPUSH;
170        break;
171    case CheckboxPart:
172        result.m_part = BP_CHECKBOX;
173        result.m_classicState = DFCS_BUTTONCHECK;
174        break;
175    case RadioPart:
176        result.m_part = BP_RADIO;
177        result.m_classicState = DFCS_BUTTONRADIO;
178        break;
179    case ListboxPart:
180    case MenulistPart:
181    case TextFieldPart:
182    case TextAreaPart:
183        result.m_part = TFP_TEXTFIELD;
184        break;
185    }
186
187    result.m_classicState |= determineClassicState(o);
188
189    return result;
190}
191
192bool RenderThemeWinCE::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
193{
194    // Get the correct theme data for a button
195    ThemeData themeData = getThemeData(o);
196
197    // Now paint the button.
198    i.context->drawFrameControl(r, DFC_BUTTON, themeData.m_classicState);
199    if (isFocused(o)) {
200        if (themeData.m_part == BP_BUTTON) {
201            IntRect focusRect(r);
202            focusRect.inflate(-2);
203            i.context->drawFocusRect(focusRect);
204        } else
205            i.context->drawFocusRect(r);
206    }
207
208    return false;
209}
210
211void RenderThemeWinCE::setCheckboxSize(RenderStyle* style) const
212{
213    // If the width and height are both specified, then we have nothing to do.
214    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
215        return;
216
217    // FIXME:  A hard-coded size of 13 is used.  This is wrong but necessary for now.  It matches Firefox.
218    // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
219    // the higher DPI.  Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
220    // metrics.
221    if (style->width().isIntrinsicOrAuto())
222        style->setWidth(Length(13, Fixed));
223    if (style->height().isAuto())
224        style->setHeight(Length(13, Fixed));
225}
226
227bool RenderThemeWinCE::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
228{
229    // Get the correct theme data for a textfield
230    ThemeData themeData = getThemeData(o);
231
232    // Now paint the text field.
233    i.context->paintTextField(r, themeData.m_classicState);
234
235    return false;
236}
237
238void RenderThemeWinCE::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
239{
240    style->resetBorder();
241    adjustMenuListButtonStyle(selector, style, e);
242}
243
244bool RenderThemeWinCE::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
245{
246    paintTextField(o, i, r);
247    paintMenuListButton(o, i, r);
248    return true;
249}
250
251bool RenderThemeWinCE::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
252{
253    IntRect buttonRect(r.maxX() - dropDownButtonWidth - 1, r.y(), dropDownButtonWidth, r.height());
254    buttonRect.inflateY(-1);
255    i.context->drawFrameControl(buttonRect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | determineClassicState(o));
256    return true;
257}
258
259void RenderThemeWinCE::systemFont(int propId, FontDescription& fontDescription) const
260{
261    notImplemented();
262}
263
264void RenderThemeWinCE::themeChanged()
265{
266}
267
268String RenderThemeWinCE::extraDefaultStyleSheet()
269{
270    notImplemented();
271    return String();
272}
273
274String RenderThemeWinCE::extraQuirksStyleSheet()
275{
276    notImplemented();
277    return String();
278}
279
280bool RenderThemeWinCE::supportsHover(const RenderStyle*) const
281{
282    return false;
283}
284
285// Map a CSSValue* system color to an index understood by GetSysColor
286static int cssValueIdToSysColorIndex(int cssValueId)
287{
288    switch (cssValueId) {
289    case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
290    case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
291    case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
292    case CSSValueBackground: return COLOR_BACKGROUND;
293    case CSSValueButtonface: return COLOR_BTNFACE;
294    case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
295    case CSSValueButtonshadow: return COLOR_BTNSHADOW;
296    case CSSValueButtontext: return COLOR_BTNTEXT;
297    case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
298    case CSSValueGraytext: return COLOR_GRAYTEXT;
299    case CSSValueHighlight: return COLOR_HIGHLIGHT;
300    case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
301    case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
302    case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
303    case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
304    case CSSValueInfobackground: return COLOR_INFOBK;
305    case CSSValueInfotext: return COLOR_INFOTEXT;
306    case CSSValueMenu: return COLOR_MENU;
307    case CSSValueMenutext: return COLOR_MENUTEXT;
308    case CSSValueScrollbar: return COLOR_SCROLLBAR;
309    case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
310    case CSSValueThreedface: return COLOR_3DFACE;
311    case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
312    case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
313    case CSSValueThreedshadow: return COLOR_3DSHADOW;
314    case CSSValueWindow: return COLOR_WINDOW;
315    case CSSValueWindowframe: return COLOR_WINDOWFRAME;
316    case CSSValueWindowtext: return COLOR_WINDOWTEXT;
317    default: return -1; // Unsupported CSSValue
318    }
319}
320
321Color RenderThemeWinCE::systemColor(int cssValueId) const
322{
323    int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
324    if (sysColorIndex == -1)
325        return RenderTheme::systemColor(cssValueId);
326
327    COLORREF color = GetSysColor(sysColorIndex);
328    return Color(GetRValue(color), GetGValue(color), GetBValue(color));
329}
330
331const int sliderThumbWidth = 7;
332const int sliderThumbHeight = 15;
333
334void RenderThemeWinCE::adjustSliderThumbSize(RenderObject* o) const
335{
336    if (o->style()->appearance() == SliderThumbVerticalPart) {
337        o->style()->setWidth(Length(sliderThumbHeight, Fixed));
338        o->style()->setHeight(Length(sliderThumbWidth, Fixed));
339    } else if (o->style()->appearance() == SliderThumbHorizontalPart) {
340        o->style()->setWidth(Length(sliderThumbWidth, Fixed));
341        o->style()->setHeight(Length(sliderThumbHeight, Fixed));
342    }
343}
344
345#if 0
346void RenderThemeWinCE::adjustButtonInnerStyle(RenderStyle* style) const
347{
348    // This inner padding matches Firefox.
349    style->setPaddingTop(Length(1, Fixed));
350    style->setPaddingRight(Length(3, Fixed));
351    style->setPaddingBottom(Length(1, Fixed));
352    style->setPaddingLeft(Length(3, Fixed));
353}
354
355void RenderThemeWinCE::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
356{
357    // Override padding size to match AppKit text positioning.
358    const int padding = 1;
359    style->setPaddingLeft(Length(padding, Fixed));
360    style->setPaddingRight(Length(padding, Fixed));
361    style->setPaddingTop(Length(padding, Fixed));
362    style->setPaddingBottom(Length(padding, Fixed));
363}
364#endif
365
366bool RenderThemeWinCE::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& r)
367{
368    return paintTextField(o, i, r);
369}
370
371bool RenderThemeWinCE::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
372{
373    Color buttonColor = (o->node() && o->node()->active()) ? Color(138, 138, 138) : Color(186, 186, 186);
374
375    IntSize cancelSize(10, 10);
376    IntSize cancelRadius(cancelSize.width() / 2, cancelSize.height() / 2);
377    int x = r.x() + (r.width() - cancelSize.width()) / 2;
378    int y = r.y() + (r.height() - cancelSize.height()) / 2 + 1;
379    IntRect cancelBounds(IntPoint(x, y), cancelSize);
380    paintInfo.context->save();
381    paintInfo.context->addRoundedRectClip(RoundedIntRect(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius));
382    paintInfo.context->fillRect(cancelBounds, buttonColor, ColorSpaceDeviceRGB);
383
384    // Draw the 'x'
385    IntSize xSize(3, 3);
386    IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize);
387    paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB);
388    paintInfo.context->drawLine(xBounds.location(),  xBounds.location() + xBounds.size());
389    paintInfo.context->drawLine(IntPoint(xBounds.maxX(), xBounds.y()),  IntPoint(xBounds.x(), xBounds.maxY()));
390
391    paintInfo.context->restore();
392    return false;
393}
394
395void RenderThemeWinCE::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
396{
397    IntSize cancelSize(13, 11);
398    style->setWidth(Length(cancelSize.width(), Fixed));
399    style->setHeight(Length(cancelSize.height(), Fixed));
400}
401
402void RenderThemeWinCE::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
403{
404    IntSize emptySize(1, 11);
405    style->setWidth(Length(emptySize.width(), Fixed));
406    style->setHeight(Length(emptySize.height(), Fixed));
407}
408
409void RenderThemeWinCE::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
410{
411    IntSize magnifierSize(15, 11);
412    style->setWidth(Length(magnifierSize.width(), Fixed));
413    style->setHeight(Length(magnifierSize.height(), Fixed));
414}
415
416bool RenderThemeWinCE::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
417{
418    notImplemented();
419    return false;
420}
421
422void RenderThemeWinCE::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
423{
424    IntSize magnifierSize(15, 11);
425    style->setWidth(Length(magnifierSize.width(), Fixed));
426    style->setHeight(Length(magnifierSize.height(), Fixed));
427}
428
429bool RenderThemeWinCE::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
430{
431    paintSearchFieldResultsDecoration(o, paintInfo, r);
432    return false;
433}
434
435void RenderThemeWinCE::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
436{
437    // These are the paddings needed to place the text correctly in the <select> box
438    const int dropDownBoxPaddingTop    = 2;
439    const int dropDownBoxPaddingRight  = style->direction() == LTR ? 4 + dropDownButtonWidth : 4;
440    const int dropDownBoxPaddingBottom = 2;
441    const int dropDownBoxPaddingLeft   = style->direction() == LTR ? 4 : 4 + dropDownButtonWidth;
442    // The <select> box must be at least 12px high for the button to render nicely on Windows
443    const int dropDownBoxMinHeight = 12;
444
445    // Position the text correctly within the select box and make the box wide enough to fit the dropdown button
446    style->setPaddingTop(Length(dropDownBoxPaddingTop, Fixed));
447    style->setPaddingRight(Length(dropDownBoxPaddingRight, Fixed));
448    style->setPaddingBottom(Length(dropDownBoxPaddingBottom, Fixed));
449    style->setPaddingLeft(Length(dropDownBoxPaddingLeft, Fixed));
450
451    // Height is locked to auto
452    style->setHeight(Length(Auto));
453
454    // Calculate our min-height
455    int minHeight = style->fontMetrics().height();
456    minHeight = max(minHeight, dropDownBoxMinHeight);
457
458    style->setMinHeight(Length(minHeight, Fixed));
459
460    // White-space is locked to pre
461    style->setWhiteSpace(PRE);
462
463    DWORD colorMenu = GetSysColor(COLOR_MENU);
464    DWORD colorMenuText = GetSysColor(COLOR_MENUTEXT);
465    Color bgColor(GetRValue(colorMenu), GetGValue(colorMenu), GetBValue(colorMenu), 255);
466    Color textColor(GetRValue(colorMenuText), GetGValue(colorMenuText), GetBValue(colorMenuText), 255);
467    if (bgColor == textColor)
468        textColor.setRGB((~bgColor.rgb()) | 0xFF000000);
469    style->clearBackgroundLayers();
470    style->accessBackgroundLayers()->setClip(ContentFillBox);
471    style->setBackgroundColor(bgColor);
472    style->setColor(textColor);
473}
474
475#if ENABLE(VIDEO)
476// Attempt to retrieve a HTMLMediaElement from a Node. Returns 0 if one cannot be found.
477static HTMLMediaElement* mediaElementParent(Node* node)
478{
479    if (!node)
480        return 0;
481    Node* mediaNode = node->shadowAncestorNode();
482    if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag)))
483        return 0;
484
485    return static_cast<HTMLMediaElement*>(mediaNode);
486}
487#endif
488
489bool RenderThemeWinCE::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
490{
491    bool rc = RenderTheme::paintSliderTrack(o, i, r);
492    IntPoint left = IntPoint(r.x() + 2, (r.y() + r.maxY()) / 2);
493    i.context->save();
494    i.context->setStrokeColor(Color::gray, ColorSpaceDeviceRGB);
495    i.context->setFillColor(Color::gray, ColorSpaceDeviceRGB);
496    i.context->fillRect(r);
497#if ENABLE(VIDEO)
498    HTMLMediaElement* mediaElement = mediaElementParent(o->node());
499    if (mediaElement) {
500        i.context->setStrokeColor(Color(0, 0xff, 0));
501        IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.maxX() - r.x() - 4), (r.y() + r.maxY()) / 2);
502        i.context->drawLine(left, right);
503        left = right;
504    }
505#endif
506    i.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
507    i.context->drawLine(left, IntPoint(r.maxX() - 2, left.y()));
508    i.context->restore();
509    return rc;
510}
511
512bool RenderThemeWinCE::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
513{
514    bool rc = RenderTheme::paintSliderThumb(o, i, r);
515    i.context->save();
516    i.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB);
517    i.context->setFillColor(Color::black, ColorSpaceDeviceRGB);
518#if ENABLE(VIDEO)
519    HTMLMediaElement* mediaElement = mediaElementParent(o->node());
520    if (mediaElement) {
521        float pt = (mediaElement->currentTime() - mediaElement->startTime()) / mediaElement->duration();
522        FloatRect intRect = r;
523        intRect.setX(intRect.x() + intRect.width() * pt - 2);
524        intRect.setWidth(5);
525        i.context->fillRect(intRect);
526    }
527#endif
528    i.context->restore();
529    return rc;
530}
531
532void RenderThemeWinCE::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
533{
534    const int padding = 1;
535    style->setPaddingLeft(Length(padding, Fixed));
536    style->setPaddingRight(Length(padding, Fixed));
537    style->setPaddingTop(Length(padding, Fixed));
538    style->setPaddingBottom(Length(padding, Fixed));
539}
540
541#if ENABLE(VIDEO)
542
543bool RenderThemeWinCE::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
544{
545    bool rc = paintButton(o, paintInfo, r);
546    FloatRect imRect = r;
547    imRect.inflate(-2);
548    paintInfo.context->save();
549    paintInfo.context->setStrokeColor(Color::black);
550    paintInfo.context->setFillColor(Color::gray);
551    paintInfo.context->fillRect(imRect);
552    paintInfo.context->restore();
553    return rc;
554}
555
556bool RenderThemeWinCE::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
557{
558    bool rc = paintButton(o, paintInfo, r);
559    HTMLMediaElement* mediaElement = mediaElementParent(o->node());
560    bool muted = !mediaElement || mediaElement->muted();
561    FloatRect imRect = r;
562    imRect.inflate(-2);
563    paintInfo.context->save();
564    paintInfo.context->setStrokeColor(Color::black);
565    paintInfo.context->setFillColor(Color::black);
566    FloatPoint pts[6] = {
567        FloatPoint(imRect.x() + 1, imRect.y() + imRect.height() / 3.0),
568        FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + imRect.height() / 3.0),
569        FloatPoint(imRect.maxX() - 1, imRect.y()),
570        FloatPoint(imRect.maxX() - 1, imRect.maxY()),
571        FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + 2.0 * imRect.height() / 3.0),
572        FloatPoint(imRect.x() + 1, imRect.y() + 2.0 * imRect.height() / 3.0)
573    };
574    paintInfo.context->drawConvexPolygon(6, pts);
575    if (muted)
576        paintInfo.context->drawLine(IntPoint(imRect.maxX(), imRect.y()), IntPoint(imRect.x(), imRect.maxY()));
577    paintInfo.context->restore();
578    return rc;
579}
580
581bool RenderThemeWinCE::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
582{
583    bool rc = paintButton(o, paintInfo, r);
584    FloatRect imRect = r;
585    imRect.inflate(-3);
586    paintInfo.context->save();
587    paintInfo.context->setStrokeColor(Color::black);
588    paintInfo.context->setFillColor(Color::black);
589    HTMLMediaElement* mediaElement = mediaElementParent(o->node());
590    bool paused = !mediaElement || mediaElement->paused();
591    if (paused) {
592        float width = imRect.width();
593        imRect.setWidth(width / 3.0);
594        paintInfo.context->fillRect(imRect);
595        imRect.move(2.0 * width / 3.0, 0);
596        paintInfo.context->fillRect(imRect);
597    } else {
598        FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) };
599        paintInfo.context->drawConvexPolygon(3, pts);
600    }
601    paintInfo.context->restore();
602    return rc;
603}
604
605bool RenderThemeWinCE::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
606{
607    bool rc = paintButton(o, paintInfo, r);
608    FloatRect imRect = r;
609    imRect.inflate(-3);
610    FloatPoint pts[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.x(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) };
611    FloatPoint pts2[3] = { FloatPoint(imRect.maxX(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.maxX(), imRect.maxY()) };
612    paintInfo.context->save();
613    paintInfo.context->setStrokeColor(Color::black);
614    paintInfo.context->setFillColor(Color::black);
615    paintInfo.context->drawConvexPolygon(3, pts);
616    paintInfo.context->drawConvexPolygon(3, pts2);
617    paintInfo.context->restore();
618    return rc;
619}
620
621bool RenderThemeWinCE::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
622{
623    bool rc = paintButton(o, paintInfo, r);
624    FloatRect imRect = r;
625    imRect.inflate(-3);
626    FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) };
627    FloatPoint pts2[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) };
628    paintInfo.context->save();
629    paintInfo.context->setStrokeColor(Color::black);
630    paintInfo.context->setFillColor(Color::black);
631    paintInfo.context->drawConvexPolygon(3, pts);
632    paintInfo.context->drawConvexPolygon(3, pts2);
633    paintInfo.context->restore();
634    return rc;
635}
636
637bool RenderThemeWinCE::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
638{
639    return paintSliderTrack(o, paintInfo, r);
640}
641
642bool RenderThemeWinCE::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
643{
644    return paintSliderThumb(o, paintInfo, r);
645}
646#endif
647
648} // namespace WebCore
649