2 * This file is part of the WebKit project.
4 * Copyright (C) 2006 Apple Computer, Inc.
5 * Copyright (C) 2008, 2009 Google, Inc.
6 * Copyright (C) 2009 Kenneth Rohde Christiansen
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
26 #include "RenderThemeChromiumWin.h"
32 #include "CSSValueKeywords.h"
33 #include "FontSelector.h"
34 #include "FontUtilsChromiumWin.h"
35 #include "GraphicsContext.h"
36 #include "HTMLMediaElement.h"
37 #include "HTMLNames.h"
39 #include "LayoutTestSupport.h"
40 #include "MediaControlElements.h"
41 #include "PaintInfo.h"
42 #include "PlatformSupport.h"
43 #include "RenderBox.h"
44 #include "RenderProgress.h"
45 #include "RenderSlider.h"
46 #include "ScrollbarTheme.h"
47 #include "SystemInfo.h"
48 #include "TransparencyWin.h"
49 #include <wtf/CurrentTime.h>
52 // FIXME: This dependency should eventually be removed.
53 #include <skia/ext/skia_utils_win.h>
55 #define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
56 offsetof(structName, member) + \
57 (sizeof static_cast<structName*>(0)->member)
58 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \
59 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
63 // The standard width for the menu list drop-down button when run under
64 // layout test mode. Use the value that's currently captured in most baselines.
65 static const int kStandardMenuListButtonWidth = 17;
68 // We must not create multiple ThemePainter instances.
71 ThemePainter(GraphicsContext* context, const IntRect& r)
74 ASSERT(!s_hasInstance);
77 TransparencyWin::TransformMode transformMode = getTransformMode(context->getCTM());
78 m_helper.init(context, getLayerMode(context, transformMode), transformMode, r);
80 if (!m_helper.context()) {
81 // TransparencyWin doesn't have well-defined copy-ctor nor op=()
82 // so we re-initialize it instead of assigning a fresh istance.
83 // On the reinitialization, we fallback to use NoLayer mode.
84 // Note that the original initialization failure can be caused by
85 // a failure of an internal buffer allocation and NoLayer mode
86 // does not have such buffer allocations.
87 m_helper.~TransparencyWin();
88 new (&m_helper) TransparencyWin();
89 m_helper.init(context, TransparencyWin::NoLayer, transformMode, r);
97 s_hasInstance = false;
101 GraphicsContext* context() { return m_helper.context(); }
102 const IntRect& drawRect() { return m_helper.drawRect(); }
106 static TransparencyWin::LayerMode getLayerMode(GraphicsContext* context, TransparencyWin::TransformMode transformMode)
108 if (context->platformContext()->isDrawingToImageBuffer()) // Might have transparent background.
109 return TransparencyWin::WhiteLayer;
110 if (context->platformContext()->canvas()->isDrawingToLayer()) // Needs antialiasing help.
111 return TransparencyWin::OpaqueCompositeLayer;
112 // Nothing interesting.
113 return transformMode == TransparencyWin::KeepTransform ? TransparencyWin::NoLayer : TransparencyWin::OpaqueCompositeLayer;
116 static TransparencyWin::TransformMode getTransformMode(const AffineTransform& matrix)
118 if (matrix.b() || matrix.c()) // Skew.
119 return TransparencyWin::Untransform;
120 if (matrix.a() != 1.0 || matrix.d() != 1.0) // Scale.
121 return TransparencyWin::ScaleTransform;
122 // Nothing interesting.
123 return TransparencyWin::KeepTransform;
126 TransparencyWin m_helper;
128 static bool s_hasInstance;
133 bool ThemePainter::s_hasInstance = false;
138 static void getNonClientMetrics(NONCLIENTMETRICS* metrics)
140 static UINT size = (windowsVersion() >= WindowsVista) ?
141 sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
142 metrics->cbSize = size;
143 bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0);
147 static FontDescription smallSystemFont;
148 static FontDescription menuFont;
149 static FontDescription labelFont;
151 // Internal static helper functions. We don't put them in an anonymous
152 // namespace so they have easier access to the WebCore namespace.
154 static bool supportsFocus(ControlPart appearance)
156 switch (appearance) {
157 case SquareButtonPart:
160 case DefaultButtonPart:
161 case SearchFieldPart:
169 // Return the height of system font |font| in pixels. We use this size by
170 // default for some non-form-control elements.
171 static float systemFontSize(const LOGFONT& font)
173 float size = -font.lfHeight;
175 HFONT hFont = CreateFontIndirect(&font);
177 HWndDC hdc(0); // What about printing? Is this the right DC?
179 HGDIOBJ hObject = SelectObject(hdc, hFont);
181 GetTextMetrics(hdc, &tm);
182 SelectObject(hdc, hObject);
189 // The "codepage 936" bit here is from Gecko; apparently this helps make
190 // fonts more legible in Simplified Chinese where the default font size is
193 // FIXME: http://b/1119883 Since this is only used for "small caption",
194 // "menu", and "status bar" objects, I'm not sure how much this even
195 // matters. Plus the Gecko patch went in back in 2002, and maybe this
196 // isn't even relevant anymore. We should investigate whether this should
197 // be removed, or perhaps broadened to be "any CJK locale".
199 return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
202 // Converts |points| to pixels. One point is 1/72 of an inch.
203 static float pointsToPixels(float points)
205 static float pixelsPerInch = 0.0f;
206 if (!pixelsPerInch) {
207 HWndDC hdc(0); // What about printing? Is this the right DC?
208 if (hdc) // Can this ever actually be NULL?
209 pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
211 pixelsPerInch = 96.0f;
214 static const float pointsPerInch = 72.0f;
215 return points / pointsPerInch * pixelsPerInch;
218 static double querySystemBlinkInterval(double defaultInterval)
220 UINT blinkTime = GetCaretBlinkTime();
222 return defaultInterval;
223 if (blinkTime == INFINITE)
225 return blinkTime / 1000.0;
228 PassRefPtr<RenderTheme> RenderThemeChromiumWin::create()
230 return adoptRef(new RenderThemeChromiumWin);
233 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
235 static RenderTheme* rt = RenderThemeChromiumWin::create().leakRef();
239 bool RenderThemeChromiumWin::supportsFocusRing(const RenderStyle* style) const
241 // Let webkit draw one of its halo rings around any focused element,
242 // except push buttons. For buttons we use the windows PBS_DEFAULTED
243 // styling to give it a blue border.
244 return style->appearance() == ButtonPart
245 || style->appearance() == PushButtonPart
246 || style->appearance() == SquareButtonPart;
249 Color RenderThemeChromiumWin::platformActiveSelectionBackgroundColor() const
251 if (isRunningLayoutTest())
252 return Color(0x00, 0x00, 0xff); // Royal blue.
253 COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
254 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
257 Color RenderThemeChromiumWin::platformInactiveSelectionBackgroundColor() const
259 if (isRunningLayoutTest())
260 return Color(0x99, 0x99, 0x99); // Medium gray.
261 COLORREF color = GetSysColor(COLOR_GRAYTEXT);
262 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
265 Color RenderThemeChromiumWin::platformActiveSelectionForegroundColor() const
267 if (isRunningLayoutTest())
268 return Color(0xff, 0xff, 0xcc); // Pale yellow.
269 COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
270 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
273 Color RenderThemeChromiumWin::platformInactiveSelectionForegroundColor() const
278 Color RenderThemeChromiumWin::platformActiveTextSearchHighlightColor() const
280 return Color(0xff, 0x96, 0x32); // Orange.
283 Color RenderThemeChromiumWin::platformInactiveTextSearchHighlightColor() const
285 return Color(0xff, 0xff, 0x96); // Yellow.
288 void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescription) const
290 // This logic owes much to RenderThemeSafari.cpp.
291 FontDescription* cachedDesc = 0;
292 AtomicString faceName;
295 case CSSValueSmallCaption:
296 cachedDesc = &smallSystemFont;
297 if (!smallSystemFont.isAbsoluteSize()) {
298 NONCLIENTMETRICS metrics;
299 getNonClientMetrics(&metrics);
300 faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName));
301 fontSize = systemFontSize(metrics.lfSmCaptionFont);
305 cachedDesc = &menuFont;
306 if (!menuFont.isAbsoluteSize()) {
307 NONCLIENTMETRICS metrics;
308 getNonClientMetrics(&metrics);
309 faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName));
310 fontSize = systemFontSize(metrics.lfMenuFont);
313 case CSSValueStatusBar:
314 cachedDesc = &labelFont;
315 if (!labelFont.isAbsoluteSize()) {
316 NONCLIENTMETRICS metrics;
317 getNonClientMetrics(&metrics);
318 faceName = metrics.lfStatusFont.lfFaceName;
319 fontSize = systemFontSize(metrics.lfStatusFont);
322 case CSSValueWebkitMiniControl:
323 case CSSValueWebkitSmallControl:
324 case CSSValueWebkitControl:
325 faceName = defaultGUIFont();
326 // Why 2 points smaller? Because that's what Gecko does.
327 fontSize = defaultFontSize - pointsToPixels(2);
330 faceName = defaultGUIFont();
331 fontSize = defaultFontSize;
336 cachedDesc = &fontDescription;
339 cachedDesc->firstFamily().setFamily(faceName);
340 cachedDesc->setIsAbsoluteSize(true);
341 cachedDesc->setGenericFamily(FontDescription::NoFamily);
342 cachedDesc->setSpecifiedSize(fontSize);
343 cachedDesc->setWeight(FontWeightNormal);
344 cachedDesc->setItalic(false);
346 fontDescription = *cachedDesc;
349 // Map a CSSValue* system color to an index understood by GetSysColor().
350 static int cssValueIdToSysColorIndex(int cssValueId)
352 switch (cssValueId) {
353 case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
354 case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
355 case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
356 case CSSValueBackground: return COLOR_BACKGROUND;
357 case CSSValueButtonface: return COLOR_BTNFACE;
358 case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
359 case CSSValueButtonshadow: return COLOR_BTNSHADOW;
360 case CSSValueButtontext: return COLOR_BTNTEXT;
361 case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
362 case CSSValueGraytext: return COLOR_GRAYTEXT;
363 case CSSValueHighlight: return COLOR_HIGHLIGHT;
364 case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
365 case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
366 case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
367 case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
368 case CSSValueInfobackground: return COLOR_INFOBK;
369 case CSSValueInfotext: return COLOR_INFOTEXT;
370 case CSSValueMenu: return COLOR_MENU;
371 case CSSValueMenutext: return COLOR_MENUTEXT;
372 case CSSValueScrollbar: return COLOR_SCROLLBAR;
373 case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
374 case CSSValueThreedface: return COLOR_3DFACE;
375 case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
376 case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
377 case CSSValueThreedshadow: return COLOR_3DSHADOW;
378 case CSSValueWindow: return COLOR_WINDOW;
379 case CSSValueWindowframe: return COLOR_WINDOWFRAME;
380 case CSSValueWindowtext: return COLOR_WINDOWTEXT;
381 default: return -1; // Unsupported CSSValue
385 Color RenderThemeChromiumWin::systemColor(int cssValueId) const
387 int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
388 if (isRunningLayoutTest() || (sysColorIndex == -1))
389 return RenderTheme::systemColor(cssValueId);
391 COLORREF color = GetSysColor(sysColorIndex);
392 return Color(GetRValue(color), GetGValue(color), GetBValue(color));
395 #if ENABLE(DATALIST_ELEMENT)
396 IntSize RenderThemeChromiumWin::sliderTickSize() const
398 return IntSize(1, 3);
401 int RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter() const
407 void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style, Element* element) const
409 // These sizes match what WinXP draws for various menus.
410 const int sliderThumbAlongAxis = 11;
411 const int sliderThumbAcrossAxis = 21;
412 if (style->appearance() == SliderThumbHorizontalPart) {
413 style->setWidth(Length(sliderThumbAlongAxis, Fixed));
414 style->setHeight(Length(sliderThumbAcrossAxis, Fixed));
415 } else if (style->appearance() == SliderThumbVerticalPart) {
416 style->setWidth(Length(sliderThumbAcrossAxis, Fixed));
417 style->setHeight(Length(sliderThumbAlongAxis, Fixed));
419 RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
422 bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
424 return paintButton(o, i, r);
426 bool RenderThemeChromiumWin::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
428 return paintButton(o, i, r);
431 bool RenderThemeChromiumWin::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
433 const ThemeData& themeData = getThemeData(o);
435 ThemePainter painter(i.context, r);
436 PlatformSupport::paintButton(painter.context(),
439 themeData.m_classicState,
444 bool RenderThemeChromiumWin::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
446 return paintTextFieldInternal(o, i, r, true);
449 bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
451 const ThemeData& themeData = getThemeData(o);
453 ThemePainter painter(i.context, r);
454 PlatformSupport::paintTrackbar(painter.context(),
457 themeData.m_classicState,
460 #if ENABLE(DATALIST_ELEMENT)
461 paintSliderTicks(o, i, r);
467 bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
469 const ThemeData& themeData = getThemeData(o);
471 ThemePainter painter(i.context, r);
472 PlatformSupport::paintTrackbar(painter.context(),
475 themeData.m_classicState,
481 static int menuListButtonWidth()
483 static int width = isRunningLayoutTest() ? kStandardMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL);
487 // Used to paint unstyled menulists (i.e. with the default border)
488 bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
493 const RenderBox* box = toRenderBox(o);
494 int borderRight = box->borderRight();
495 int borderLeft = box->borderLeft();
496 int borderTop = box->borderTop();
497 int borderBottom = box->borderBottom();
499 // If all the borders are 0, then tell skia not to paint the border on the
500 // textfield. FIXME: http://b/1210017 Figure out how to get Windows to not
501 // draw individual borders and then pass that to skia so we can avoid
502 // drawing any borders that are set to 0. For non-zero borders, we draw the
503 // border, but webkit just draws over it.
504 bool drawEdges = !(!borderRight && !borderLeft && !borderTop && !borderBottom);
506 paintTextFieldInternal(o, i, r, drawEdges);
508 // Take padding and border into account. If the MenuList is smaller than
509 // the size of a button, make sure to shrink it appropriately and not put
510 // its x position to the left of the menulist.
511 const int buttonWidth = menuListButtonWidth();
512 int spacingLeft = borderLeft + box->paddingLeft();
513 int spacingRight = borderRight + box->paddingRight();
514 int spacingTop = borderTop + box->paddingTop();
515 int spacingBottom = borderBottom + box->paddingBottom();
518 if (r.maxX() - r.x() < buttonWidth)
521 buttonX = o->style()->direction() == LTR ? r.maxX() - spacingRight - buttonWidth : r.x() + spacingLeft;
523 // Compute the rectangle of the button in the destination image.
524 IntRect rect(buttonX,
526 std::min(buttonWidth, r.maxX() - r.x()),
527 r.height() - (spacingTop + spacingBottom));
529 // Get the correct theme data for a textfield and paint the menu.
530 ThemePainter painter(i.context, rect);
531 PlatformSupport::paintMenuList(painter.context(),
534 determineClassicState(o),
540 void RenderThemeChromiumWin::setDefaultFontSize(int fontSize)
542 RenderThemeChromiumSkia::setDefaultFontSize(fontSize);
544 // Reset cached fonts.
545 smallSystemFont = menuFont = labelFont = FontDescription();
548 double RenderThemeChromiumWin::caretBlinkIntervalInternal() const
550 // This involves a system call, so we cache the result.
551 static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval());
552 return blinkInterval;
555 unsigned RenderThemeChromiumWin::determineState(RenderObject* o, ControlSubPart subPart)
557 unsigned result = TS_NORMAL;
558 ControlPart appearance = o->style()->appearance();
560 result = TS_DISABLED;
561 else if (isReadOnlyControl(o))
562 result = (appearance == TextFieldPart || appearance == TextAreaPart || appearance == SearchFieldPart) ? ETS_READONLY : TS_DISABLED;
563 // Active overrides hover and focused.
564 else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
566 else if (supportsFocus(appearance) && isFocused(o))
567 result = ETS_FOCUSED;
568 else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
571 // CBS_UNCHECKED*: 1-4
574 if (isIndeterminate(o))
576 else if (isChecked(o))
581 unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o)
583 unsigned result = TUS_NORMAL;
585 result = TUS_DISABLED;
586 else if (supportsFocus(o->style()->appearance()) && isFocused(o))
587 result = TUS_FOCUSED;
588 else if (isPressed(o))
589 result = TUS_PRESSED;
590 else if (isHovered(o))
595 unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o, ControlSubPart subPart)
599 ControlPart part = o->style()->appearance();
601 // Sliders are always in the normal state.
602 if (part == SliderHorizontalPart || part == SliderVerticalPart)
605 // So are readonly text fields.
606 if (isReadOnlyControl(o) && (part == TextFieldPart || part == TextAreaPart || part == SearchFieldPart))
609 if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
611 result = DFCS_INACTIVE;
612 else if (isPressed(o)) // Active supersedes hover
613 result = DFCS_PUSHED;
614 else if (isHovered(o))
617 if (!isEnabled(o) || isReadOnlyControl(o))
618 result = DFCS_INACTIVE;
619 // Active supersedes hover
620 else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
621 result = DFCS_PUSHED;
622 else if (supportsFocus(part) && isFocused(o)) // So does focused
624 else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
626 // Classic theme can't represent indeterminate states. Use unchecked appearance.
627 if (isChecked(o) && !isIndeterminate(o))
628 result |= DFCS_CHECKED;
633 ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o, ControlSubPart subPart)
636 switch (o->style()->appearance()) {
638 result.m_part = BP_CHECKBOX;
639 result.m_state = determineState(o);
640 result.m_classicState = DFCS_BUTTONCHECK;
643 result.m_part = BP_RADIOBUTTON;
644 result.m_state = determineState(o);
645 result.m_classicState = DFCS_BUTTONRADIO;
647 case SquareButtonPart:
650 result.m_part = BP_PUSHBUTTON;
651 result.m_state = determineState(o);
652 result.m_classicState = DFCS_BUTTONPUSH;
654 case SliderHorizontalPart:
655 result.m_part = TKP_TRACK;
656 result.m_state = TRS_NORMAL;
658 case SliderVerticalPart:
659 result.m_part = TKP_TRACKVERT;
660 result.m_state = TRVS_NORMAL;
662 case SliderThumbHorizontalPart:
663 result.m_part = TKP_THUMBBOTTOM;
664 result.m_state = determineSliderThumbState(o);
666 case SliderThumbVerticalPart:
667 result.m_part = TKP_THUMBVERT;
668 result.m_state = determineSliderThumbState(o);
672 case MenulistButtonPart:
673 case SearchFieldPart:
676 result.m_part = EP_EDITTEXT;
677 result.m_state = determineState(o);
679 case InnerSpinButtonPart:
680 result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
681 result.m_state = determineState(o, subPart);
682 result.m_classicState = subPart == SpinButtonUp ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
686 result.m_classicState |= determineClassicState(o, subPart);
691 bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
696 // Fallback to white if the specified color object is invalid.
697 // (Note PlatformSupport::paintTextField duplicates this check).
698 Color backgroundColor(Color::white);
699 if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
700 backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);
702 // If we have background-image, don't fill the content area to expose the
703 // parent's background. Also, we shouldn't fill the content area if the
704 // alpha of the color is 0. The API of Windows GDI ignores the alpha.
706 // Note that we should paint the content area white if we have neither the
707 // background color nor background image explicitly specified to keep the
708 // appearance of select element consistent with other browsers.
709 bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha();
711 if (o->style()->hasBorderRadius()) {
712 // If the style has rounded borders, setup the context to clip the
713 // background (themed or filled) appropriately.
714 // FIXME: make sure we do the right thing if css background-clip is set.
716 i.context->addRoundedRectClip(o->style()->getRoundedBorderFor(r));
719 const ThemeData& themeData = getThemeData(o);
720 ThemePainter painter(i.context, r);
721 PlatformSupport::paintTextField(painter.context(),
724 themeData.m_classicState,
729 // End of block commits the painter before restoring context.
731 if (o->style()->hasBorderRadius())
732 i.context->restore();
736 void RenderThemeChromiumWin::adjustInnerSpinButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
738 int width = ScrollbarTheme::theme()->scrollbarThickness();
739 style->setWidth(Length(width, Fixed));
740 style->setMinWidth(Length(width, Fixed));
743 bool RenderThemeChromiumWin::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
747 // Need explicit blocks to avoid to create multiple ThemePainter instances.
749 half.setHeight(rect.height() / 2);
750 const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
751 ThemePainter upPainter(info.context, half);
752 PlatformSupport::paintSpinButton(upPainter.context(),
755 upThemeData.m_classicState,
756 upPainter.drawRect());
760 half.setY(rect.y() + rect.height() / 2);
761 const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
762 ThemePainter downPainter(info.context, half);
763 PlatformSupport::paintSpinButton(downPainter.context(),
764 downThemeData.m_part,
765 downThemeData.m_state,
766 downThemeData.m_classicState,
767 downPainter.drawRect());
772 #if ENABLE(PROGRESS_ELEMENT)
774 // MSDN says that update intervals for the bar is 30ms.
775 // http://msdn.microsoft.com/en-us/library/bb760842(v=VS.85).aspx
776 static const double progressAnimationFrameRate = 0.033;
778 double RenderThemeChromiumWin::animationRepeatIntervalForProgressBar(RenderProgress*) const
780 return progressAnimationFrameRate;
783 double RenderThemeChromiumWin::animationDurationForProgressBar(RenderProgress* renderProgress) const
785 // On Chromium Windows port, animationProgress() and associated values aren't used.
786 // So here we can return arbitrary positive value.
787 return progressAnimationFrameRate;
790 void RenderThemeChromiumWin::adjustProgressBarStyle(StyleResolver*, RenderStyle*, Element*) const
794 bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& r)
796 if (!o->isProgress())
799 RenderProgress* renderProgress = toRenderProgress(o);
800 // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
801 // because the animation is a platform detail and WebKit doesn't need to know how.
802 IntRect valueRect = renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, r) : IntRect(0, 0, 0, 0);
803 double animatedSeconds = renderProgress->animationStartTime() ? WTF::currentTime() - renderProgress->animationStartTime() : 0;
804 ThemePainter painter(i.context, r);
805 DirectionFlippingScope scope(o, i, r);
806 PlatformSupport::paintProgressBar(painter.context(), r, valueRect, renderProgress->isDeterminate(), animatedSeconds);
812 } // namespace WebCore