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 "ChromiumBridge.h"
34 #include "CurrentTime.h"
35 #include "FontSelector.h"
36 #include "FontUtilsChromiumWin.h"
37 #include "GraphicsContext.h"
38 #include "HTMLMediaElement.h"
39 #include "HTMLNames.h"
40 #include "MediaControlElements.h"
41 #include "PaintInfo.h"
42 #include "RenderBox.h"
43 #include "RenderProgress.h"
44 #include "RenderSlider.h"
45 #include "ScrollbarTheme.h"
46 #include "TransparencyWin.h"
47 #include "WindowsVersion.h"
49 // FIXME: This dependency should eventually be removed.
50 #include <skia/ext/skia_utils_win.h>
52 #define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
53 offsetof(structName, member) + \
54 (sizeof static_cast<structName*>(0)->member)
55 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \
56 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
60 // The standard width for the menu list drop-down button when run under
61 // layout test mode. Use the value that's currently captured in most baselines.
62 static const int kStandardMenuListButtonWidth = 17;
67 ThemePainter(GraphicsContext* context, const IntRect& r)
69 TransparencyWin::TransformMode transformMode = getTransformMode(context->getCTM());
70 m_helper.init(context, getLayerMode(context, transformMode), transformMode, r);
72 if (!m_helper.context()) {
73 // TransparencyWin doesn't have well-defined copy-ctor nor op=()
74 // so we re-initialize it instead of assigning a fresh istance.
75 // On the reinitialization, we fallback to use NoLayer mode.
76 // Note that the original initialization failure can be caused by
77 // a failure of an internal buffer allocation and NoLayer mode
78 // does not have such buffer allocations.
79 m_helper.~TransparencyWin();
80 new (&m_helper) TransparencyWin();
81 m_helper.init(context, TransparencyWin::NoLayer, transformMode, r);
90 GraphicsContext* context() { return m_helper.context(); }
91 const IntRect& drawRect() { return m_helper.drawRect(); }
95 static bool canvasHasMultipleLayers(const SkCanvas* canvas)
97 SkCanvas::LayerIter iter(const_cast<SkCanvas*>(canvas), false);
98 iter.next(); // There is always at least one layer.
99 return !iter.done(); // There is > 1 layer if the the iterator can stil advance.
102 static TransparencyWin::LayerMode getLayerMode(GraphicsContext* context, TransparencyWin::TransformMode transformMode)
104 if (context->platformContext()->isDrawingToImageBuffer()) // Might have transparent background.
105 return TransparencyWin::WhiteLayer;
106 if (canvasHasMultipleLayers(context->platformContext()->canvas())) // Needs antialiasing help.
107 return TransparencyWin::OpaqueCompositeLayer;
108 // Nothing interesting.
109 return transformMode == TransparencyWin::KeepTransform ? TransparencyWin::NoLayer : TransparencyWin::OpaqueCompositeLayer;
112 static TransparencyWin::TransformMode getTransformMode(const AffineTransform& matrix)
114 if (matrix.b() || matrix.c()) // Skew.
115 return TransparencyWin::Untransform;
116 if (matrix.a() != 1.0 || matrix.d() != 1.0) // Scale.
117 return TransparencyWin::ScaleTransform;
118 // Nothing interesting.
119 return TransparencyWin::KeepTransform;
122 TransparencyWin m_helper;
127 static void getNonClientMetrics(NONCLIENTMETRICS* metrics)
129 static UINT size = isVistaOrNewer() ?
130 sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
131 metrics->cbSize = size;
132 bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, size, metrics, 0);
136 static FontDescription smallSystemFont;
137 static FontDescription menuFont;
138 static FontDescription labelFont;
140 // Internal static helper functions. We don't put them in an anonymous
141 // namespace so they have easier access to the WebCore namespace.
143 static bool supportsFocus(ControlPart appearance)
145 switch (appearance) {
148 case DefaultButtonPart:
149 case SearchFieldPart:
157 // Return the height of system font |font| in pixels. We use this size by
158 // default for some non-form-control elements.
159 static float systemFontSize(const LOGFONT& font)
161 float size = -font.lfHeight;
163 HFONT hFont = CreateFontIndirect(&font);
165 HDC hdc = GetDC(0); // What about printing? Is this the right DC?
167 HGDIOBJ hObject = SelectObject(hdc, hFont);
169 GetTextMetrics(hdc, &tm);
170 SelectObject(hdc, hObject);
178 // The "codepage 936" bit here is from Gecko; apparently this helps make
179 // fonts more legible in Simplified Chinese where the default font size is
182 // FIXME: http://b/1119883 Since this is only used for "small caption",
183 // "menu", and "status bar" objects, I'm not sure how much this even
184 // matters. Plus the Gecko patch went in back in 2002, and maybe this
185 // isn't even relevant anymore. We should investigate whether this should
186 // be removed, or perhaps broadened to be "any CJK locale".
188 return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
191 // Converts |points| to pixels. One point is 1/72 of an inch.
192 static float pointsToPixels(float points)
194 static float pixelsPerInch = 0.0f;
195 if (!pixelsPerInch) {
196 HDC hdc = GetDC(0); // What about printing? Is this the right DC?
197 if (hdc) { // Can this ever actually be NULL?
198 pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
201 pixelsPerInch = 96.0f;
205 static const float pointsPerInch = 72.0f;
206 return points / pointsPerInch * pixelsPerInch;
209 static double querySystemBlinkInterval(double defaultInterval)
211 UINT blinkTime = GetCaretBlinkTime();
213 return defaultInterval;
214 if (blinkTime == INFINITE)
216 return blinkTime / 1000.0;
219 PassRefPtr<RenderTheme> RenderThemeChromiumWin::create()
221 return adoptRef(new RenderThemeChromiumWin);
224 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
226 static RenderTheme* rt = RenderThemeChromiumWin::create().releaseRef();
230 bool RenderThemeChromiumWin::supportsFocusRing(const RenderStyle* style) const
232 // Let webkit draw one of its halo rings around any focused element,
233 // except push buttons. For buttons we use the windows PBS_DEFAULTED
234 // styling to give it a blue border.
235 return style->appearance() == ButtonPart
236 || style->appearance() == PushButtonPart;
239 Color RenderThemeChromiumWin::platformActiveSelectionBackgroundColor() const
241 if (ChromiumBridge::layoutTestMode())
242 return Color(0x00, 0x00, 0xff); // Royal blue.
243 COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
244 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
247 Color RenderThemeChromiumWin::platformInactiveSelectionBackgroundColor() const
249 if (ChromiumBridge::layoutTestMode())
250 return Color(0x99, 0x99, 0x99); // Medium gray.
251 COLORREF color = GetSysColor(COLOR_GRAYTEXT);
252 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
255 Color RenderThemeChromiumWin::platformActiveSelectionForegroundColor() const
257 if (ChromiumBridge::layoutTestMode())
258 return Color(0xff, 0xff, 0xcc); // Pale yellow.
259 COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
260 return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
263 Color RenderThemeChromiumWin::platformInactiveSelectionForegroundColor() const
268 Color RenderThemeChromiumWin::platformActiveTextSearchHighlightColor() const
270 return Color(0xff, 0x96, 0x32); // Orange.
273 Color RenderThemeChromiumWin::platformInactiveTextSearchHighlightColor() const
275 return Color(0xff, 0xff, 0x96); // Yellow.
278 void RenderThemeChromiumWin::systemFont(int propId, FontDescription& fontDescription) const
280 // This logic owes much to RenderThemeSafari.cpp.
281 FontDescription* cachedDesc = 0;
282 AtomicString faceName;
285 case CSSValueSmallCaption:
286 cachedDesc = &smallSystemFont;
287 if (!smallSystemFont.isAbsoluteSize()) {
288 NONCLIENTMETRICS metrics;
289 getNonClientMetrics(&metrics);
290 faceName = AtomicString(metrics.lfSmCaptionFont.lfFaceName, wcslen(metrics.lfSmCaptionFont.lfFaceName));
291 fontSize = systemFontSize(metrics.lfSmCaptionFont);
295 cachedDesc = &menuFont;
296 if (!menuFont.isAbsoluteSize()) {
297 NONCLIENTMETRICS metrics;
298 getNonClientMetrics(&metrics);
299 faceName = AtomicString(metrics.lfMenuFont.lfFaceName, wcslen(metrics.lfMenuFont.lfFaceName));
300 fontSize = systemFontSize(metrics.lfMenuFont);
303 case CSSValueStatusBar:
304 cachedDesc = &labelFont;
305 if (!labelFont.isAbsoluteSize()) {
306 NONCLIENTMETRICS metrics;
307 getNonClientMetrics(&metrics);
308 faceName = metrics.lfStatusFont.lfFaceName;
309 fontSize = systemFontSize(metrics.lfStatusFont);
312 case CSSValueWebkitMiniControl:
313 case CSSValueWebkitSmallControl:
314 case CSSValueWebkitControl:
315 faceName = defaultGUIFont();
316 // Why 2 points smaller? Because that's what Gecko does.
317 fontSize = defaultFontSize - pointsToPixels(2);
320 faceName = defaultGUIFont();
321 fontSize = defaultFontSize;
326 cachedDesc = &fontDescription;
329 cachedDesc->firstFamily().setFamily(faceName);
330 cachedDesc->setIsAbsoluteSize(true);
331 cachedDesc->setGenericFamily(FontDescription::NoFamily);
332 cachedDesc->setSpecifiedSize(fontSize);
333 cachedDesc->setWeight(FontWeightNormal);
334 cachedDesc->setItalic(false);
336 fontDescription = *cachedDesc;
339 // Map a CSSValue* system color to an index understood by GetSysColor().
340 static int cssValueIdToSysColorIndex(int cssValueId)
342 switch (cssValueId) {
343 case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
344 case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
345 case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
346 case CSSValueBackground: return COLOR_BACKGROUND;
347 case CSSValueButtonface: return COLOR_BTNFACE;
348 case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
349 case CSSValueButtonshadow: return COLOR_BTNSHADOW;
350 case CSSValueButtontext: return COLOR_BTNTEXT;
351 case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
352 case CSSValueGraytext: return COLOR_GRAYTEXT;
353 case CSSValueHighlight: return COLOR_HIGHLIGHT;
354 case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
355 case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
356 case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
357 case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
358 case CSSValueInfobackground: return COLOR_INFOBK;
359 case CSSValueInfotext: return COLOR_INFOTEXT;
360 case CSSValueMenu: return COLOR_MENU;
361 case CSSValueMenutext: return COLOR_MENUTEXT;
362 case CSSValueScrollbar: return COLOR_SCROLLBAR;
363 case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
364 case CSSValueThreedface: return COLOR_3DFACE;
365 case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
366 case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
367 case CSSValueThreedshadow: return COLOR_3DSHADOW;
368 case CSSValueWindow: return COLOR_WINDOW;
369 case CSSValueWindowframe: return COLOR_WINDOWFRAME;
370 case CSSValueWindowtext: return COLOR_WINDOWTEXT;
371 default: return -1; // Unsupported CSSValue
375 Color RenderThemeChromiumWin::systemColor(int cssValueId) const
377 int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
378 if (ChromiumBridge::layoutTestMode() || (sysColorIndex == -1))
379 return RenderTheme::systemColor(cssValueId);
381 COLORREF color = GetSysColor(sysColorIndex);
382 return Color(GetRValue(color), GetGValue(color), GetBValue(color));
385 void RenderThemeChromiumWin::adjustSliderThumbSize(RenderObject* o) const
387 // These sizes match what WinXP draws for various menus.
388 const int sliderThumbAlongAxis = 11;
389 const int sliderThumbAcrossAxis = 21;
390 if (o->style()->appearance() == SliderThumbHorizontalPart) {
391 o->style()->setWidth(Length(sliderThumbAlongAxis, Fixed));
392 o->style()->setHeight(Length(sliderThumbAcrossAxis, Fixed));
393 } else if (o->style()->appearance() == SliderThumbVerticalPart) {
394 o->style()->setWidth(Length(sliderThumbAcrossAxis, Fixed));
395 o->style()->setHeight(Length(sliderThumbAlongAxis, Fixed));
397 RenderThemeChromiumSkia::adjustSliderThumbSize(o);
400 bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
402 return paintButton(o, i, r);
404 bool RenderThemeChromiumWin::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
406 return paintButton(o, i, r);
409 bool RenderThemeChromiumWin::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
411 const ThemeData& themeData = getThemeData(o);
413 ThemePainter painter(i.context, r);
414 ChromiumBridge::paintButton(painter.context(),
417 themeData.m_classicState,
422 bool RenderThemeChromiumWin::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
424 return paintTextFieldInternal(o, i, r, true);
427 bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
429 const ThemeData& themeData = getThemeData(o);
431 ThemePainter painter(i.context, r);
432 ChromiumBridge::paintTrackbar(painter.context(),
435 themeData.m_classicState,
440 bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
442 return paintSliderTrack(o, i, r);
445 static int menuListButtonWidth()
447 static int width = ChromiumBridge::layoutTestMode() ? kStandardMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL);
451 // Used to paint unstyled menulists (i.e. with the default border)
452 bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
457 const RenderBox* box = toRenderBox(o);
458 int borderRight = box->borderRight();
459 int borderLeft = box->borderLeft();
460 int borderTop = box->borderTop();
461 int borderBottom = box->borderBottom();
463 // If all the borders are 0, then tell skia not to paint the border on the
464 // textfield. FIXME: http://b/1210017 Figure out how to get Windows to not
465 // draw individual borders and then pass that to skia so we can avoid
466 // drawing any borders that are set to 0. For non-zero borders, we draw the
467 // border, but webkit just draws over it.
468 bool drawEdges = !(!borderRight && !borderLeft && !borderTop && !borderBottom);
470 paintTextFieldInternal(o, i, r, drawEdges);
472 // Take padding and border into account. If the MenuList is smaller than
473 // the size of a button, make sure to shrink it appropriately and not put
474 // its x position to the left of the menulist.
475 const int buttonWidth = menuListButtonWidth();
476 int spacingLeft = borderLeft + box->paddingLeft();
477 int spacingRight = borderRight + box->paddingRight();
478 int spacingTop = borderTop + box->paddingTop();
479 int spacingBottom = borderBottom + box->paddingBottom();
482 if (r.right() - r.x() < buttonWidth)
485 buttonX = o->style()->direction() == LTR ? r.right() - spacingRight - buttonWidth : r.x() + spacingLeft;
487 // Compute the rectangle of the button in the destination image.
488 IntRect rect(buttonX,
490 std::min(buttonWidth, r.right() - r.x()),
491 r.height() - (spacingTop + spacingBottom));
493 // Get the correct theme data for a textfield and paint the menu.
494 ThemePainter painter(i.context, rect);
495 ChromiumBridge::paintMenuList(painter.context(),
498 determineClassicState(o),
504 void RenderThemeChromiumWin::setDefaultFontSize(int fontSize)
506 RenderThemeChromiumSkia::setDefaultFontSize(fontSize);
508 // Reset cached fonts.
509 smallSystemFont = menuFont = labelFont = FontDescription();
512 double RenderThemeChromiumWin::caretBlinkIntervalInternal() const
514 // This involves a system call, so we cache the result.
515 static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval());
516 return blinkInterval;
519 unsigned RenderThemeChromiumWin::determineState(RenderObject* o, ControlSubPart subPart)
521 unsigned result = TS_NORMAL;
522 ControlPart appearance = o->style()->appearance();
524 result = TS_DISABLED;
525 else if (isReadOnlyControl(o))
526 result = (appearance == TextFieldPart || appearance == TextAreaPart || appearance == SearchFieldPart) ? ETS_READONLY : TS_DISABLED;
527 // Active overrides hover and focused.
528 else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
530 else if (supportsFocus(appearance) && isFocused(o))
531 result = ETS_FOCUSED;
532 else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
535 // CBS_UNCHECKED*: 1-4
538 if (isIndeterminate(o))
540 else if (isChecked(o))
545 unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o)
547 unsigned result = TUS_NORMAL;
548 if (!isEnabled(o->parent()))
549 result = TUS_DISABLED;
550 else if (supportsFocus(o->style()->appearance()) && isFocused(o->parent()))
551 result = TUS_FOCUSED;
552 else if (toRenderSlider(o->parent())->inDragMode())
553 result = TUS_PRESSED;
554 else if (isHovered(o))
559 unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o, ControlSubPart subPart)
563 ControlPart part = o->style()->appearance();
565 // Sliders are always in the normal state.
566 if (part == SliderHorizontalPart || part == SliderVerticalPart)
569 // So are readonly text fields.
570 if (isReadOnlyControl(o) && (part == TextFieldPart || part == TextAreaPart || part == SearchFieldPart))
573 if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
574 if (!isEnabled(o->parent()))
575 result = DFCS_INACTIVE;
576 else if (toRenderSlider(o->parent())->inDragMode()) // Active supersedes hover
577 result = DFCS_PUSHED;
578 else if (isHovered(o))
581 if (!isEnabled(o) || isReadOnlyControl(o))
582 result = DFCS_INACTIVE;
583 // Active supersedes hover
584 else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
585 result = DFCS_PUSHED;
586 else if (supportsFocus(part) && isFocused(o)) // So does focused
588 else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
590 // Classic theme can't represent indeterminate states. Use unchecked appearance.
591 if (isChecked(o) && !isIndeterminate(o))
592 result |= DFCS_CHECKED;
597 ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o, ControlSubPart subPart)
600 switch (o->style()->appearance()) {
602 result.m_part = BP_CHECKBOX;
603 result.m_state = determineState(o);
604 result.m_classicState = DFCS_BUTTONCHECK;
607 result.m_part = BP_RADIOBUTTON;
608 result.m_state = determineState(o);
609 result.m_classicState = DFCS_BUTTONRADIO;
613 result.m_part = BP_PUSHBUTTON;
614 result.m_state = determineState(o);
615 result.m_classicState = DFCS_BUTTONPUSH;
617 case SliderHorizontalPart:
618 result.m_part = TKP_TRACK;
619 result.m_state = TRS_NORMAL;
621 case SliderVerticalPart:
622 result.m_part = TKP_TRACKVERT;
623 result.m_state = TRVS_NORMAL;
625 case SliderThumbHorizontalPart:
626 result.m_part = TKP_THUMBBOTTOM;
627 result.m_state = determineSliderThumbState(o);
629 case SliderThumbVerticalPart:
630 result.m_part = TKP_THUMBVERT;
631 result.m_state = determineSliderThumbState(o);
635 case MenulistButtonPart:
636 case SearchFieldPart:
639 result.m_part = EP_EDITTEXT;
640 result.m_state = determineState(o);
642 case InnerSpinButtonPart:
643 result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
644 result.m_state = determineState(o, subPart);
645 result.m_classicState = subPart == SpinButtonUp ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
649 result.m_classicState |= determineClassicState(o, subPart);
654 bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
659 // Fallback to white if the specified color object is invalid.
660 // (Note ChromiumBridge::paintTextField duplicates this check).
661 Color backgroundColor(Color::white);
662 if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
663 backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);
665 // If we have background-image, don't fill the content area to expose the
666 // parent's background. Also, we shouldn't fill the content area if the
667 // alpha of the color is 0. The API of Windows GDI ignores the alpha.
669 // Note that we should paint the content area white if we have neither the
670 // background color nor background image explicitly specified to keep the
671 // appearance of select element consistent with other browsers.
672 bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha();
674 if (o->style()->hasBorderRadius()) {
675 // If the style has rounded borders, setup the context to clip the
676 // background (themed or filled) appropriately.
677 // FIXME: make sure we do the right thing if css background-clip is set.
679 i.context->addRoundedRectClip(o->style()->getRoundedBorderFor(r));
682 const ThemeData& themeData = getThemeData(o);
683 ThemePainter painter(i.context, r);
684 ChromiumBridge::paintTextField(painter.context(),
687 themeData.m_classicState,
692 // End of block commits the painter before restoring context.
694 if (o->style()->hasBorderRadius())
695 i.context->restore();
699 void RenderThemeChromiumWin::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
701 int width = ScrollbarTheme::nativeTheme()->scrollbarThickness();
702 style->setWidth(Length(width, Fixed));
703 style->setMinWidth(Length(width, Fixed));
706 bool RenderThemeChromiumWin::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
710 half.setHeight(rect.height() / 2);
711 const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
712 ThemePainter upPainter(info.context, half);
713 ChromiumBridge::paintSpinButton(upPainter.context(),
716 upThemeData.m_classicState,
717 upPainter.drawRect());
719 half.setY(rect.y() + rect.height() / 2);
720 const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
721 ThemePainter downPainter(info.context, half);
722 ChromiumBridge::paintSpinButton(downPainter.context(),
723 downThemeData.m_part,
724 downThemeData.m_state,
725 downThemeData.m_classicState,
726 downPainter.drawRect());
730 #if ENABLE(PROGRESS_TAG)
732 // MSDN says that update intervals for the bar is 30ms.
733 // http://msdn.microsoft.com/en-us/library/bb760842(v=VS.85).aspx
734 static const double progressAnimationFrameRate = 0.033;
736 double RenderThemeChromiumWin::animationRepeatIntervalForProgressBar(RenderProgress*) const
738 return progressAnimationFrameRate;
741 double RenderThemeChromiumWin::animationDurationForProgressBar(RenderProgress* renderProgress) const
743 // On Chromium Windows port, animationProgress() and associated values aren't used.
744 // So here we can return arbitrary positive value.
745 return progressAnimationFrameRate;
748 void RenderThemeChromiumWin::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const
752 bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& r)
754 if (!o->isProgress())
757 RenderProgress* renderProgress = toRenderProgress(o);
758 // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
759 // because the animation is a platform detail and WebKit doesn't need to know how.
760 IntRect valueRect = renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, r) : IntRect(0, 0, 0, 0);
761 double animatedSeconds = renderProgress->animationStartTime() ? WTF::currentTime() - renderProgress->animationStartTime() : 0;
762 ThemePainter painter(i.context, r);
763 ChromiumBridge::paintProgressBar(painter.context(), r, valueRect, renderProgress->isDeterminate(), animatedSeconds);
769 } // namespace WebCore