summaryrefslogtreecommitdiffstats
path: root/webkit/port/rendering
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:20:51 +0000
commitf5b16fed647e941aa66933178da85db2860d639b (patch)
treef00e9856c04aad3b558a140955e7674add33f051 /webkit/port/rendering
parent920c091ac3ee15079194c82ae8a7a18215f3f23c (diff)
downloadchromium_src-f5b16fed647e941aa66933178da85db2860d639b.zip
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.gz
chromium_src-f5b16fed647e941aa66933178da85db2860d639b.tar.bz2
Add webkit to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/rendering')
-rw-r--r--webkit/port/rendering/RenderThemeWin.cpp864
-rw-r--r--webkit/port/rendering/RenderThemeWin.h133
2 files changed, 997 insertions, 0 deletions
diff --git a/webkit/port/rendering/RenderThemeWin.cpp b/webkit/port/rendering/RenderThemeWin.cpp
new file mode 100644
index 0000000..d0509e1
--- /dev/null
+++ b/webkit/port/rendering/RenderThemeWin.cpp
@@ -0,0 +1,864 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2006 Apple Computer, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+#include "RenderThemeWin.h"
+
+#include <windows.h>
+#include <uxtheme.h>
+#include <vssym32.h>
+
+#include "CSSValueKeywords.h"
+#include "Document.h"
+#include "FontSelector.h"
+#include "GraphicsContext.h"
+#include "PlatformScrollBar.h"
+#include "SkiaUtils.h"
+
+#include "base/gfx/native_theme.h"
+#include "base/gfx/font_utils.h"
+#include "base/win_util.h"
+#include "webkit/glue/webkit_glue.h"
+
+// These enums correspond to similarly named values defined by SafariTheme.h
+enum ControlSize {
+ RegularControlSize,
+ SmallControlSize,
+ MiniControlSize
+};
+
+enum PaddingType {
+ TopPadding,
+ RightPadding,
+ BottomPadding,
+ LeftPadding
+};
+
+namespace {
+ const int kDefaultButtonPadding = 2;
+
+ // These magic numbers come from Apple's version of RenderThemeWin.cpp.
+ const int kMenuListPadding[4] = { 1, 2, 1, 2 };
+
+ // The kLayoutTest* constants are metrics used only in layout test mode,
+ // so as to match RenderThemeMac.mm and to remain consistent despite any
+ // theme or font changes.
+ const int kLayoutTestControlHeight[3] = { 21, 18, 15 };
+ const int kLayoutTestButtonPadding[4] = { 0, 8, 0, 8 };
+ const int kLayoutTestStyledMenuListInternalPadding[4] = { 1, 0, 2, 8 };
+ const int kLayoutTestMenuListInternalPadding[3][4] =
+ {
+ { 2, 26, 3, 8 },
+ { 2, 23, 3, 8 },
+ { 2, 22, 3, 10 }
+ };
+ const int kLayoutTestMenuListMinimumWidth[3] = { 9, 5, 0 };
+ const float kLayoutTestBaseFontSize = 11.0f;
+ const float kLayoutTestStatusBarFontSize = 10.0f;
+ const float kLayoutTestSystemFontSize = 13.0f;
+
+ const int kLayoutTestSliderThumbWidth = 15;
+ const int kLayoutTestSliderThumbHeight = 15;
+
+ const int kLayoutTestMenuListButtonWidth = 15;
+ const int kLayoutTestButtonMinHeight = 15;
+
+ const int kLayoutTestSearchFieldHeight[3] = { 22, 19, 17 };
+ const int kLayoutTestEmptyResultsOffset = 9;
+ const int kLayoutTestResultsArrowWidth = 5;
+
+ const short kLayoutTestSearchFieldBorderWidth = 2;
+ const int kLayoutTestSearchFieldPadding = 1;
+
+
+
+ // Constants that are used in non-layout-test mode.
+ const int kStyledMenuListInternalPadding[4] = { 1, 4, 1, 4 };
+
+ // The default variable-width font size. We use this as the default font
+ // size for the "system font", and as a base size (which we then shrink) for
+ // form control fonts.
+ float DefaultFontSize = 16.0;
+
+ WebCore::FontDescription SmallSystemFont;
+ WebCore::FontDescription MenuFont;
+ WebCore::FontDescription LabelFont;
+}
+
+namespace WebCore {
+
+static void setFixedPadding(RenderStyle* style, const int padding[4])
+{
+ style->setPaddingLeft(Length(padding[LeftPadding], Fixed));
+ style->setPaddingRight(Length(padding[RightPadding], Fixed));
+ style->setPaddingTop(Length(padding[TopPadding], Fixed));
+ style->setPaddingBottom(Length(padding[BottomPadding], Fixed));
+}
+
+// This is logic from RenderThemeMac.mm, and is used by layout test mode.
+static ControlSize controlSizeForFont(RenderStyle* style)
+{
+ if (style->fontSize() >= 16) {
+ return RegularControlSize;
+ } else if (style->fontSize() >= 11) {
+ return SmallControlSize;
+ }
+ return MiniControlSize;
+}
+
+RenderTheme* theme()
+{
+ static RenderThemeWin winTheme;
+ return &winTheme;
+}
+
+RenderThemeWin::RenderThemeWin()
+{
+}
+
+RenderThemeWin::~RenderThemeWin()
+{
+}
+
+Color RenderThemeWin::platformActiveSelectionBackgroundColor() const
+{
+ if (webkit_glue::IsLayoutTestMode())
+ return Color("#0000FF"); // Royal blue
+ COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
+ return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
+}
+
+Color RenderThemeWin::platformInactiveSelectionBackgroundColor() const
+{
+ if (webkit_glue::IsLayoutTestMode())
+ return Color("#999999"); // Medium grey
+ COLORREF color = GetSysColor(COLOR_GRAYTEXT);
+ return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
+}
+
+Color RenderThemeWin::platformActiveSelectionForegroundColor() const
+{
+ if (webkit_glue::IsLayoutTestMode())
+ return Color("#FFFFCC"); // Pale yellow
+ COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ return Color(GetRValue(color), GetGValue(color), GetBValue(color), 255);
+}
+
+Color RenderThemeWin::platformInactiveSelectionForegroundColor() const
+{
+ return Color::white;
+}
+
+static float systemFontSizeForControlSize(ControlSize controlSize)
+{
+ static float sizes[] = { 13.0f, 11.0f, 9.0f };
+
+ return sizes[controlSize];
+}
+
+// This is basically RenderThemeMac::setFontFromControlSize
+static int layoutTestSetFontFromControlSize(CSSStyleSelector* selector, RenderStyle* style)
+{
+ FontDescription fontDescription;
+ fontDescription.setIsAbsoluteSize(true);
+ fontDescription.setGenericFamily(FontDescription::SerifFamily);
+
+ float fontSize = systemFontSizeForControlSize(controlSizeForFont(style));
+ fontDescription.firstFamily().setFamily("Lucida Grande");
+
+ fontDescription.setComputedSize(fontSize);
+ fontDescription.setSpecifiedSize(fontSize);
+
+ // Reset line height
+ style->setLineHeight(RenderStyle::initialLineHeight());
+
+ style->setFontDescription(fontDescription);
+ style->font().update(0);
+
+ return 0;
+}
+
+// Return the height of system font |font| in pixels. We use this size by
+// default for some non-form-control elements.
+static float systemFontSize(const LOGFONT& font)
+{
+ float size = -font.lfHeight;
+ if (size < 0) {
+ HFONT hFont = CreateFontIndirect(&font);
+ if (hFont) {
+ HDC hdc = GetDC(0); // What about printing? Is this the right DC?
+ if (hdc) {
+ HGDIOBJ hObject = SelectObject(hdc, hFont);
+ TEXTMETRIC tm;
+ GetTextMetrics(hdc, &tm);
+ SelectObject(hdc, hObject);
+ ReleaseDC(0, hdc);
+ size = tm.tmAscent;
+ }
+ DeleteObject(hFont);
+ }
+ }
+
+ // The "codepage 936" bit here is from Gecko; apparently this helps make
+ // fonts more legible in Simplified Chinese where the default font size is
+ // too small.
+ // TODO(pkasting): http://b/1119883 Since this is only used for "small
+ // caption", "menu", and "status bar" objects, I'm not sure how much this
+ // even matters. Plus the Gecko patch went in back in 2002, and maybe this
+ // isn't even relevant anymore. We should investigate whether this should
+ // be removed, or perhaps broadened to be "any CJK locale".
+ return ((size < 12.0f) && (GetACP() == 936)) ? 12.0f : size;
+}
+
+// We aim to match IE here.
+// -IE uses a font based on the encoding as the default font for form controls.
+// -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT),
+// which returns MS Shell Dlg)
+// -Safari uses Lucida Grande.
+//
+// TODO(ojan): Fix this!
+// The only case where we know we don't match IE is for ANSI encodings. IE uses
+// MS Shell Dlg there, which we render incorrectly at certain pixel sizes
+// (e.g. 15px). So, for now we just use Arial.
+static wchar_t* defaultGUIFont(Document* document)
+{
+ UScriptCode dominantScript = document->dominantScript();
+ const wchar_t* family = NULL;
+
+ if (dominantScript != USCRIPT_INVALID_CODE) {
+ family = gfx::GetFontFamilyForScript(dominantScript,
+ gfx::GenericFamilyType::GENERIC_FAMILY_NONE);
+ if (family)
+ return const_cast<wchar_t*>(family);
+ }
+ return L"Arial";
+}
+
+// Converts |points| to pixels. One point is 1/72 of an inch.
+static float pointsToPixels(float points)
+{
+ static float pixelsPerInch = 0.0f;
+ if (!pixelsPerInch) {
+ HDC hdc = GetDC(0); // What about printing? Is this the right DC?
+ if (hdc) { // Can this ever actually be NULL?
+ pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(0, hdc);
+ } else {
+ pixelsPerInch = 96.0f;
+ }
+ }
+
+ static const float POINTS_PER_INCH = 72.0f;
+ return points / POINTS_PER_INCH * pixelsPerInch;
+}
+
+double RenderThemeWin::caretBlinkFrequency() const
+{
+ // Disable the blinking caret in layout test mode, as it introduces
+ // a race condition for the pixel tests. http://b/1198440
+ if (webkit_glue::IsLayoutTestMode())
+ return 0;
+
+ // TODO(ericroman): this should be using the platform's blink frequency.
+ return RenderTheme::caretBlinkFrequency();
+}
+
+void RenderThemeWin::systemFont(int propId, Document* document, FontDescription& fontDescription) const
+{
+ // This logic owes much to RenderThemeSafari.cpp.
+ FontDescription* cachedDesc = NULL;
+ wchar_t* faceName = 0;
+ float fontSize = 0;
+ switch (propId) {
+ case CSS_VAL_SMALL_CAPTION:
+ cachedDesc = &SmallSystemFont;
+ if (!SmallSystemFont.isAbsoluteSize()) {
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = systemFontSizeForControlSize(SmallControlSize);
+ } else {
+ NONCLIENTMETRICS metrics;
+ win_util::GetNonClientMetrics(&metrics);
+ faceName = metrics.lfSmCaptionFont.lfFaceName;
+ fontSize = systemFontSize(metrics.lfSmCaptionFont);
+ }
+ }
+ break;
+ case CSS_VAL_MENU:
+ cachedDesc = &MenuFont;
+ if (!MenuFont.isAbsoluteSize()) {
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = systemFontSizeForControlSize(RegularControlSize);
+ } else {
+ NONCLIENTMETRICS metrics;
+ win_util::GetNonClientMetrics(&metrics);
+ faceName = metrics.lfMenuFont.lfFaceName;
+ fontSize = systemFontSize(metrics.lfMenuFont);
+ }
+ }
+ break;
+ case CSS_VAL_STATUS_BAR:
+ cachedDesc = &LabelFont;
+ if (!LabelFont.isAbsoluteSize()) {
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = kLayoutTestStatusBarFontSize;
+ } else {
+ NONCLIENTMETRICS metrics;
+ win_util::GetNonClientMetrics(&metrics);
+ faceName = metrics.lfStatusFont.lfFaceName;
+ fontSize = systemFontSize(metrics.lfStatusFont);
+ }
+ }
+ break;
+ case CSS_VAL__WEBKIT_MINI_CONTROL:
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = systemFontSizeForControlSize(MiniControlSize);
+ } else {
+ faceName = defaultGUIFont(document);
+ // Why 2 points smaller? Because that's what Gecko does.
+ // Also see 2 places below.
+ fontSize = DefaultFontSize - pointsToPixels(2);
+ }
+ break;
+ case CSS_VAL__WEBKIT_SMALL_CONTROL:
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = systemFontSizeForControlSize(SmallControlSize);
+ } else {
+ faceName = defaultGUIFont(document);
+ fontSize = DefaultFontSize - pointsToPixels(2);
+ }
+ break;
+ case CSS_VAL__WEBKIT_CONTROL:
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = systemFontSizeForControlSize(RegularControlSize);
+ } else {
+ faceName = defaultGUIFont(document);
+ fontSize = DefaultFontSize - pointsToPixels(2);
+ }
+ break;
+ default:
+ if (webkit_glue::IsLayoutTestMode()) {
+ fontSize = kLayoutTestSystemFontSize;
+ } else {
+ faceName = defaultGUIFont(document);
+ fontSize = DefaultFontSize;
+ }
+ }
+
+ if (!cachedDesc)
+ cachedDesc = &fontDescription;
+
+ if (fontSize) {
+ if (webkit_glue::IsLayoutTestMode()) {
+ cachedDesc->firstFamily().setFamily("Lucida Grande");
+ } else {
+ ASSERT(faceName);
+ cachedDesc->firstFamily().setFamily(AtomicString(faceName,
+ wcslen(faceName)));
+ }
+ cachedDesc->setIsAbsoluteSize(true);
+ cachedDesc->setGenericFamily(FontDescription::NoFamily);
+ cachedDesc->setSpecifiedSize(fontSize);
+ cachedDesc->setBold(false);
+ cachedDesc->setItalic(false);
+ }
+ fontDescription = *cachedDesc;
+}
+
+bool RenderThemeWin::supportsFocus(EAppearance appearance)
+{
+ switch (appearance) {
+ case PushButtonAppearance:
+ case ButtonAppearance:
+ case TextFieldAppearance:
+ case TextAreaAppearance:
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+bool RenderThemeWin::supportsFocusRing(const RenderStyle* style) const
+{
+ // Let webkit draw one of its halo rings around any focused element,
+ // except push buttons. For buttons we use the windows PBS_DEFAULTED
+ // styling to give it a blue border.
+ return style->appearance() == ButtonAppearance ||
+ style->appearance() == PushButtonAppearance;
+}
+
+unsigned RenderThemeWin::determineState(RenderObject* o)
+{
+ unsigned result = TS_NORMAL;
+ if (!isEnabled(o))
+ result = TS_DISABLED;
+ else if (isReadOnlyControl(o))
+ result = ETS_READONLY; // Readonly is supported on textfields.
+ else if (supportsFocus(o->style()->appearance()) && isFocused(o))
+ result = TS_CHECKED;
+ else if (isPressed(o)) // Active overrides hover.
+ result = TS_PRESSED;
+ else if (isHovered(o))
+ result = TS_HOT;
+ if (isChecked(o))
+ result += 4; // 4 unchecked states, 4 checked states.
+ return result;
+}
+
+unsigned RenderThemeWin::determineClassicState(RenderObject* o)
+{
+ unsigned result = 0;
+ if (!isEnabled(o) || isReadOnlyControl(o))
+ result = DFCS_INACTIVE;
+ else if (isPressed(o)) // Active supersedes hover
+ result = DFCS_PUSHED;
+ else if (isHovered(o))
+ result = DFCS_HOT;
+ if (isChecked(o))
+ result |= DFCS_CHECKED;
+ return result;
+}
+
+ThemeData RenderThemeWin::getThemeData(RenderObject* o)
+{
+ ThemeData result;
+ switch (o->style()->appearance()) {
+ case PushButtonAppearance:
+ case ButtonAppearance:
+ result.m_part = BP_PUSHBUTTON;
+ result.m_classicState = DFCS_BUTTONPUSH;
+ break;
+ case CheckboxAppearance:
+ result.m_part = BP_CHECKBOX;
+ result.m_classicState = DFCS_BUTTONCHECK;
+ break;
+ case RadioAppearance:
+ result.m_part = BP_RADIOBUTTON;
+ result.m_classicState = DFCS_BUTTONRADIO;
+ break;
+ case ListboxAppearance:
+ case MenulistAppearance:
+ case TextFieldAppearance:
+ case TextAreaAppearance:
+ result.m_part = ETS_NORMAL;
+ break;
+ }
+
+ result.m_state = determineState(o);
+ result.m_classicState |= determineClassicState(o);
+
+ return result;
+}
+
+bool RenderThemeWin::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ // Get the correct theme data for a button and paint the button.
+ PlatformContextSkia* skia = PlatformContextToPlatformContextSkia(i.context->platformContext());
+ SkIRect rect;
+ WebCoreRectToSkiaRect(r, &rect);
+ skia->paintButton(rect, getThemeData(o));
+ return false;
+}
+
+static void setSizeIfAuto(RenderStyle* style, const IntSize& size)
+{
+ if (style->width().isIntrinsicOrAuto())
+ style->setWidth(Length(size.width(), Fixed));
+ if (style->height().isAuto())
+ style->setHeight(Length(size.height(), Fixed));
+}
+
+int RenderThemeWin::minimumMenuListSize(RenderStyle* style) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ return kLayoutTestMenuListMinimumWidth[controlSizeForFont(style)];
+ } else {
+ return 0;
+ }
+}
+
+static IntSize layoutTestCheckboxSize(RenderStyle* style)
+{
+ static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) };
+ return sizes[controlSizeForFont(style)];
+}
+
+static IntSize layoutTestRadioboxSize(RenderStyle* style)
+{
+ static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) };
+ return sizes[controlSizeForFont(style)];
+}
+
+void RenderThemeWin::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.
+ const IntSize size = webkit_glue::IsLayoutTestMode() ?
+ layoutTestCheckboxSize(style) : IntSize(13, 13);
+ setSizeIfAuto(style, size);
+}
+
+void RenderThemeWin::setRadioSize(RenderStyle* style) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ setSizeIfAuto(style, layoutTestRadioboxSize(style));
+ } else {
+ // Use same sizing for radio box as checkbox.
+ setCheckboxSize(style);
+ }
+}
+
+bool RenderThemeWin::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintTextFieldInternal(o, i, r, true);
+}
+
+bool RenderThemeWin::paintTextFieldInternal(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r, bool drawEdges)
+{
+ // Nasty hack to make us not paint the border on text fields with a border-radius.
+ // Webkit paints elements with border-radius for us.
+ // TODO(ojan): Get rid of this if-check once we can properly clip rounded borders
+ // http://b/1112604 and http://b/1108635
+ // TODO(ojan): make sure we do the right thing if css background-clip is set.
+ if (o->style()->hasBorderRadius())
+ return false;
+
+ // Get the correct theme data for a textfield and paint the text field.
+ PlatformContextSkia* skia = PlatformContextToPlatformContextSkia(i.context->platformContext());
+ SkIRect rect;
+ WebCoreRectToSkiaRect(r, &rect);
+ skia->paintTextField(rect, getThemeData(o), o->style()->backgroundColor().rgb(), drawEdges);
+ return false;
+}
+
+bool RenderThemeWin::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintTextField(o, i, r);
+}
+
+void RenderThemeWin::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ // Height is locked to auto on all browsers.
+ style->setLineHeight(RenderStyle::initialLineHeight());
+
+ if (webkit_glue::IsLayoutTestMode()) {
+ style->resetBorder();
+ style->setHeight(Length(Auto));
+ // Select one of the 3 fixed heights for controls
+ style->resetPadding();
+ if (style->height().isAuto()) {
+ // RenderThemeMac locks the size to 3 distinct values (NSControlSize).
+ // We on the other hand, base the height off the font.
+ int fixedHeight = kLayoutTestControlHeight[controlSizeForFont(style)];
+ style->setHeight(Length(fixedHeight, Fixed));
+ }
+ layoutTestSetFontFromControlSize(selector, style);
+ }
+}
+
+void RenderThemeWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ adjustMenuListStyle(selector, style, e);
+}
+
+// Used to paint unstyled menulists (i.e. with the default border)
+bool RenderThemeWin::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ int borderRight = o->borderRight();
+ int borderLeft = o->borderLeft();
+ int borderTop = o->borderTop();
+ int borderBottom = o->borderBottom();
+
+ // If all the borders are 0, then tell skia not to paint the border on the textfield.
+ // TODO(ojan): http://b/1210017 Figure out how to get Windows to not draw individual
+ // borders and then pass that to skia so we can avoid drawing any borders that are
+ // set to 0. For non-zero borders, we draw the border, but webkit just draws
+ // over it.
+ // TODO(ojan): layout-test-mode removes borders, so we end up never drawing
+ // edges in layout-test-mode. See adjustMenuListStyle, style->resetBorder().
+ // We really need to remove the layout-test-mode only hacks.
+ bool drawEdges = !(borderRight == 0 && borderLeft == 0 && borderTop == 0 && borderBottom == 0);
+
+ paintTextFieldInternal(o, i, r, drawEdges);
+
+ // Take padding and border into account.
+ // If the MenuList is smaller than the size of a button, make sure to
+ // shrink it appropriately and not put its x position to the left of
+ // the menulist.
+ const int buttonWidth = webkit_glue::IsLayoutTestMode() ?
+ kLayoutTestMenuListButtonWidth : GetSystemMetrics(SM_CXVSCROLL);
+ int spacingLeft = borderLeft + o->paddingLeft();
+ int spacingRight = borderRight + o->paddingRight();
+ int spacingTop = borderTop + o->paddingTop();
+ int spacingBottom = borderBottom + o->paddingBottom();
+
+ int buttonX;
+ if (r.right() - r.x() < buttonWidth) {
+ buttonX = r.x();
+ } else {
+ buttonX = o->style()->direction() == LTR ? r.right() - spacingRight - buttonWidth : r.x() + spacingLeft;
+ }
+ IntRect buttonRect(buttonX,
+ r.y() + spacingTop,
+ std::min(buttonWidth, r.right() - r.x()),
+ r.height() - (spacingTop + spacingBottom));
+
+ // Get the correct theme data for a textfield and paint the menu.
+ PlatformContextSkia* skia = PlatformContextToPlatformContextSkia(i.context->platformContext());
+ SkIRect rect;
+ WebCoreRectToSkiaRect(buttonRect, &rect);
+ skia->paintMenuListArrowButton(rect, determineState(o), determineClassicState(o));
+ return false;
+}
+
+// Used to paint styled menulists (i.e. with a non-default border)
+bool RenderThemeWin::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+{
+ return paintMenuList(o, i, r);
+}
+
+int RenderThemeWin::popupInternalPaddingLeft(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, LeftPadding);
+}
+
+int RenderThemeWin::popupInternalPaddingRight(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, RightPadding);
+}
+
+int RenderThemeWin::popupInternalPaddingTop(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, TopPadding);
+}
+
+int RenderThemeWin::popupInternalPaddingBottom(RenderStyle* style) const
+{
+ return menuListInternalPadding(style, BottomPadding);
+}
+
+// Hacks for using Mac menu list metrics when in layout test mode.
+static int layoutTestMenuListInternalPadding(RenderStyle* style, int paddingType)
+{
+ if (style->appearance() == MenulistAppearance) {
+ return kLayoutTestMenuListInternalPadding[controlSizeForFont(style)][paddingType];
+ }
+ if (style->appearance() == MenulistButtonAppearance) {
+ if (paddingType == RightPadding) {
+ const float baseArrowWidth = 5.0f;
+ float fontScale = style->fontSize() / kLayoutTestBaseFontSize;
+ float arrowWidth = ceilf(baseArrowWidth * fontScale);
+
+ int arrowPaddingLeft = 6;
+ int arrowPaddingRight = 6;
+ int paddingBeforeSeparator = 4;
+ // Add 2 for separator space, seems to match RenderThemeMac::paintMenuListButton.
+ return static_cast<int>(arrowWidth + arrowPaddingLeft + arrowPaddingRight +
+ paddingBeforeSeparator);
+ } else {
+ return kLayoutTestStyledMenuListInternalPadding[paddingType];
+ }
+ }
+ return 0;
+}
+
+int RenderThemeWin::menuListInternalPadding(RenderStyle* style, int paddingType) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ return layoutTestMenuListInternalPadding(style, paddingType);
+ }
+
+ // This internal padding is in addition to the user-supplied padding.
+ // Matches the FF behavior.
+ int padding = kStyledMenuListInternalPadding[paddingType];
+
+ // Reserve the space for right arrow here. The rest of the padding is
+ // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from
+ // RenderMenuList to lay out the individual items in the popup.
+ // If the MenuList actually has appearance "NoAppearance", then that means
+ // we don't draw a button, so don't reserve space for it.
+ const int bar_type = style->direction() == LTR ? RightPadding : LeftPadding;
+ if (paddingType == bar_type && style->appearance() != NoAppearance)
+ padding += PlatformScrollbar::verticalScrollbarWidth();
+
+ return padding;
+}
+
+void RenderThemeWin::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 RenderThemeWin::setButtonPadding(RenderStyle* style) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ setFixedPadding(style, kLayoutTestButtonPadding);
+
+ } else if (!style->width().isAuto()) {
+ // We need to set the minimum padding for the buttons, or else they
+ // render too small and clip the button face text. The right way to do
+ // this is to ask window's theme manager to give us the minimum
+ // (TS_MIN) size for the part. As a failsafe we set at least
+ // kDefaultButtonPadding because zero just looks bad.
+ Length minXPadding(kDefaultButtonPadding, Fixed);
+ Length minYPadding(kDefaultButtonPadding, Fixed);
+ // Find minimum padding.
+ getMinimalButtonPadding(&minXPadding);
+
+ // Set the minimum padding.
+ if (style->paddingLeft().value() < minXPadding.value()) {
+ style->setPaddingLeft(minXPadding);
+ }
+ if (style->paddingRight().value() < minXPadding.value()) {
+ style->setPaddingRight(minXPadding);
+ }
+ if (style->paddingBottom().value() < minYPadding.value()) {
+ style->setPaddingBottom(minYPadding);
+ }
+ if (style->paddingTop().value() < minYPadding.value()) {
+ style->setPaddingTop(minYPadding);
+ }
+ }
+}
+
+void RenderThemeWin::adjustSliderThumbSize(RenderObject* o) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ if (o->style()->appearance() == SliderThumbHorizontalAppearance ||
+ o->style()->appearance() == SliderThumbVerticalAppearance) {
+ o->style()->setWidth(Length(kLayoutTestSliderThumbWidth, Fixed));
+ o->style()->setHeight(Length(kLayoutTestSliderThumbHeight, Fixed));
+ }
+ }
+}
+
+void RenderThemeWin::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ // Override border.
+ style->resetBorder();
+ style->setBorderLeftWidth(kLayoutTestSearchFieldBorderWidth);
+ style->setBorderLeftStyle(INSET);
+ style->setBorderRightWidth(kLayoutTestSearchFieldBorderWidth);
+ style->setBorderRightStyle(INSET);
+ style->setBorderBottomWidth(kLayoutTestSearchFieldBorderWidth);
+ style->setBorderBottomStyle(INSET);
+ style->setBorderTopWidth(kLayoutTestSearchFieldBorderWidth);
+ style->setBorderTopStyle(INSET);
+
+ // Override height.
+ style->setHeight(Length(
+ kLayoutTestSearchFieldHeight[controlSizeForFont(style)],
+ Fixed));
+
+ // Override padding size to match AppKit text positioning.
+ style->setPaddingLeft(Length(kLayoutTestSearchFieldPadding, Fixed));
+ style->setPaddingRight(Length(kLayoutTestSearchFieldPadding, Fixed));
+ style->setPaddingTop(Length(kLayoutTestSearchFieldPadding, Fixed));
+ style->setPaddingBottom(Length(kLayoutTestSearchFieldPadding, Fixed));
+
+ style->setBoxShadow(0);
+ }
+}
+
+static const IntSize* layoutTestCancelButtonSizes()
+{
+ static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(13, 9) };
+ return sizes;
+}
+
+static const IntSize* layoutTestResultsButtonSizes()
+{
+ static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(17, 9) };
+ return sizes;
+}
+
+void RenderThemeWin::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ IntSize size = layoutTestCancelButtonSizes()[controlSizeForFont(style)];
+ style->setWidth(Length(size.width(), Fixed));
+ style->setHeight(Length(size.height(), Fixed));
+ style->setBoxShadow(0);
+ }
+}
+
+void RenderThemeWin::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ IntSize size = layoutTestResultsButtonSizes()[controlSizeForFont(style)];
+ style->setWidth(Length(size.width() - kLayoutTestEmptyResultsOffset, Fixed));
+ style->setHeight(Length(size.height(), Fixed));
+ style->setBoxShadow(0);
+ }
+}
+
+void RenderThemeWin::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ IntSize size = layoutTestResultsButtonSizes()[controlSizeForFont(style)];
+ style->setWidth(Length(size.width(), Fixed));
+ style->setHeight(Length(size.height(), Fixed));
+ style->setBoxShadow(0);
+ }
+}
+
+void RenderThemeWin::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
+{
+ if (webkit_glue::IsLayoutTestMode()) {
+ IntSize size = layoutTestResultsButtonSizes()[controlSizeForFont(style)];
+ style->setWidth(Length(size.width() + kLayoutTestResultsArrowWidth, Fixed));
+ style->setHeight(Length(size.height(), Fixed));
+ style->setBoxShadow(0);
+ }
+}
+
+void RenderThemeWin::getMinimalButtonPadding(Length* minXPadding) const {
+ // TODO(maruel): This get messy if 1. the theme change; 2. we are serializing.
+ SIZE size;
+ if (SUCCEEDED(gfx::NativeTheme::instance()->GetThemePartSize(
+ gfx::NativeTheme::BUTTON, 0, BP_PUSHBUTTON, PBS_NORMAL, 0, TS_MIN,
+ &size))) {
+ *minXPadding = Length(size.cx, Fixed);
+ }
+}
+
+// static
+void RenderThemeWin::setDefaultFontSize(int fontSize) {
+ DefaultFontSize = static_cast<float>(fontSize);
+
+ // Reset cached fonts.
+ SmallSystemFont = MenuFont = LabelFont = FontDescription();
+}
+
+}
diff --git a/webkit/port/rendering/RenderThemeWin.h b/webkit/port/rendering/RenderThemeWin.h
new file mode 100644
index 0000000..bd4db98
--- /dev/null
+++ b/webkit/port/rendering/RenderThemeWin.h
@@ -0,0 +1,133 @@
+/*
+ * This file is part of the WebKit project.
+ *
+ * Copyright (C) 2006 Apple Computer, 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.
+ *
+ */
+
+#ifndef RenderThemeWin_h
+#define RenderThemeWin_h
+
+#include "RenderTheme.h"
+#include "ThemeData.h"
+
+#if WIN32
+typedef void* HANDLE;
+typedef struct HINSTANCE__* HINSTANCE;
+typedef HINSTANCE HMODULE;
+#endif
+
+namespace WebCore {
+
+class RenderThemeWin : public RenderTheme {
+public:
+ RenderThemeWin();
+ ~RenderThemeWin();
+
+ // A method asking if the theme's controls actually care about redrawing when hovered.
+ virtual bool supportsHover(const RenderStyle*) const { return true; }
+
+ virtual bool supportsFocusRing(const RenderStyle*) const;
+
+ virtual Color platformActiveSelectionBackgroundColor() const;
+ virtual Color platformInactiveSelectionBackgroundColor() const;
+ virtual Color platformActiveSelectionForegroundColor() const;
+ virtual Color platformInactiveSelectionForegroundColor() const;
+
+ virtual double caretBlinkFrequency() const;
+
+ // System fonts.
+ virtual void systemFont(int propId, Document*, FontDescription&) const;
+
+ virtual int minimumMenuListSize(RenderStyle*) const;
+
+ virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+ { return paintButton(o, i, r); }
+ virtual void setCheckboxSize(RenderStyle*) const;
+
+ virtual bool paintRadio(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+ { return paintButton(o, i, r); }
+ virtual void setRadioSize(RenderStyle* style) const;
+
+ virtual bool paintButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+
+ virtual bool paintTextField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+
+ virtual bool paintTextArea(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r)
+ { return paintTextField(o, i, r); }
+
+ // MenuList refers to an unstyled menulist (meaning a menulist without
+ // background-color or border set) and MenuListButton refers to a styled
+ // menulist (a menulist with background-color or border set). They have
+ // this distinction to support showing aqua style themes whenever they
+ // possibly can, which is something we don't want to replicate.
+ //
+ // In short, we either go down the MenuList code path or the MenuListButton
+ // codepath. We never go down both. And in both cases, they render the
+ // entire menulist.
+ virtual void adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const;
+ virtual bool paintMenuList(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+ virtual void adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const;
+ virtual bool paintMenuListButton(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+
+ // These methods define the padding for the MenuList's inner block.
+ virtual int popupInternalPaddingLeft(RenderStyle*) const;
+ virtual int popupInternalPaddingRight(RenderStyle*) const;
+ virtual int popupInternalPaddingTop(RenderStyle*) const;
+ virtual int popupInternalPaddingBottom(RenderStyle*) const;
+
+ virtual void adjustButtonInnerStyle(RenderStyle* style) const;
+
+ virtual void adjustSliderThumbSize(RenderObject*) const;
+
+ virtual void adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual void adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual void adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual void adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+
+ virtual bool paintSearchField(RenderObject*, const RenderObject::PaintInfo&, const IntRect&);
+
+ // Provide a way to pass the default font size from the Settings object to
+ // the render theme. TODO(tc): http://b/1129186 A cleaner way would be to
+ // remove the default font size from this object and have callers that need
+ // the value to get it directly from the appropriate Settings object.
+ static void setDefaultFontSize(int);
+
+private:
+ void addIntrinsicMargins(RenderStyle*) const;
+
+ unsigned determineState(RenderObject*);
+ unsigned determineClassicState(RenderObject*);
+ bool supportsFocus(EAppearance);
+
+ ThemeData getThemeData(RenderObject*);
+
+ bool paintTextFieldInternal(RenderObject*, const RenderObject::PaintInfo&, const IntRect&, bool);
+
+ void setButtonPadding(RenderStyle* style) const;
+
+ // Gets the minimal x button padding according to the current theme.
+ void getMinimalButtonPadding(Length* minXPadding) const;
+
+ int menuListInternalPadding(RenderStyle* style, int paddingType) const;
+};
+
+};
+
+#endif