Subpixel rendering[iOS]: <select> decoration is misaligned when the renderer is on...
[WebKit-https.git] / Source / WebCore / rendering / RenderThemeWin.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2013 Apple Inc.
3  * Copyright (C) 2009 Kenneth Rohde Christiansen
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  */
21
22 #include "config.h"
23 #include "RenderThemeWin.h"
24
25 #include "CSSValueKeywords.h"
26 #include "Element.h"
27 #include "FontMetrics.h"
28 #include "Frame.h"
29 #include "FrameSelection.h"
30 #include "GraphicsContext.h"
31 #include "HTMLMeterElement.h"
32 #include "LocalWindowsContext.h"
33 #include "PaintInfo.h"
34 #include "RenderMeter.h"
35 #include "RenderSlider.h"
36 #include "Settings.h"
37 #include "SoftLinking.h"
38 #include "SystemInfo.h"
39 #include "UserAgentStyleSheets.h"
40 #include "WebCoreBundleWin.h"
41 #include <wtf/win/GDIObject.h>
42
43 #if ENABLE(VIDEO)
44 #include "RenderMediaControls.h"
45 #endif
46
47 #include <tchar.h>
48
49 /* 
50  * The following constants are used to determine how a widget is drawn using
51  * Windows' Theme API. For more information on theme parts and states see
52  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
53  */
54
55 // Generic state constants
56 #define TS_NORMAL    1
57 #define TS_HOVER     2
58 #define TS_ACTIVE    3
59 #define TS_DISABLED  4
60 #define TS_FOCUSED   5
61
62 // Button constants
63 #define BP_BUTTON    1
64 #define BP_RADIO     2
65 #define BP_CHECKBOX  3
66
67 // Textfield constants
68 #define TFP_TEXTFIELD 1
69 #define EP_EDITBORDER_NOSCROLL 6
70 #define TFS_READONLY  6
71
72 // ComboBox constants (from vsstyle.h)
73 #define CP_DROPDOWNBUTTON 1
74 #define CP_BORDER 4
75 #define CP_READONLY 5
76 #define CP_DROPDOWNBUTTONRIGHT 6
77
78 // TrackBar (slider) parts
79 #define TKP_TRACK       1
80 #define TKP_TRACKVERT   2
81
82 // TrackBar (slider) thumb parts
83 #define TKP_THUMBBOTTOM 4
84 #define TKP_THUMBTOP    5
85 #define TKP_THUMBLEFT   7
86 #define TKP_THUMBRIGHT  8
87
88 // Trackbar (slider) thumb states
89 #define TUS_NORMAL      1
90 #define TUS_HOT         2
91 #define TUS_PRESSED     3
92 #define TUS_FOCUSED     4
93 #define TUS_DISABLED    5
94
95 // button states
96 #define PBS_NORMAL      1
97 #define PBS_HOT         2
98 #define PBS_PRESSED     3
99 #define PBS_DISABLED    4
100 #define PBS_DEFAULTED   5
101
102 // Spin button parts
103 #define SPNP_UP         1
104 #define SPNP_DOWN       2
105
106 // Spin button states
107 #define DNS_NORMAL      1
108 #define DNS_HOT         2
109 #define DNS_PRESSED     3
110 #define DNS_DISABLED    4
111 #define UPS_NORMAL      1
112 #define UPS_HOT         2
113 #define UPS_PRESSED     3
114 #define UPS_DISABLED    4
115
116 // Progress bar parts
117 #define PP_BAR          1
118 #define PP_BARVERT      2
119 #define PP_CHUNK        3
120 #define PP_CHUNKVERT    4
121 #define PP_FILL         5
122 #define PP_FILLVERT     6
123 #define PP_PULSEOVERLAY 7
124 #define PP_MOVEOVERLAY  8
125 #define PP_PULSEOVERLAYVERT 9
126 #define PP_MOVEOVERLAYVERT  10
127 #define PP_TRANSPARENTBAR   11
128 #define PP_TRANSPARENTBARVERT 12
129
130 // Progress bar states
131 #define PBBS_NORMAL     1
132 #define PBBS_PARTIAL    2
133 #define PBBVS_NORMAL    1 // Vertical
134 #define PBBVS_PARTIAL   2
135
136 // Progress bar fill states
137 #define PBFS_NORMAL     1
138 #define PBFS_ERROR      2
139 #define PBFS_PAUSED     3
140 #define PBFS_PARTIAL    4
141 #define PBFVS_NORMAL    1 // Vertical
142 #define PBFVS_ERROR     2
143 #define PBFVS_PAUSED    3
144 #define PBFVS_PARTIAL   4
145
146
147 SOFT_LINK_LIBRARY(uxtheme)
148 SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList))
149 SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
150 SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
151 SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
152 SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))
153
154 static bool haveTheme;
155
156 static const unsigned vistaMenuListButtonOutset = 1;
157
158 using namespace std;
159
160 namespace WebCore {
161
162 // This is the fixed width IE and Firefox use for buttons on dropdown menus
163 static const int dropDownButtonWidth = 17;
164
165 static const int shell32MagnifierIconIndex = 22;
166
167 // Default font size to match Firefox.
168 static const float defaultControlFontPixelSize = 13;
169
170 static const float defaultCancelButtonSize = 9;
171 static const float minCancelButtonSize = 5;
172 static const float maxCancelButtonSize = 21;
173 static const float defaultSearchFieldResultsDecorationSize = 13;
174 static const float minSearchFieldResultsDecorationSize = 9;
175 static const float maxSearchFieldResultsDecorationSize = 30;
176 static const float defaultSearchFieldResultsButtonWidth = 18;
177
178 static bool gWebKitIsBeingUnloaded;
179
180 void RenderThemeWin::setWebKitIsBeingUnloaded()
181 {
182     gWebKitIsBeingUnloaded = true;
183 }
184
185 PassRefPtr<RenderTheme> RenderThemeWin::create()
186 {
187     return adoptRef(new RenderThemeWin);
188 }
189
190 #if !USE(SAFARI_THEME)
191 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
192 {
193     static RenderTheme* winTheme = RenderThemeWin::create().leakRef();
194     return winTheme;
195 }
196 #endif
197
198 RenderThemeWin::RenderThemeWin()
199     : m_buttonTheme(0)
200     , m_textFieldTheme(0)
201     , m_menuListTheme(0)
202     , m_sliderTheme(0)
203     , m_spinButtonTheme(0)
204     , m_progressBarTheme(0)
205 {
206     haveTheme = uxthemeLibrary() && IsThemeActive();
207 }
208
209 RenderThemeWin::~RenderThemeWin()
210 {
211     // If WebKit is being unloaded, then uxtheme.dll is no longer available.
212     if (gWebKitIsBeingUnloaded || !uxthemeLibrary())
213         return;
214     close();
215 }
216
217 HANDLE RenderThemeWin::buttonTheme() const
218 {
219     if (haveTheme && !m_buttonTheme)
220         m_buttonTheme = OpenThemeData(0, L"Button");
221     return m_buttonTheme;
222 }
223
224 HANDLE RenderThemeWin::textFieldTheme() const
225 {
226     if (haveTheme && !m_textFieldTheme)
227         m_textFieldTheme = OpenThemeData(0, L"Edit");
228     return m_textFieldTheme;
229 }
230
231 HANDLE RenderThemeWin::menuListTheme() const
232 {
233     if (haveTheme && !m_menuListTheme)
234         m_menuListTheme = OpenThemeData(0, L"ComboBox");
235     return m_menuListTheme;
236 }
237
238 HANDLE RenderThemeWin::sliderTheme() const
239 {
240     if (haveTheme && !m_sliderTheme)
241         m_sliderTheme = OpenThemeData(0, L"TrackBar");
242     return m_sliderTheme;
243 }
244
245 HANDLE RenderThemeWin::spinButtonTheme() const
246 {
247     if (haveTheme && !m_spinButtonTheme)
248         m_spinButtonTheme = OpenThemeData(0, L"Spin");
249     return m_spinButtonTheme;
250 }
251
252 HANDLE RenderThemeWin::progressBarTheme() const
253 {
254     if (haveTheme && !m_progressBarTheme)
255         m_progressBarTheme = OpenThemeData(0, L"Progress");
256     return m_progressBarTheme;
257 }
258
259 void RenderThemeWin::close()
260 {
261     // This method will need to be called when the OS theme changes to flush our cached themes.
262     if (m_buttonTheme)
263         CloseThemeData(m_buttonTheme);
264     if (m_textFieldTheme)
265         CloseThemeData(m_textFieldTheme);
266     if (m_menuListTheme)
267         CloseThemeData(m_menuListTheme);
268     if (m_sliderTheme)
269         CloseThemeData(m_sliderTheme);
270     if (m_spinButtonTheme)
271         CloseThemeData(m_spinButtonTheme);
272     if (m_progressBarTheme)
273         CloseThemeData(m_progressBarTheme);
274     m_buttonTheme = m_textFieldTheme = m_menuListTheme = m_sliderTheme = m_spinButtonTheme = m_progressBarTheme = 0;
275
276     haveTheme = uxthemeLibrary() && IsThemeActive();
277 }
278
279 void RenderThemeWin::themeChanged()
280 {
281     close();
282 }
283
284 String RenderThemeWin::extraDefaultStyleSheet()
285 {
286     return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
287 }
288
289 String RenderThemeWin::extraQuirksStyleSheet()
290 {
291     return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
292 }
293
294 bool RenderThemeWin::supportsHover(const RenderStyle*) const
295 {
296     // The Classic/2k look has no hover effects.
297     return haveTheme;
298 }
299
300 Color RenderThemeWin::platformActiveSelectionBackgroundColor() const
301 {
302     COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
303     return Color(GetRValue(color), GetGValue(color), GetBValue(color));
304 }
305
306 Color RenderThemeWin::platformInactiveSelectionBackgroundColor() const
307 {
308     // This color matches Firefox.
309     return Color(176, 176, 176);
310 }
311
312 Color RenderThemeWin::platformActiveSelectionForegroundColor() const
313 {
314     COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
315     return Color(GetRValue(color), GetGValue(color), GetBValue(color));
316 }
317
318 Color RenderThemeWin::platformInactiveSelectionForegroundColor() const
319 {
320     return platformActiveSelectionForegroundColor();
321 }
322
323 static void fillFontDescription(FontDescription& fontDescription, LOGFONT& logFont, float fontSize)
324 {    
325     fontDescription.setIsAbsoluteSize(true);
326     fontDescription.setGenericFamily(FontDescription::NoFamily);
327     fontDescription.setOneFamily(String(logFont.lfFaceName));
328     fontDescription.setSpecifiedSize(fontSize);
329     fontDescription.setWeight(logFont.lfWeight >= 700 ? FontWeightBold : FontWeightNormal); // FIXME: Use real weight.
330     fontDescription.setItalic(logFont.lfItalic);
331 }
332
333 static void fillFontDescription(FontDescription& fontDescription, LOGFONT& logFont)
334 {   
335     fillFontDescription(fontDescription, logFont, abs(logFont.lfHeight));
336 }
337
338 void RenderThemeWin::systemFont(CSSValueID valueID, FontDescription& fontDescription) const
339 {
340     static FontDescription captionFont;
341     static FontDescription controlFont;
342     static FontDescription smallCaptionFont;
343     static FontDescription menuFont;
344     static FontDescription iconFont;
345     static FontDescription messageBoxFont;
346     static FontDescription statusBarFont;
347     static FontDescription systemFont;
348     
349     static bool initialized;
350     static NONCLIENTMETRICS ncm;
351
352     if (!initialized) {
353         initialized = true;
354         ncm.cbSize = sizeof(NONCLIENTMETRICS);
355         ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
356     }
357  
358     switch (valueID) {
359     case CSSValueIcon: {
360         if (!iconFont.isAbsoluteSize()) {
361             LOGFONT logFont;
362             ::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0);
363             fillFontDescription(iconFont, logFont);
364         }
365         fontDescription = iconFont;
366         break;
367     }
368     case CSSValueMenu:
369         if (!menuFont.isAbsoluteSize())
370             fillFontDescription(menuFont, ncm.lfMenuFont);
371         fontDescription = menuFont;
372         break;
373     case CSSValueMessageBox:
374         if (!messageBoxFont.isAbsoluteSize())
375             fillFontDescription(messageBoxFont, ncm.lfMessageFont);
376         fontDescription = messageBoxFont;
377         break;
378     case CSSValueStatusBar:
379         if (!statusBarFont.isAbsoluteSize())
380             fillFontDescription(statusBarFont, ncm.lfStatusFont);
381         fontDescription = statusBarFont;
382         break;
383     case CSSValueCaption:
384         if (!captionFont.isAbsoluteSize())
385             fillFontDescription(captionFont, ncm.lfCaptionFont);
386         fontDescription = captionFont;
387         break;
388     case CSSValueSmallCaption:
389         if (!smallCaptionFont.isAbsoluteSize())
390             fillFontDescription(smallCaptionFont, ncm.lfSmCaptionFont);
391         fontDescription = smallCaptionFont;
392         break;
393     case CSSValueWebkitSmallControl:
394     case CSSValueWebkitMiniControl: // Just map to small.
395     case CSSValueWebkitControl: // Just map to small.
396         if (!controlFont.isAbsoluteSize()) {
397             HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
398             if (hGDI) {
399                 LOGFONT logFont;
400                 if (::GetObject(hGDI, sizeof(logFont), &logFont) > 0)
401                     fillFontDescription(controlFont, logFont, defaultControlFontPixelSize);
402             }
403         }
404         fontDescription = controlFont;
405         break;
406     default: { // Everything else uses the stock GUI font.
407         if (!systemFont.isAbsoluteSize()) {
408             HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
409             if (hGDI) {
410                 LOGFONT logFont;
411                 if (::GetObject(hGDI, sizeof(logFont), &logFont) > 0)
412                     fillFontDescription(systemFont, logFont);
413             }
414         }
415         fontDescription = systemFont;
416     }
417     }
418 }
419
420 bool RenderThemeWin::supportsFocus(ControlPart appearance) const
421 {
422     switch (appearance) {
423         case PushButtonPart:
424         case ButtonPart:
425         case DefaultButtonPart:
426             return true;
427         default:
428             return false;
429     }
430 }
431
432 bool RenderThemeWin::supportsFocusRing(const RenderStyle* style) const
433 {
434     return supportsFocus(style->appearance());
435 }
436
437 unsigned RenderThemeWin::determineClassicState(const RenderObject& o, ControlSubPart subPart)
438 {
439     unsigned state = 0;
440     switch (o.style().appearance()) {
441         case PushButtonPart:
442         case ButtonPart:
443         case DefaultButtonPart:
444             state = DFCS_BUTTONPUSH;
445             if (!isEnabled(o))
446                 state |= DFCS_INACTIVE;
447             else if (isPressed(o))
448                 state |= DFCS_PUSHED;
449             break;
450         case RadioPart:
451         case CheckboxPart:
452             state = (o.style().appearance() == RadioPart) ? DFCS_BUTTONRADIO : DFCS_BUTTONCHECK;
453             if (isChecked(o))
454                 state |= DFCS_CHECKED;
455             if (!isEnabled(o))
456                 state |= DFCS_INACTIVE;
457             else if (isPressed(o))
458                 state |= DFCS_PUSHED;
459             break;
460         case MenulistPart:
461             state = DFCS_SCROLLCOMBOBOX;
462             if (!isEnabled(o))
463                 state |= DFCS_INACTIVE;
464             else if (isPressed(o))
465                 state |= DFCS_PUSHED;
466             break;
467         case InnerSpinButtonPart: {
468             bool isUpButton = subPart == SpinButtonUp;
469             state = isUpButton ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
470             if (!isEnabled(o) || isReadOnlyControl(o))
471                 state |= DFCS_INACTIVE;
472             else if (isPressed(o) && isUpButton == isSpinUpButtonPartPressed(o))
473                 state |= DFCS_PUSHED;
474             else if (isHovered(o) && isUpButton == isSpinUpButtonPartHovered(o))
475                 state |= DFCS_HOT;
476             break;
477         }
478         default:
479             break;
480     }
481     return state;
482 }
483
484 unsigned RenderThemeWin::determineState(const RenderObject& o)
485 {
486     unsigned result = TS_NORMAL;
487     ControlPart appearance = o.style().appearance();
488     if (!isEnabled(o))
489         result = TS_DISABLED;
490     else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPart == appearance || SearchFieldPart == appearance))
491         result = TFS_READONLY; // Readonly is supported on textfields.
492     else if (isPressed(o)) // Active overrides hover and focused.
493         result = TS_ACTIVE;
494     else if (supportsFocus(appearance) && isFocused(o))
495         result = TS_FOCUSED;
496     else if (isHovered(o))
497         result = TS_HOVER;
498     if (isChecked(o))
499         result += 4; // 4 unchecked states, 4 checked states.
500     else if (isIndeterminate(o) && appearance == CheckboxPart)
501         result += 8;
502     return result;
503 }
504
505 unsigned RenderThemeWin::determineSliderThumbState(const RenderObject& o)
506 {
507     unsigned result = TUS_NORMAL;
508     if (!isEnabled(o))
509         result = TUS_DISABLED;
510     else if (supportsFocus(o.style().appearance()) && isFocused(o))
511         result = TUS_FOCUSED;
512     else if (isPressed(o))
513         result = TUS_PRESSED;
514     else if (isHovered(o))
515         result = TUS_HOT;
516     return result;
517 }
518
519 unsigned RenderThemeWin::determineButtonState(const RenderObject& o)
520 {
521     unsigned result = PBS_NORMAL;
522     if (!isEnabled(o))
523         result = PBS_DISABLED;
524     else if (isPressed(o))
525         result = PBS_PRESSED;
526     else if (supportsFocus(o.style().appearance()) && isFocused(o))
527         result = PBS_DEFAULTED;
528     else if (isHovered(o))
529         result = PBS_HOT;
530     else if (isDefault(o))
531         result = PBS_DEFAULTED;
532     return result;
533 }
534
535 unsigned RenderThemeWin::determineSpinButtonState(const RenderObject& o, ControlSubPart subPart)
536 {
537     bool isUpButton = subPart == SpinButtonUp;
538     unsigned result = isUpButton ? UPS_NORMAL : DNS_NORMAL;
539     if (!isEnabled(o) || isReadOnlyControl(o))
540         result = isUpButton ? UPS_DISABLED : DNS_DISABLED;
541     else if (isPressed(o) && isUpButton == isSpinUpButtonPartPressed(o))
542         result = isUpButton ? UPS_PRESSED : DNS_PRESSED;
543     else if (isHovered(o) && isUpButton == isSpinUpButtonPartHovered(o))
544         result = isUpButton ? UPS_HOT : DNS_HOT;
545     return result;
546 }
547
548 ThemeData RenderThemeWin::getClassicThemeData(const RenderObject& o, ControlSubPart subPart)
549 {
550     ThemeData result;
551     switch (o.style().appearance()) {
552         case PushButtonPart:
553         case ButtonPart:
554         case DefaultButtonPart:
555         case CheckboxPart:
556         case RadioPart:
557             result.m_part = DFC_BUTTON;
558             result.m_state = determineClassicState(o);
559             break;
560         case MenulistPart:
561             result.m_part = DFC_SCROLL;
562             result.m_state = determineClassicState(o);
563             break;
564         case MeterPart:
565             result.m_part = PP_BAR;
566             result.m_state = determineState(o);
567             break;
568         case SearchFieldPart:
569         case TextFieldPart:
570         case TextAreaPart:
571             result.m_part = TFP_TEXTFIELD;
572             result.m_state = determineState(o);
573             break;
574         case SliderHorizontalPart:
575             result.m_part = TKP_TRACK;
576             result.m_state = TS_NORMAL;
577             break;
578         case SliderVerticalPart:
579             result.m_part = TKP_TRACKVERT;
580             result.m_state = TS_NORMAL;
581             break;
582         case SliderThumbHorizontalPart:
583             result.m_part = TKP_THUMBBOTTOM;
584             result.m_state = determineSliderThumbState(o);
585             break;
586         case SliderThumbVerticalPart:
587             result.m_part = TKP_THUMBRIGHT;
588             result.m_state = determineSliderThumbState(o);
589             break;
590         case InnerSpinButtonPart:
591             result.m_part = DFC_SCROLL;
592             result.m_state = determineClassicState(o, subPart);
593             break;
594         default:
595             break;
596     }
597     return result;
598 }
599
600 ThemeData RenderThemeWin::getThemeData(const RenderObject& o, ControlSubPart subPart)
601 {
602     if (!haveTheme)
603         return getClassicThemeData(o, subPart);
604
605     ThemeData result;
606     switch (o.style().appearance()) {
607         case PushButtonPart:
608         case ButtonPart:
609         case DefaultButtonPart:
610             result.m_part = BP_BUTTON;
611             result.m_state = determineButtonState(o);
612             break;
613         case CheckboxPart:
614             result.m_part = BP_CHECKBOX;
615             result.m_state = determineState(o);
616             break;
617         case MenulistPart:
618         case MenulistButtonPart: {
619             const bool isVistaOrLater = (windowsVersion() >= WindowsVista);
620             result.m_part = isVistaOrLater ? CP_DROPDOWNBUTTONRIGHT : CP_DROPDOWNBUTTON;
621             if (isVistaOrLater && o.frame().settings().applicationChromeMode()) {
622                 // The "readonly" look we use in application chrome mode
623                 // only uses a "normal" look for the drop down button.
624                 result.m_state = TS_NORMAL;
625             } else
626                 result.m_state = determineState(o);
627             break;
628         }
629         case MeterPart:
630             result.m_part = PP_BAR;
631             result.m_state = determineState(o);
632             break;
633         case RadioPart:
634             result.m_part = BP_RADIO;
635             result.m_state = determineState(o);
636             break;
637         case SearchFieldPart:
638         case TextFieldPart:
639         case TextAreaPart:
640             result.m_part = (windowsVersion() >= WindowsVista) ? EP_EDITBORDER_NOSCROLL : TFP_TEXTFIELD;
641             result.m_state = determineState(o);
642             break;
643         case SliderHorizontalPart:
644             result.m_part = TKP_TRACK;
645             result.m_state = TS_NORMAL;
646             break;
647         case SliderVerticalPart:
648             result.m_part = TKP_TRACKVERT;
649             result.m_state = TS_NORMAL;
650             break;
651         case SliderThumbHorizontalPart:
652             result.m_part = TKP_THUMBBOTTOM;
653             result.m_state = determineSliderThumbState(o);
654             break;
655         case SliderThumbVerticalPart:
656             result.m_part = TKP_THUMBRIGHT;
657             result.m_state = determineSliderThumbState(o);
658             break;
659         case InnerSpinButtonPart:
660             result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
661             result.m_state = determineSpinButtonState(o, subPart);
662             break;
663     }
664
665     return result;
666 }
667
668 static void drawControl(GraphicsContext* context, const RenderObject& o, HANDLE theme, const ThemeData& themeData, const IntRect& r)
669 {
670     bool alphaBlend = false;
671     if (theme)
672         alphaBlend = IsThemeBackgroundPartiallyTransparent(theme, themeData.m_part, themeData.m_state);
673     LocalWindowsContext windowsContext(context, r, alphaBlend);
674     RECT widgetRect = r;
675     if (theme)
676         DrawThemeBackground(theme, windowsContext.hdc(), themeData.m_part, themeData.m_state, &widgetRect, 0);
677     else {
678         HDC hdc = windowsContext.hdc();
679         if (themeData.m_part == TFP_TEXTFIELD) {
680             ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
681             if (themeData.m_state == TS_DISABLED || themeData.m_state ==  TFS_READONLY)
682                 ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_BTNFACE+1));
683             else
684                 ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_WINDOW+1));
685         } else if (themeData.m_part == TKP_TRACK || themeData.m_part == TKP_TRACKVERT) {
686             ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
687             ::FillRect(hdc, &widgetRect, (HBRUSH)GetStockObject(GRAY_BRUSH));
688         } else if ((o.style().appearance() == SliderThumbHorizontalPart
689         || o.style().appearance() == SliderThumbVerticalPart)
690         && (themeData.m_part == TKP_THUMBBOTTOM || themeData.m_part == TKP_THUMBTOP
691         || themeData.m_part == TKP_THUMBLEFT || themeData.m_part == TKP_THUMBRIGHT)) {
692             ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
693             if (themeData.m_state == TUS_DISABLED) {
694                 static WORD patternBits[8] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
695                 auto patternBmp = adoptGDIObject(::CreateBitmap(8, 8, 1, 1, patternBits));
696                 if (patternBmp) {
697                     auto brush = adoptGDIObject(::CreatePatternBrush(patternBmp.get()));
698                     COLORREF oldForeColor = ::SetTextColor(hdc, ::GetSysColor(COLOR_3DFACE));
699                     COLORREF oldBackColor = ::SetBkColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
700                     POINT p;
701                     ::GetViewportOrgEx(hdc, &p);
702                     ::SetBrushOrgEx(hdc, p.x + widgetRect.left, p.y + widgetRect.top, NULL);
703                     HGDIOBJ oldBrush = ::SelectObject(hdc, brush.get());
704                     ::FillRect(hdc, &widgetRect, brush.get());
705                     ::SetTextColor(hdc, oldForeColor);
706                     ::SetBkColor(hdc, oldBackColor);
707                     ::SelectObject(hdc, oldBrush);
708                 } else
709                     ::FillRect(hdc, &widgetRect, (HBRUSH)COLOR_3DHILIGHT);
710             }
711         } else {
712             // Push buttons, buttons, checkboxes and radios, and the dropdown arrow in menulists.
713             if (o.style().appearance() == DefaultButtonPart) {
714                 HBRUSH brush = ::GetSysColorBrush(COLOR_3DDKSHADOW);
715                 ::FrameRect(hdc, &widgetRect, brush);
716                 ::InflateRect(&widgetRect, -1, -1);
717                 ::DrawEdge(hdc, &widgetRect, BDR_RAISEDOUTER, BF_RECT | BF_MIDDLE);
718             }
719             ::DrawFrameControl(hdc, &widgetRect, themeData.m_part, themeData.m_state);
720         }
721     }
722
723     if (!alphaBlend && !context->isInTransparencyLayer())
724         DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), r, 255);
725 }
726
727 bool RenderThemeWin::paintButton(const RenderObject& o, const PaintInfo& i, const IntRect& r)
728 {  
729     drawControl(i.context,  o, buttonTheme(), getThemeData(o), r);
730     return false;
731 }
732
733 void RenderThemeWin::adjustInnerSpinButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
734 {
735     int width = ::GetSystemMetrics(SM_CXVSCROLL);
736     if (width <= 0)
737         width = 17; // Vista's default.
738     style->setWidth(Length(width, Fixed));
739     style->setMinWidth(Length(width, Fixed));
740 }
741
742 bool RenderThemeWin::paintInnerSpinButton(const RenderObject& o, const PaintInfo& i, const IntRect& r)
743 {
744     // We split the specified rectangle into two vertically. We can't draw a
745     // spin button of which height is less than 2px.
746     if (r.height() < 2)
747         return false;
748     IntRect upRect(r);
749     upRect.setHeight(r.height() / 2);
750     IntRect downRect(r);
751     downRect.setY(upRect.maxY());
752     downRect.setHeight(r.height() - upRect.height());
753     drawControl(i.context, o, spinButtonTheme(), getThemeData(o, SpinButtonUp), upRect);
754     drawControl(i.context, o, spinButtonTheme(), getThemeData(o, SpinButtonDown), downRect);
755     return false;
756 }
757
758 void RenderThemeWin::setCheckboxSize(RenderStyle* style) const
759 {
760     // If the width and height are both specified, then we have nothing to do.
761     if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
762         return;
763
764     // FIXME:  A hard-coded size of 13 is used.  This is wrong but necessary for now.  It matches Firefox.
765     // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
766     // the higher DPI.  Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
767     // metrics.
768     if (style->width().isIntrinsicOrAuto())
769         style->setWidth(Length(13, Fixed));
770     if (style->height().isAuto())
771         style->setHeight(Length(13, Fixed));
772 }
773
774 bool RenderThemeWin::paintTextField(const RenderObject& o, const PaintInfo& i, const IntRect& r)
775 {
776     drawControl(i.context,  o, textFieldTheme(), getThemeData(o), r);
777     return false;
778 }
779
780 bool RenderThemeWin::paintMenuList(const RenderObject& renderer, const PaintInfo& paintInfo, const IntRect& rect)
781 {
782     HANDLE theme;
783     int part;
784     if (haveTheme && (windowsVersion() >= WindowsVista)) {
785         theme = menuListTheme();
786         if (renderer.frame().settings().applicationChromeMode())
787             part = CP_READONLY;
788         else
789             part = CP_BORDER;
790     } else {
791         theme = textFieldTheme();
792         part = TFP_TEXTFIELD;
793     }
794
795     drawControl(paintInfo.context, renderer, theme, ThemeData(part, determineState(renderer)), rect);
796     
797     return paintMenuListButtonDecorations(renderer, paintInfo, FloatRect(rect));
798 }
799
800 void RenderThemeWin::adjustMenuListStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
801 {
802     style->resetBorder();
803     adjustMenuListButtonStyle(styleResolver, style, e);
804 }
805
806 void RenderThemeWin::adjustMenuListButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
807 {
808     // These are the paddings needed to place the text correctly in the <select> box
809     const int dropDownBoxPaddingTop    = 2;
810     const int dropDownBoxPaddingRight  = style->direction() == LTR ? 4 + dropDownButtonWidth : 4;
811     const int dropDownBoxPaddingBottom = 2;
812     const int dropDownBoxPaddingLeft   = style->direction() == LTR ? 4 : 4 + dropDownButtonWidth;
813     // The <select> box must be at least 12px high for the button to render nicely on Windows
814     const int dropDownBoxMinHeight = 12;
815     
816     // Position the text correctly within the select box and make the box wide enough to fit the dropdown button
817     style->setPaddingTop(Length(dropDownBoxPaddingTop, Fixed));
818     style->setPaddingRight(Length(dropDownBoxPaddingRight, Fixed));
819     style->setPaddingBottom(Length(dropDownBoxPaddingBottom, Fixed));
820     style->setPaddingLeft(Length(dropDownBoxPaddingLeft, Fixed));
821
822     // Height is locked to auto
823     style->setHeight(Length(Auto));
824
825     // Calculate our min-height
826     int minHeight = style->fontMetrics().height();
827     minHeight = max(minHeight, dropDownBoxMinHeight);
828
829     style->setMinHeight(Length(minHeight, Fixed));
830
831     style->setLineHeight(RenderStyle::initialLineHeight());
832     
833     // White-space is locked to pre
834     style->setWhiteSpace(PRE);
835 }
836
837 bool RenderThemeWin::paintMenuListButtonDecorations(const RenderObject& renderer, const PaintInfo& paintInfo, const FloatRect& rect)
838 {
839     // FIXME: Don't make hardcoded assumptions about the thickness of the textfield border.
840     int borderThickness = haveTheme ? 1 : 2;
841
842     // Paint the dropdown button on the inner edge of the text field,
843     // leaving space for the text field's 1px border
844     IntRect buttonRect(rect);
845     buttonRect.inflate(-borderThickness);
846     if (renderer.style().direction() == LTR)
847         buttonRect.setX(buttonRect.maxX() - dropDownButtonWidth);
848     buttonRect.setWidth(dropDownButtonWidth);
849
850     if ((windowsVersion() >= WindowsVista)) {
851         // Outset the top, right, and bottom borders of the button so that they coincide with the <select>'s border.
852         buttonRect.setY(buttonRect.y() - vistaMenuListButtonOutset);
853         buttonRect.setHeight(buttonRect.height() + 2 * vistaMenuListButtonOutset);
854         buttonRect.setWidth(buttonRect.width() + vistaMenuListButtonOutset);
855     }
856
857     drawControl(paintInfo.context, renderer, menuListTheme(), getThemeData(renderer), buttonRect);
858
859     return false;
860 }
861
862 const int trackWidth = 4;
863
864 bool RenderThemeWin::paintSliderTrack(const RenderObject& o, const PaintInfo& i, const IntRect& r)
865 {
866     IntRect bounds = r;
867     
868     if (o.style().appearance() ==  SliderHorizontalPart) {
869         bounds.setHeight(trackWidth);
870         bounds.setY(r.y() + r.height() / 2 - trackWidth / 2);
871     } else if (o.style().appearance() == SliderVerticalPart) {
872         bounds.setWidth(trackWidth);
873         bounds.setX(r.x() + r.width() / 2 - trackWidth / 2);
874     }
875     
876     drawControl(i.context,  o, sliderTheme(), getThemeData(o), bounds);
877     return false;
878 }
879
880 bool RenderThemeWin::paintSliderThumb(const RenderObject& o, const PaintInfo& i, const IntRect& r)
881 {   
882     drawControl(i.context,  o, sliderTheme(), getThemeData(o), r);
883     return false;
884 }
885
886 const int sliderThumbWidth = 7;
887 const int sliderThumbHeight = 15;
888
889 void RenderThemeWin::adjustSliderThumbSize(RenderStyle* style, Element*) const
890 {
891     ControlPart part = style->appearance();
892     if (part == SliderThumbVerticalPart) {
893         style->setWidth(Length(sliderThumbHeight, Fixed));
894         style->setHeight(Length(sliderThumbWidth, Fixed));
895     } else if (part == SliderThumbHorizontalPart) {
896         style->setWidth(Length(sliderThumbWidth, Fixed));
897         style->setHeight(Length(sliderThumbHeight, Fixed));
898     }
899 #if ENABLE(VIDEO) && USE(CG)
900     else if (part == MediaSliderThumbPart || part == MediaVolumeSliderThumbPart) 
901         RenderMediaControls::adjustMediaSliderThumbSize(style);
902 #endif
903 }
904
905 bool RenderThemeWin::paintSearchField(const RenderObject& o, const PaintInfo& i, const IntRect& r)
906 {
907     return paintTextField(o, i, r);
908 }
909
910 void RenderThemeWin::adjustSearchFieldStyle(StyleResolver* styleResolver, RenderStyle* style, Element* e) const
911 {
912     // Override paddingSize to match AppKit text positioning.
913     const int padding = 1;
914     style->setPaddingLeft(Length(padding, Fixed));
915     style->setPaddingRight(Length(padding, Fixed));
916     style->setPaddingTop(Length(padding, Fixed));
917     style->setPaddingBottom(Length(padding, Fixed));
918     if (e && e->focused() && e->document().frame()->selection().isFocusedAndActive())
919         style->setOutlineOffset(-2);
920 }
921
922 bool RenderThemeWin::paintSearchFieldCancelButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r)
923 {
924     IntRect bounds = r;
925     ASSERT(o.parent());
926     if (!o.parent() || !o.parent()->isBox())
927         return false;
928     
929     RenderBox* parentRenderBox = toRenderBox(o.parent());
930
931     IntRect parentBox = parentRenderBox->absoluteContentBox();
932     
933     // Make sure the scaled button stays square and will fit in its parent's box
934     bounds.setHeight(min(parentBox.width(), min(parentBox.height(), bounds.height())));
935     bounds.setWidth(bounds.height());
936
937     // Center the button vertically.  Round up though, so if it has to be one pixel off-center, it will
938     // be one pixel closer to the bottom of the field.  This tends to look better with the text.
939     bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
940
941     static Image* cancelImage = Image::loadPlatformResource("searchCancel").leakRef();
942     static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").leakRef();
943     paintInfo.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, o.style().colorSpace(), bounds);
944     return false;
945 }
946
947 void RenderThemeWin::adjustSearchFieldCancelButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
948 {
949     // Scale the button size based on the font size
950     float fontScale = style->fontSize() / defaultControlFontPixelSize;
951     int cancelButtonSize = lroundf(min(max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
952     style->setWidth(Length(cancelButtonSize, Fixed));
953     style->setHeight(Length(cancelButtonSize, Fixed));
954 }
955
956 void RenderThemeWin::adjustSearchFieldDecorationPartStyle(StyleResolver*, RenderStyle* style, Element*) const
957 {
958     IntSize emptySize(1, 11);
959     style->setWidth(Length(emptySize.width(), Fixed));
960     style->setHeight(Length(emptySize.height(), Fixed));
961 }
962
963 void RenderThemeWin::adjustSearchFieldResultsDecorationPartStyle(StyleResolver*, RenderStyle* style, Element*) const
964 {
965     // Scale the decoration size based on the font size
966     float fontScale = style->fontSize() / defaultControlFontPixelSize;
967     int magnifierSize = lroundf(min(max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 
968                                      maxSearchFieldResultsDecorationSize));
969     style->setWidth(Length(magnifierSize, Fixed));
970     style->setHeight(Length(magnifierSize, Fixed));
971 }
972
973 bool RenderThemeWin::paintSearchFieldResultsDecorationPart(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r)
974 {
975     IntRect bounds = r;
976     ASSERT(o.parent());
977     if (!o.parent() || !o.parent()->isBox())
978         return false;
979     
980     RenderBox* parentRenderBox = toRenderBox(o.parent());
981     IntRect parentBox = parentRenderBox->absoluteContentBox();
982     
983     // Make sure the scaled decoration stays square and will fit in its parent's box
984     bounds.setHeight(min(parentBox.width(), min(parentBox.height(), bounds.height())));
985     bounds.setWidth(bounds.height());
986
987     // Center the decoration vertically.  Round up though, so if it has to be one pixel off-center, it will
988     // be one pixel closer to the bottom of the field.  This tends to look better with the text.
989     bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
990     
991     static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").leakRef();
992     paintInfo.context->drawImage(magnifierImage, o.style().colorSpace(), bounds);
993     return false;
994 }
995
996 void RenderThemeWin::adjustSearchFieldResultsButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
997 {
998     // Scale the button size based on the font size
999     float fontScale = style->fontSize() / defaultControlFontPixelSize;
1000     int magnifierHeight = lroundf(min(max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 
1001                                    maxSearchFieldResultsDecorationSize));
1002     int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize);
1003     style->setWidth(Length(magnifierWidth, Fixed));
1004     style->setHeight(Length(magnifierHeight, Fixed));
1005 }
1006
1007 bool RenderThemeWin::paintSearchFieldResultsButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r)
1008 {
1009     IntRect bounds = r;
1010     ASSERT(o.parent());
1011     if (!o.parent())
1012         return false;
1013     if (!o.parent() || !o.parent()->isBox())
1014         return false;
1015     
1016     RenderBox* parentRenderBox = toRenderBox(o.parent());
1017     IntRect parentBox = parentRenderBox->absoluteContentBox();
1018     
1019     // Make sure the scaled decoration will fit in its parent's box
1020     bounds.setHeight(min(parentBox.height(), bounds.height()));
1021     bounds.setWidth(min<int>(parentBox.width(), bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize));
1022
1023     // Center the button vertically.  Round up though, so if it has to be one pixel off-center, it will
1024     // be one pixel closer to the bottom of the field.  This tends to look better with the text.
1025     bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
1026
1027     static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").leakRef();
1028     paintInfo.context->drawImage(magnifierImage, o.style().colorSpace(), bounds);
1029     return false;
1030 }
1031
1032 // Map a CSSValue* system color to an index understood by GetSysColor
1033 static int cssValueIdToSysColorIndex(CSSValueID cssValueId)
1034 {
1035     switch (cssValueId) {
1036     case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
1037     case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
1038     case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
1039     case CSSValueBackground: return COLOR_BACKGROUND;
1040     case CSSValueButtonface: return COLOR_BTNFACE;
1041     case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
1042     case CSSValueButtonshadow: return COLOR_BTNSHADOW;
1043     case CSSValueButtontext: return COLOR_BTNTEXT;
1044     case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
1045     case CSSValueGraytext: return COLOR_GRAYTEXT;
1046     case CSSValueHighlight: return COLOR_HIGHLIGHT;
1047     case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
1048     case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
1049     case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
1050     case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
1051     case CSSValueInfobackground: return COLOR_INFOBK;
1052     case CSSValueInfotext: return COLOR_INFOTEXT;
1053     case CSSValueMenu: return COLOR_MENU;
1054     case CSSValueMenutext: return COLOR_MENUTEXT;
1055     case CSSValueScrollbar: return COLOR_SCROLLBAR;
1056     case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
1057     case CSSValueThreedface: return COLOR_3DFACE;
1058     case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
1059     case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
1060     case CSSValueThreedshadow: return COLOR_3DSHADOW;
1061     case CSSValueWindow: return COLOR_WINDOW;
1062     case CSSValueWindowframe: return COLOR_WINDOWFRAME;
1063     case CSSValueWindowtext: return COLOR_WINDOWTEXT;
1064     default: return -1; // Unsupported CSSValue
1065     }
1066 }
1067
1068 Color RenderThemeWin::systemColor(CSSValueID cssValueId) const
1069 {
1070     int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
1071     if (sysColorIndex == -1)
1072         return RenderTheme::systemColor(cssValueId);
1073
1074     COLORREF color = GetSysColor(sysColorIndex);
1075     return Color(GetRValue(color), GetGValue(color), GetBValue(color));
1076 }
1077
1078 #if ENABLE(VIDEO)
1079 static const size_t maximumReasonableBufferSize = 32768;
1080
1081 static void fillBufferWithContentsOfFile(PlatformFileHandle file, long long filesize, Vector<char>& buffer)
1082 {
1083     // Load the file content into buffer
1084     buffer.resize(filesize + 1);
1085
1086     int bufferPosition = 0;
1087     int bufferReadSize = 4096;
1088     int bytesRead = 0;
1089     while (filesize > bufferPosition) {
1090         if (filesize - bufferPosition < bufferReadSize)
1091             bufferReadSize = filesize - bufferPosition;
1092
1093         bytesRead = readFromFile(file, buffer.data() + bufferPosition, bufferReadSize);
1094         if (bytesRead != bufferReadSize) {
1095             buffer.clear();
1096             return;
1097         }
1098
1099         bufferPosition += bufferReadSize;
1100     }
1101
1102     buffer[filesize] = 0;
1103 }
1104
1105 String RenderThemeWin::stringWithContentsOfFile(CFStringRef name, CFStringRef type)
1106 {
1107     RetainPtr<CFURLRef> requestedURLRef = adoptCF(CFBundleCopyResourceURL(webKitBundle(), name, type, 0));
1108     if (!requestedURLRef)
1109         return String();
1110
1111     UInt8 requestedFilePath[MAX_PATH];
1112     if (!CFURLGetFileSystemRepresentation(requestedURLRef.get(), false, requestedFilePath, MAX_PATH))
1113         return String();
1114
1115     PlatformFileHandle requestedFileHandle = openFile(requestedFilePath, OpenForRead);
1116     if (!isHandleValid(requestedFileHandle))
1117         return String();
1118
1119     long long filesize = -1;
1120     if (!getFileSize(requestedFilePath, filesize)) {
1121         closeFile(requestedFileHandle);
1122         return String();
1123     }
1124
1125     Vector<char> fileContents;
1126     fillBufferWithContentsOfFile(requestedFileHandle, filesize, fileContents);
1127     closeFile(requestedFileHandle);
1128
1129     return String(fileContents.data(), static_cast<size_t>(filesize));
1130 }
1131
1132 String RenderThemeWin::mediaControlsStyleSheet()
1133 {
1134 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1135     if (m_mediaControlsStyleSheet.isEmpty())
1136         m_mediaControlsStyleSheet = stringWithContentsOfFile(CFSTR("mediaControlsApple"), CFSTR("css"));
1137     return m_mediaControlsStyleSheet;
1138 #else
1139     return emptyString();
1140 #endif
1141 }
1142
1143 String RenderThemeWin::mediaControlsScript()
1144 {
1145 #if ENABLE(MEDIA_CONTROLS_SCRIPT)
1146     if (m_mediaControlsScript.isEmpty()) {
1147         StringBuilder scriptBuilder;
1148         scriptBuilder.append(stringWithContentsOfFile(CFSTR("mediaControlsLocalizedStrings"), CFSTR("js")));
1149         scriptBuilder.append(stringWithContentsOfFile(CFSTR("mediaControlsApple"), CFSTR("js")));
1150         m_mediaControlsScript = scriptBuilder.toString();
1151     }
1152     return m_mediaControlsScript;
1153 #else
1154     return emptyString();
1155 #endif
1156 }
1157 #endif
1158
1159 #if ENABLE(METER_ELEMENT)
1160 void RenderThemeWin::adjustMeterStyle(StyleResolver*, RenderStyle* style, Element*) const
1161 {
1162     style->setBoxShadow(nullptr);
1163 }
1164
1165 bool RenderThemeWin::supportsMeter(ControlPart part) const
1166 {
1167     switch (part) {
1168     case MeterPart:
1169         return true;
1170     default:
1171         return false;
1172     }
1173 }
1174
1175 IntSize RenderThemeWin::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
1176 {
1177     return bounds.size();
1178 }
1179
1180 bool RenderThemeWin::paintMeter(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
1181 {
1182     if (!renderObject.isMeter())
1183         return true;
1184
1185     HTMLMeterElement* element = toRenderMeter(&renderObject)->meterElement();
1186
1187     ThemeData theme = getThemeData(renderObject);
1188
1189     int remaining = static_cast<int>((1.0 - element->valueRatio()) * static_cast<double>(rect.size().width()));
1190
1191     // Draw the background
1192     drawControl(paintInfo.context, renderObject, progressBarTheme(), theme, rect);
1193
1194     // Draw the progress portion
1195     IntRect completedRect(rect);
1196     completedRect.contract(remaining, 0);
1197
1198     theme.m_part = PP_FILL;
1199     drawControl(paintInfo.context, renderObject, progressBarTheme(), theme, completedRect);
1200
1201     return true;
1202 }
1203
1204 #endif
1205
1206
1207 }