/* * This file is part of the WebKit project. * * Copyright (C) 2006, 2007 Apple Computer, Inc. * Copyright (C) 2007-2009 Torch Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "config.h" #include "RenderThemeWinCE.h" #include "CSSStyleSheet.h" #include "CSSValueKeywords.h" #include "Document.h" #include "GraphicsContext.h" #if ENABLE(VIDEO) #include "HTMLMediaElement.h" #endif #include "NotImplemented.h" #include "PaintInfo.h" #include /* * The following constants are used to determine how a widget is drawn using * Windows' Theme API. For more information on theme parts and states see * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp */ #define THEME_COLOR 204 #define THEME_FONT 210 // Generic state constants #define TS_NORMAL 1 #define TS_HOVER 2 #define TS_ACTIVE 3 #define TS_DISABLED 4 #define TS_FOCUSED 5 // Button constants #define BP_BUTTON 1 #define BP_RADIO 2 #define BP_CHECKBOX 3 // Textfield constants #define TFP_TEXTFIELD 1 #define TFS_READONLY 6 typedef HANDLE (WINAPI*openThemeDataPtr)(HWND hwnd, LPCWSTR pszClassList); typedef HRESULT (WINAPI*closeThemeDataPtr)(HANDLE hTheme); typedef HRESULT (WINAPI*drawThemeBackgroundPtr)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT* pClipRect); typedef HRESULT (WINAPI*drawThemeEdgePtr)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, unsigned uEdge, unsigned uFlags, const RECT* pClipRect); typedef HRESULT (WINAPI*getThemeContentRectPtr)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, RECT* pContentRect); typedef HRESULT (WINAPI*getThemePartSizePtr)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, RECT* prc, int ts, SIZE* psz); typedef HRESULT (WINAPI*getThemeSysFontPtr)(HANDLE hTheme, int iFontId, OUT LOGFONT* pFont); typedef HRESULT (WINAPI*getThemeColorPtr)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, OUT COLORREF* pFont); namespace WebCore { static const int dropDownButtonWidth = 17; static const int trackWidth = 4; PassRefPtr RenderThemeWinCE::create() { return adoptRef(new RenderThemeWinCE); } PassRefPtr RenderTheme::themeForPage(Page* page) { static RenderTheme* winceTheme = RenderThemeWinCE::create().releaseRef(); return winceTheme; } RenderThemeWinCE::RenderThemeWinCE() { } RenderThemeWinCE::~RenderThemeWinCE() { } Color RenderThemeWinCE::platformActiveSelectionBackgroundColor() const { COLORREF color = GetSysColor(COLOR_HIGHLIGHT); return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); } Color RenderThemeWinCE::platformInactiveSelectionBackgroundColor() const { COLORREF color = GetSysColor(COLOR_GRAYTEXT); return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); } Color RenderThemeWinCE::platformActiveSelectionForegroundColor() const { COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT); return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255); } Color RenderThemeWinCE::platformInactiveSelectionForegroundColor() const { return Color::white; } bool RenderThemeWinCE::supportsFocus(ControlPart appearance) const { switch (appearance) { case PushButtonPart: case ButtonPart: case TextFieldPart: case TextAreaPart: return true; default: return false; } return false; } bool RenderThemeWinCE::supportsFocusRing(const RenderStyle *style) const { return supportsFocus(style->appearance()); } unsigned RenderThemeWinCE::determineClassicState(RenderObject* o) { unsigned result = 0; if (!isEnabled(o) || isReadOnlyControl(o)) result = DFCS_INACTIVE; else if (isPressed(o)) // Active supersedes hover result = DFCS_PUSHED; if (isChecked(o)) result |= DFCS_CHECKED; return result; } ThemeData RenderThemeWinCE::getThemeData(RenderObject* o) { ThemeData result; switch (o->style()->appearance()) { case PushButtonPart: case ButtonPart: result.m_part = BP_BUTTON; result.m_classicState = DFCS_BUTTONPUSH; break; case CheckboxPart: result.m_part = BP_CHECKBOX; result.m_classicState = DFCS_BUTTONCHECK; break; case RadioPart: result.m_part = BP_RADIO; result.m_classicState = DFCS_BUTTONRADIO; break; case ListboxPart: case MenulistPart: case TextFieldPart: case TextAreaPart: result.m_part = TFP_TEXTFIELD; break; } result.m_classicState |= determineClassicState(o); return result; } bool RenderThemeWinCE::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { // Get the correct theme data for a button ThemeData themeData = getThemeData(o); // Now paint the button. i.context->drawFrameControl(r, DFC_BUTTON, themeData.m_classicState); if (isFocused(o)) { if (themeData.m_part == BP_BUTTON) { IntRect focusRect(r); focusRect.inflate(-2); i.context->drawFocusRect(focusRect); } else i.context->drawFocusRect(r); } return false; } void RenderThemeWinCE::setCheckboxSize(RenderStyle* style) const { // If the width and height are both specified, then we have nothing to do. if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) return; // FIXME: A hard-coded size of 13 is used. This is wrong but necessary for now. It matches Firefox. // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for // the higher DPI. Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's // metrics. if (style->width().isIntrinsicOrAuto()) style->setWidth(Length(13, Fixed)); if (style->height().isAuto()) style->setHeight(Length(13, Fixed)); } bool RenderThemeWinCE::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r) { // Get the correct theme data for a textfield ThemeData themeData = getThemeData(o); // Now paint the text field. i.context->paintTextField(r, themeData.m_classicState); return false; } void RenderThemeWinCE::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { style->resetBorder(); adjustMenuListButtonStyle(selector, style, e); } bool RenderThemeWinCE::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r) { paintTextField(o, i, r); paintMenuListButton(o, i, r); return true; } bool RenderThemeWinCE::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r) { IntRect buttonRect(r.maxX() - dropDownButtonWidth - 1, r.y(), dropDownButtonWidth, r.height()); buttonRect.inflateY(-1); i.context->drawFrameControl(buttonRect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | determineClassicState(o)); return true; } void RenderThemeWinCE::systemFont(int propId, FontDescription& fontDescription) const { notImplemented(); } void RenderThemeWinCE::themeChanged() { } String RenderThemeWinCE::extraDefaultStyleSheet() { notImplemented(); return String(); } String RenderThemeWinCE::extraQuirksStyleSheet() { notImplemented(); return String(); } bool RenderThemeWinCE::supportsHover(const RenderStyle*) const { return false; } // Map a CSSValue* system color to an index understood by GetSysColor static int cssValueIdToSysColorIndex(int cssValueId) { switch (cssValueId) { case CSSValueActiveborder: return COLOR_ACTIVEBORDER; case CSSValueActivecaption: return COLOR_ACTIVECAPTION; case CSSValueAppworkspace: return COLOR_APPWORKSPACE; case CSSValueBackground: return COLOR_BACKGROUND; case CSSValueButtonface: return COLOR_BTNFACE; case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT; case CSSValueButtonshadow: return COLOR_BTNSHADOW; case CSSValueButtontext: return COLOR_BTNTEXT; case CSSValueCaptiontext: return COLOR_CAPTIONTEXT; case CSSValueGraytext: return COLOR_GRAYTEXT; case CSSValueHighlight: return COLOR_HIGHLIGHT; case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT; case CSSValueInactiveborder: return COLOR_INACTIVEBORDER; case CSSValueInactivecaption: return COLOR_INACTIVECAPTION; case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT; case CSSValueInfobackground: return COLOR_INFOBK; case CSSValueInfotext: return COLOR_INFOTEXT; case CSSValueMenu: return COLOR_MENU; case CSSValueMenutext: return COLOR_MENUTEXT; case CSSValueScrollbar: return COLOR_SCROLLBAR; case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW; case CSSValueThreedface: return COLOR_3DFACE; case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT; case CSSValueThreedlightshadow: return COLOR_3DLIGHT; case CSSValueThreedshadow: return COLOR_3DSHADOW; case CSSValueWindow: return COLOR_WINDOW; case CSSValueWindowframe: return COLOR_WINDOWFRAME; case CSSValueWindowtext: return COLOR_WINDOWTEXT; default: return -1; // Unsupported CSSValue } } Color RenderThemeWinCE::systemColor(int cssValueId) const { int sysColorIndex = cssValueIdToSysColorIndex(cssValueId); if (sysColorIndex == -1) return RenderTheme::systemColor(cssValueId); COLORREF color = GetSysColor(sysColorIndex); return Color(GetRValue(color), GetGValue(color), GetBValue(color)); } const int sliderThumbWidth = 7; const int sliderThumbHeight = 15; void RenderThemeWinCE::adjustSliderThumbSize(RenderObject* o) const { if (o->style()->appearance() == SliderThumbVerticalPart) { o->style()->setWidth(Length(sliderThumbHeight, Fixed)); o->style()->setHeight(Length(sliderThumbWidth, Fixed)); } else if (o->style()->appearance() == SliderThumbHorizontalPart) { o->style()->setWidth(Length(sliderThumbWidth, Fixed)); o->style()->setHeight(Length(sliderThumbHeight, Fixed)); } } #if 0 void RenderThemeWinCE::adjustButtonInnerStyle(RenderStyle* style) const { // This inner padding matches Firefox. style->setPaddingTop(Length(1, Fixed)); style->setPaddingRight(Length(3, Fixed)); style->setPaddingBottom(Length(1, Fixed)); style->setPaddingLeft(Length(3, Fixed)); } void RenderThemeWinCE::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { // Override padding size to match AppKit text positioning. const int padding = 1; style->setPaddingLeft(Length(padding, Fixed)); style->setPaddingRight(Length(padding, Fixed)); style->setPaddingTop(Length(padding, Fixed)); style->setPaddingBottom(Length(padding, Fixed)); } #endif bool RenderThemeWinCE::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); } bool RenderThemeWinCE::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { Color buttonColor = (o->node() && o->node()->active()) ? Color(138, 138, 138) : Color(186, 186, 186); IntSize cancelSize(10, 10); IntSize cancelRadius(cancelSize.width() / 2, cancelSize.height() / 2); int x = r.x() + (r.width() - cancelSize.width()) / 2; int y = r.y() + (r.height() - cancelSize.height()) / 2 + 1; IntRect cancelBounds(IntPoint(x, y), cancelSize); paintInfo.context->save(); paintInfo.context->addRoundedRectClip(RoundedIntRect(cancelBounds, cancelRadius, cancelRadius, cancelRadius, cancelRadius)); paintInfo.context->fillRect(cancelBounds, buttonColor, ColorSpaceDeviceRGB); // Draw the 'x' IntSize xSize(3, 3); IntRect xBounds(cancelBounds.location() + IntSize(3, 3), xSize); paintInfo.context->setStrokeColor(Color::white, ColorSpaceDeviceRGB); paintInfo.context->drawLine(xBounds.location(), xBounds.location() + xBounds.size()); paintInfo.context->drawLine(IntPoint(xBounds.maxX(), xBounds.y()), IntPoint(xBounds.x(), xBounds.maxY())); paintInfo.context->restore(); return false; } void RenderThemeWinCE::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { IntSize cancelSize(13, 11); style->setWidth(Length(cancelSize.width(), Fixed)); style->setHeight(Length(cancelSize.height(), Fixed)); } void RenderThemeWinCE::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { IntSize emptySize(1, 11); style->setWidth(Length(emptySize.width(), Fixed)); style->setHeight(Length(emptySize.height(), Fixed)); } void RenderThemeWinCE::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { IntSize magnifierSize(15, 11); style->setWidth(Length(magnifierSize.width(), Fixed)); style->setHeight(Length(magnifierSize.height(), Fixed)); } bool RenderThemeWinCE::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { notImplemented(); return false; } void RenderThemeWinCE::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { IntSize magnifierSize(15, 11); style->setWidth(Length(magnifierSize.width(), Fixed)); style->setHeight(Length(magnifierSize.height(), Fixed)); } bool RenderThemeWinCE::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { paintSearchFieldResultsDecoration(o, paintInfo, r); return false; } void RenderThemeWinCE::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { // These are the paddings needed to place the text correctly in the box must be at least 12px high for the button to render nicely on Windows const int dropDownBoxMinHeight = 12; // Position the text correctly within the select box and make the box wide enough to fit the dropdown button style->setPaddingTop(Length(dropDownBoxPaddingTop, Fixed)); style->setPaddingRight(Length(dropDownBoxPaddingRight, Fixed)); style->setPaddingBottom(Length(dropDownBoxPaddingBottom, Fixed)); style->setPaddingLeft(Length(dropDownBoxPaddingLeft, Fixed)); // Height is locked to auto style->setHeight(Length(Auto)); // Calculate our min-height int minHeight = style->fontMetrics().height(); minHeight = max(minHeight, dropDownBoxMinHeight); style->setMinHeight(Length(minHeight, Fixed)); // White-space is locked to pre style->setWhiteSpace(PRE); DWORD colorMenu = GetSysColor(COLOR_MENU); DWORD colorMenuText = GetSysColor(COLOR_MENUTEXT); Color bgColor(GetRValue(colorMenu), GetGValue(colorMenu), GetBValue(colorMenu), 255); Color textColor(GetRValue(colorMenuText), GetGValue(colorMenuText), GetBValue(colorMenuText), 255); if (bgColor == textColor) textColor.setRGB((~bgColor.rgb()) | 0xFF000000); style->clearBackgroundLayers(); style->accessBackgroundLayers()->setClip(ContentFillBox); style->setBackgroundColor(bgColor); style->setColor(textColor); } #if ENABLE(VIDEO) // Attempt to retrieve a HTMLMediaElement from a Node. Returns 0 if one cannot be found. static HTMLMediaElement* mediaElementParent(Node* node) { if (!node) return 0; Node* mediaNode = node->shadowAncestorNode(); if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag))) return 0; return static_cast(mediaNode); } #endif bool RenderThemeWinCE::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r) { bool rc = RenderTheme::paintSliderTrack(o, i, r); IntPoint left = IntPoint(r.x() + 2, (r.y() + r.maxY()) / 2); i.context->save(); i.context->setStrokeColor(Color::gray, ColorSpaceDeviceRGB); i.context->setFillColor(Color::gray, ColorSpaceDeviceRGB); i.context->fillRect(r); #if ENABLE(VIDEO) HTMLMediaElement* mediaElement = mediaElementParent(o->node()); if (mediaElement) { i.context->setStrokeColor(Color(0, 0xff, 0)); IntPoint right = IntPoint(left.x() + mediaElement->percentLoaded() * (r.maxX() - r.x() - 4), (r.y() + r.maxY()) / 2); i.context->drawLine(left, right); left = right; } #endif i.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB); i.context->drawLine(left, IntPoint(r.maxX() - 2, left.y())); i.context->restore(); return rc; } bool RenderThemeWinCE::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r) { bool rc = RenderTheme::paintSliderThumb(o, i, r); i.context->save(); i.context->setStrokeColor(Color::black, ColorSpaceDeviceRGB); i.context->setFillColor(Color::black, ColorSpaceDeviceRGB); #if ENABLE(VIDEO) HTMLMediaElement* mediaElement = mediaElementParent(o->node()); if (mediaElement) { float pt = (mediaElement->currentTime() - mediaElement->startTime()) / mediaElement->duration(); FloatRect intRect = r; intRect.setX(intRect.x() + intRect.width() * pt - 2); intRect.setWidth(5); i.context->fillRect(intRect); } #endif i.context->restore(); return rc; } void RenderThemeWinCE::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { const int padding = 1; style->setPaddingLeft(Length(padding, Fixed)); style->setPaddingRight(Length(padding, Fixed)); style->setPaddingTop(Length(padding, Fixed)); style->setPaddingBottom(Length(padding, Fixed)); } #if ENABLE(VIDEO) bool RenderThemeWinCE::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { bool rc = paintButton(o, paintInfo, r); FloatRect imRect = r; imRect.inflate(-2); paintInfo.context->save(); paintInfo.context->setStrokeColor(Color::black); paintInfo.context->setFillColor(Color::gray); paintInfo.context->fillRect(imRect); paintInfo.context->restore(); return rc; } bool RenderThemeWinCE::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { bool rc = paintButton(o, paintInfo, r); HTMLMediaElement* mediaElement = mediaElementParent(o->node()); bool muted = !mediaElement || mediaElement->muted(); FloatRect imRect = r; imRect.inflate(-2); paintInfo.context->save(); paintInfo.context->setStrokeColor(Color::black); paintInfo.context->setFillColor(Color::black); FloatPoint pts[6] = { FloatPoint(imRect.x() + 1, imRect.y() + imRect.height() / 3.0), FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + imRect.height() / 3.0), FloatPoint(imRect.maxX() - 1, imRect.y()), FloatPoint(imRect.maxX() - 1, imRect.maxY()), FloatPoint(imRect.x() + 1 + imRect.width() / 2.0, imRect.y() + 2.0 * imRect.height() / 3.0), FloatPoint(imRect.x() + 1, imRect.y() + 2.0 * imRect.height() / 3.0) }; paintInfo.context->drawConvexPolygon(6, pts); if (muted) paintInfo.context->drawLine(IntPoint(imRect.maxX(), imRect.y()), IntPoint(imRect.x(), imRect.maxY())); paintInfo.context->restore(); return rc; } bool RenderThemeWinCE::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { bool rc = paintButton(o, paintInfo, r); FloatRect imRect = r; imRect.inflate(-3); paintInfo.context->save(); paintInfo.context->setStrokeColor(Color::black); paintInfo.context->setFillColor(Color::black); HTMLMediaElement* mediaElement = mediaElementParent(o->node()); bool paused = !mediaElement || mediaElement->paused(); if (paused) { float width = imRect.width(); imRect.setWidth(width / 3.0); paintInfo.context->fillRect(imRect); imRect.move(2.0 * width / 3.0, 0); paintInfo.context->fillRect(imRect); } else { FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) }; paintInfo.context->drawConvexPolygon(3, pts); } paintInfo.context->restore(); return rc; } bool RenderThemeWinCE::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { bool rc = paintButton(o, paintInfo, r); FloatRect imRect = r; imRect.inflate(-3); FloatPoint pts[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.x(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) }; FloatPoint pts2[3] = { FloatPoint(imRect.maxX(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.maxX(), imRect.maxY()) }; paintInfo.context->save(); paintInfo.context->setStrokeColor(Color::black); paintInfo.context->setFillColor(Color::black); paintInfo.context->drawConvexPolygon(3, pts); paintInfo.context->drawConvexPolygon(3, pts2); paintInfo.context->restore(); return rc; } bool RenderThemeWinCE::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { bool rc = paintButton(o, paintInfo, r); FloatRect imRect = r; imRect.inflate(-3); FloatPoint pts[3] = { FloatPoint(imRect.x(), imRect.y()), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, (imRect.y() + imRect.maxY()) / 2.0), FloatPoint(imRect.x(), imRect.maxY()) }; FloatPoint pts2[3] = { FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.y()), FloatPoint(imRect.maxX(), (imRect.y() + imRect.maxY()) / 2.0), FloatPoint((imRect.x() + imRect.maxX()) / 2.0, imRect.maxY()) }; paintInfo.context->save(); paintInfo.context->setStrokeColor(Color::black); paintInfo.context->setFillColor(Color::black); paintInfo.context->drawConvexPolygon(3, pts); paintInfo.context->drawConvexPolygon(3, pts2); paintInfo.context->restore(); return rc; } bool RenderThemeWinCE::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return paintSliderTrack(o, paintInfo, r); } bool RenderThemeWinCE::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) { return paintSliderThumb(o, paintInfo, r); } #endif } // namespace WebCore