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