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