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