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