summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/gtk
diff options
context:
space:
mode:
authorRussell Brenner <russellbrenner@google.com>2010-11-18 17:33:13 -0800
committerRussell Brenner <russellbrenner@google.com>2010-12-02 13:47:21 -0800
commit6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch)
tree103a13998c33944d6ab3b8318c509a037e639460 /WebCore/platform/gtk
parentbdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff)
downloadexternal_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip
external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz
external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'WebCore/platform/gtk')
-rw-r--r--WebCore/platform/gtk/GtkVersioning.c2
-rw-r--r--WebCore/platform/gtk/LocalizedStringsGtk.cpp26
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp137
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.h11
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.cpp17
-rw-r--r--WebCore/platform/gtk/WidgetRenderingContext.h56
-rw-r--r--WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp170
-rw-r--r--WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp52
-rw-r--r--WebCore/platform/gtk/gtk3drawing.c8
9 files changed, 352 insertions, 127 deletions
diff --git a/WebCore/platform/gtk/GtkVersioning.c b/WebCore/platform/gtk/GtkVersioning.c
index 071c5e5..0776c10 100644
--- a/WebCore/platform/gtk/GtkVersioning.c
+++ b/WebCore/platform/gtk/GtkVersioning.c
@@ -225,7 +225,7 @@ gdk_pixbuf_get_from_surface(cairo_surface_t * surface,
GdkPixbuf * dest;
/* General sanity checks */
- g_return_val_if_fail(!surface, NULL);
+ g_return_val_if_fail(surface, NULL);
g_return_val_if_fail(srcX >= 0 && srcY >= 0, NULL);
g_return_val_if_fail(width > 0 && height > 0, NULL);
diff --git a/WebCore/platform/gtk/LocalizedStringsGtk.cpp b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
index 7851326..68c1598 100644
--- a/WebCore/platform/gtk/LocalizedStringsGtk.cpp
+++ b/WebCore/platform/gtk/LocalizedStringsGtk.cpp
@@ -559,27 +559,45 @@ String validationMessageTypeMismatchText()
return String::fromUTF8(_("type mismatch"));
}
+String validationMessageTypeMismatchForEmailText()
+{
+ notImplemented();
+ return validationMessageTypeMismatchText();
+}
+
+String validationMessageTypeMismatchForMultipleEmailText()
+{
+ notImplemented();
+ return validationMessageTypeMismatchText();
+}
+
+String validationMessageTypeMismatchForURLText()
+{
+ notImplemented();
+ return validationMessageTypeMismatchText();
+}
+
String validationMessagePatternMismatchText()
{
return String::fromUTF8(_("pattern mismatch"));
}
-String validationMessageTooLongText()
+String validationMessageTooLongText(int, int)
{
return String::fromUTF8(_("too long"));
}
-String validationMessageRangeUnderflowText()
+String validationMessageRangeUnderflowText(const String&)
{
return String::fromUTF8(_("range underflow"));
}
-String validationMessageRangeOverflowText()
+String validationMessageRangeOverflowText(const String&)
{
return String::fromUTF8(_("range overflow"));
}
-String validationMessageStepMismatchText()
+String validationMessageStepMismatchText(const String&, const String&)
{
return String::fromUTF8(_("step mismatch"));
}
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 8df5cda..fe6c9e9 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -3,6 +3,7 @@
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2008 Collabora Ltd.
* Copyright (C) 2009 Kenneth Rohde Christiansen
+ * Copyright (C) 2010 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -40,6 +41,7 @@
#include "Scrollbar.h"
#include "TimeRanges.h"
#include "UserAgentStyleSheets.h"
+#include "WidgetRenderingContext.h"
#include "gtkdrawing.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h>
@@ -151,15 +153,26 @@ RenderThemeGtk::RenderThemeGtk()
, m_pauseButton(0)
, m_seekBackButton(0)
, m_seekForwardButton(0)
- , m_partsTable(adoptPlatformRef(g_hash_table_new_full(0, 0, 0, g_free)))
+#ifdef GTK_API_VERSION_2
+ , m_themePartsHaveRGBAColormap(true)
+#endif
{
- if (!mozGtkRefCount) {
- moz_gtk_init();
- // Use the theme parts for the default drawable.
- moz_gtk_use_theme_parts(partsForDrawable(0));
+ memset(&m_themeParts, 0, sizeof(GtkThemeParts));
+#ifdef GTK_API_VERSION_2
+ GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default());
+ if (!colormap) {
+ m_themePartsHaveRGBAColormap = false;
+ colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
}
+ m_themeParts.colormap = colormap;
+#endif
+ // Initialize the Mozilla theme drawing code.
+ if (!mozGtkRefCount) {
+ moz_gtk_init();
+ moz_gtk_use_theme_parts(&m_themeParts);
+ }
++mozGtkRefCount;
#if ENABLE(VIDEO)
@@ -182,36 +195,19 @@ RenderThemeGtk::~RenderThemeGtk()
m_seekBackButton.clear();
m_seekForwardButton.clear();
- GList* values = g_hash_table_get_values(m_partsTable.get());
- for (guint i = 0; i < g_list_length(values); i++)
- moz_gtk_destroy_theme_parts_widgets(
- static_cast<GtkThemeParts*>(g_list_nth_data(values, i)));
-
gtk_widget_destroy(m_gtkWindow);
}
-GtkThemeParts* RenderThemeGtk::partsForDrawable(GdkDrawable* drawable) const
+void RenderThemeGtk::getIndicatorMetrics(ControlPart part, int& indicatorSize, int& indicatorSpacing) const
{
-#ifdef GTK_API_VERSION_2
- // A null drawable represents the default screen colormap.
- GdkColormap* colormap = 0;
- if (!drawable)
- colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
- else
- colormap = gdk_drawable_get_colormap(drawable);
-
- GtkThemeParts* parts = static_cast<GtkThemeParts*>(g_hash_table_lookup(m_partsTable.get(), colormap));
- if (!parts) {
- parts = g_new0(GtkThemeParts, 1);
- parts->colormap = colormap;
- g_hash_table_insert(m_partsTable.get(), colormap, parts);
+ ASSERT(part == CheckboxPart || part == RadioPart);
+ if (part == CheckboxPart) {
+ moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing);
+ return;
}
-#else
- // For GTK+ 3.0 we no longer have to worry about maintaining a set of widgets per-colormap.
- static GtkThemeParts* parts = g_slice_new0(GtkThemeParts);
-#endif // GTK_API_VERSION_2
- return parts;
+ // RadioPart
+ moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing);
}
static bool supportsFocus(ControlPart appearance)
@@ -289,69 +285,6 @@ static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style,
style->setPaddingBottom(Length(ypadding + bottom, Fixed));
}
-#ifdef GTK_API_VERSION_2
-bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection)
-{
- // Painting is disabled so just claim to have succeeded
- if (context->paintingDisabled())
- return false;
-
- PlatformRefPtr<GdkDrawable> drawable(context->gdkDrawable());
- GdkRectangle paintRect, clipRect;
- if (drawable) {
- AffineTransform ctm = context->getCTM();
- IntPoint pos = ctm.mapPoint(rect.location());
- paintRect = IntRect(pos.x(), pos.y(), rect.width(), rect.height());
-
- // Intersect the cairo rectangle with the target widget region. This will
- // prevent the theme drawing code from drawing into regions that cairo will
- // clip anyway.
- double clipX1, clipX2, clipY1, clipY2;
- cairo_clip_extents(context->platformContext(), &clipX1, &clipY1, &clipX2, &clipY2);
- IntPoint clipPos = ctm.mapPoint(IntPoint(clipX1, clipY1));
-
- clipRect.width = clipX2 - clipX1;
- clipRect.height = clipY2 - clipY1;
- clipRect.x = clipPos.x();
- clipRect.y = clipPos.y();
- gdk_rectangle_intersect(&paintRect, &clipRect, &clipRect);
-
- } else {
- // In some situations, like during print previews, this GraphicsContext is not
- // backed by a GdkDrawable. In those situations, we render onto a pixmap and then
- // copy the rendered data back to the GraphicsContext via Cairo.
- drawable = adoptPlatformRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_depth(gdk_visual_get_system())));
- paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height());
- }
-
- moz_gtk_use_theme_parts(partsForDrawable(drawable.get()));
- bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, widgetState, flags, textDirection) == MOZ_GTK_SUCCESS;
-
- // If the drawing was successful and we rendered onto a pixmap, copy the
- // results back to the original GraphicsContext.
- if (success && !context->gdkDrawable()) {
- cairo_t* cairoContext = context->platformContext();
- cairo_save(cairoContext);
- gdk_cairo_set_source_pixmap(cairoContext, drawable.get(), rect.x(), rect.y());
- cairo_paint(cairoContext);
- cairo_restore(cairoContext);
- }
-
- return !success;
-}
-#else
-bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection)
-{
- // Painting is disabled so just claim to have succeeded
- if (context->paintingDisabled())
- return false;
-
- // false == success, because of awesome.
- GdkRectangle paintRect = rect;
- return moz_gtk_widget_paint(type, context->platformContext(), &paintRect, widgetState, flags, textDirection) != MOZ_GTK_SUCCESS;
-}
-#endif
-
bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags)
{
// Painting is disabled so just claim to have succeeded
@@ -382,8 +315,8 @@ bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* re
else
widgetState.depressed = false;
- GtkTextDirection textDirection = gtkTextDirection(renderObject->style()->direction());
- return paintMozillaGtkWidget(type, context, rect, &widgetState, flags, textDirection);
+ WidgetRenderingContext widgetContext(context, rect);
+ return !widgetContext.paintMozillaWidget(type, &widgetState, flags, gtkTextDirection(renderObject->style()->direction()));
}
static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, ControlPart appearance)
@@ -394,19 +327,7 @@ static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, Contr
// FIXME: This is probably not correct use of indicatorSize and indicatorSpacing.
gint indicatorSize, indicatorSpacing;
-
- switch (appearance) {
- case CheckboxPart:
- if (moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
- return;
- break;
- case RadioPart:
- if (moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
- return;
- break;
- default:
- return;
- }
+ theme->getIndicatorMetrics(appearance, indicatorSize, indicatorSpacing);
// Other ports hard-code this to 13, but GTK+ users tend to demand the native look.
// It could be made a configuration option values other than 13 actually break site compatibility.
@@ -614,7 +535,7 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& inf
if (part == SliderVerticalPart)
gtkPart = MOZ_GTK_SCALE_VERTICAL;
- return paintRenderObject(gtkPart, object, info.context, toRenderBox(object)->absoluteContentBox());
+ return paintRenderObject(gtkPart, object, info.context, rect);
}
void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h
index 6d324b6..ac08cf1 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.h
+++ b/WebCore/platform/gtk/RenderThemeGtk.h
@@ -83,7 +83,7 @@ public:
virtual String extraMediaControlsStyleSheet();
#endif
- bool paintMozillaGtkWidget(GtkThemeWidgetType, GraphicsContext*, const IntRect&, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE);
+ void getIndicatorMetrics(ControlPart, int& indicatorSize, int& indicatorSpacing) const;
GtkWidget* gtkScrollbar();
@@ -169,7 +169,6 @@ private:
GtkContainer* gtkContainer() const;
bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0);
- GtkThemeParts* partsForDrawable(GdkDrawable*) const;
mutable GtkWidget* m_gtkWindow;
mutable GtkContainer* m_gtkContainer;
@@ -193,9 +192,11 @@ private:
RefPtr<Image> m_pauseButton;
RefPtr<Image> m_seekBackButton;
RefPtr<Image> m_seekForwardButton;
- Page* m_page;
- PlatformRefPtr<GHashTable> m_partsTable;
-
+ GtkThemeParts m_themeParts;
+#ifdef GTK_API_VERSION_2
+ bool m_themePartsHaveRGBAColormap;
+#endif
+ friend class WidgetRenderingContext;
};
}
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
index 19b897c..10f7e71 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
@@ -30,6 +30,7 @@
#include "RenderThemeGtk.h"
#include "ScrollView.h"
#include "Scrollbar.h"
+#include "WidgetRenderingContext.h"
#include "gtkdrawing.h"
#include <gtk/gtk.h>
@@ -216,7 +217,8 @@ void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar
fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_TRACK_VERTICAL : MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL;
- static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, fullScrollbarRect, &state, 0);
+ WidgetRenderingContext widgetContext(context, fullScrollbarRect);
+ widgetContext.paintMozillaWidget(type, &state, 0);
}
void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
@@ -224,7 +226,8 @@ void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrol
// This is unused by the moz_gtk_scrollecd_window_paint.
GtkWidgetState state;
IntRect fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
- static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLED_WINDOW, context, fullScrollbarRect, &state, 0);
+ WidgetRenderingContext widgetContext(context, fullScrollbarRect);
+ widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLED_WINDOW, &state, 0);
}
void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
@@ -240,7 +243,8 @@ void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollba
state.curpos = scrollbar->currentPos();
GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
- static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, rect, &state, 0);
+ WidgetRenderingContext widgetContext(context, rect);
+ widgetContext.paintMozillaWidget(type, &state, 0);
}
IntRect ScrollbarThemeGtk::thumbRect(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect)
@@ -256,6 +260,9 @@ IntRect ScrollbarThemeGtk::thumbRect(Scrollbar* scrollbar, const IntRect& uncons
bool ScrollbarThemeGtk::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect)
{
+ if (graphicsContext->paintingDisabled())
+ return false;
+
// Create the ScrollbarControlPartMask based on the damageRect
ScrollbarControlPartMask scrollMask = NoPart;
@@ -334,6 +341,7 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
state.focused = TRUE;
state.isDefault = TRUE;
state.canDefault = TRUE;
+ state.depressed = FALSE;
if ((BackButtonStartPart == part && scrollbar->currentPos())
|| (BackButtonEndPart == part && scrollbar->currentPos())
@@ -348,7 +356,8 @@ void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollb
state.inHover = FALSE;
}
- static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLBAR_BUTTON, context, rect, &state, flags);
+ WidgetRenderingContext widgetContext(context, rect);
+ widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLBAR_BUTTON, &state, flags);
}
void ScrollbarThemeGtk::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
diff --git a/WebCore/platform/gtk/WidgetRenderingContext.h b/WebCore/platform/gtk/WidgetRenderingContext.h
new file mode 100644
index 0000000..3bb8065
--- /dev/null
+++ b/WebCore/platform/gtk/WidgetRenderingContext.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ * All rights reserved.
+ *
+ * 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 WidgetRenderingContext_h
+#define WidgetRenderingContext_h
+
+#include "IntRect.h"
+#include "gtkdrawing.h"
+
+namespace WebCore {
+
+class GraphicsContext;
+class RenderThemeGtk;
+
+class WidgetRenderingContext {
+public:
+ WidgetRenderingContext(GraphicsContext*, const IntRect&);
+ ~WidgetRenderingContext();
+ bool paintMozillaWidget(GtkThemeWidgetType, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE);
+
+private:
+ GraphicsContext* m_graphicsContext;
+ IntRect m_targetRect;
+ GdkRectangle m_paintRect;
+ IntSize m_extraSpace;
+ bool m_hadError;
+
+#ifdef GTK_API_VERSION_2
+ GdkDrawable* m_target;
+#else
+ cairo_t* m_target;
+#endif
+
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp b/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp
new file mode 100644
index 0000000..b8712d2
--- /dev/null
+++ b/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef GTK_API_VERSION_2
+
+#include "config.h"
+#include "WidgetRenderingContext.h"
+
+#include "GraphicsContext.h"
+#include "RefPtrCairo.h"
+#include "RenderThemeGtk.h"
+#include "Timer.h"
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+namespace WebCore {
+
+static GdkPixmap* gScratchBuffer = 0;
+static void purgeScratchBuffer()
+{
+ if (gScratchBuffer)
+ g_object_unref(gScratchBuffer);
+ gScratchBuffer = 0;
+}
+
+// FIXME: Perhaps we can share some of this code with the ContextShadowCairo.
+// Widget rendering needs a scratch image as the buffer for the intermediate
+// render. Instead of creating and destroying the buffer for every operation,
+// we create a buffer which will be automatically purged via a timer.
+class PurgeScratchBufferTimer : public TimerBase {
+private:
+ virtual void fired() { purgeScratchBuffer(); }
+};
+static PurgeScratchBufferTimer purgeScratchBufferTimer;
+static void scheduleScratchBufferPurge()
+{
+ if (purgeScratchBufferTimer.isActive())
+ purgeScratchBufferTimer.stop();
+ purgeScratchBufferTimer.startOneShot(2);
+}
+
+static IntSize getExtraSpaceForWidget(RenderThemeGtk* theme)
+{
+ // Checkboxes and scrollbar thumbs often draw outside their boundaries. Here we figure out
+ // the maximum amount of space we need for any type of widget and use that to increase the
+ // size of the scratch buffer, while preserving the final widget position.
+
+ // The checkbox extra space is calculated by looking at the widget style.
+ int indicatorSize, indicatorSpacing;
+ theme->getIndicatorMetrics(CheckboxPart, indicatorSize, indicatorSpacing);
+ IntSize extraSpace(indicatorSpacing, indicatorSpacing);
+
+ // Scrollbar thumbs need at least an extra pixel along their movement axis.
+ return extraSpace.expandedTo(IntSize(1, 1));
+}
+
+WidgetRenderingContext::WidgetRenderingContext(GraphicsContext* graphicsContext, const IntRect& targetRect)
+ : m_graphicsContext(graphicsContext)
+ , m_targetRect(targetRect)
+ , m_hadError(false)
+{
+ RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get());
+
+ // Fallback: We failed to create an RGBA colormap earlier, so we cannot properly paint
+ // to a temporary surface and preserve transparency. To ensure decent widget rendering, just
+ // paint directly to the target drawable. This will not render CSS rotational transforms properly.
+ if (!theme->m_themePartsHaveRGBAColormap && graphicsContext->gdkDrawable()) {
+ m_paintRect = graphicsContext->getCTM().mapRect(targetRect);
+ m_target = graphicsContext->gdkDrawable();
+ return;
+ }
+
+ // Some widgets render outside their rectangles. We need to account for this.
+ m_extraSpace = getExtraSpaceForWidget(theme);
+
+ // Offset the target rectangle so that the extra space is within the boundaries of the scratch buffer.
+ m_paintRect = IntRect(IntPoint(m_extraSpace.width(), m_extraSpace.height()),
+ m_targetRect.size());
+
+ int width = m_targetRect.width() + (m_extraSpace.width() * 2);
+ int height = m_targetRect.height() + (m_extraSpace.height() * 2);
+ int scratchWidth = 0;
+ int scratchHeight = 0;
+ if (gScratchBuffer)
+ gdk_drawable_get_size(gScratchBuffer, &scratchWidth, &scratchHeight);
+
+ // We do not need to recreate the buffer if the current buffer is large enough.
+ if (!gScratchBuffer || scratchWidth < width || scratchHeight < height) {
+ purgeScratchBuffer();
+ // Round to the nearest 32 pixels so we do not grow the buffer for similar sized requests.
+ width = (1 + (width >> 5)) << 5;
+ height = (1 + (height >> 5)) << 5;
+
+ gScratchBuffer = gdk_pixmap_new(0, width, height, gdk_colormap_get_visual(theme->m_themeParts.colormap)->depth);
+ gdk_drawable_set_colormap(gScratchBuffer, theme->m_themeParts.colormap);
+ }
+ m_target = gScratchBuffer;
+
+ // Clear the scratch buffer.
+ RefPtr<cairo_t> scratchBufferContext = adoptRef(gdk_cairo_create(gScratchBuffer));
+ cairo_set_operator(scratchBufferContext.get(), CAIRO_OPERATOR_CLEAR);
+ cairo_paint(scratchBufferContext.get());
+}
+
+WidgetRenderingContext::~WidgetRenderingContext()
+{
+ // We do not need to blit back to the target in the fallback case. See above.
+ RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get());
+ if (!theme->m_themePartsHaveRGBAColormap && m_graphicsContext->gdkDrawable())
+ return;
+
+ // Don't paint the results back if there was an error.
+ if (m_hadError) {
+ scheduleScratchBufferPurge();
+ return;
+ }
+
+ // FIXME: It's unclear if it is necessary to preserve the current source here.
+ cairo_t* cairoContext = m_graphicsContext->platformContext();
+ RefPtr<cairo_pattern_t> previousSource(cairo_get_source(cairoContext));
+
+ // The blit rectangle is the original target rectangle adjusted for any extra space.
+ IntRect fullTargetRect(m_targetRect);
+ fullTargetRect.inflateX(m_extraSpace.width());
+ fullTargetRect.inflateY(m_extraSpace.height());
+
+ gdk_cairo_set_source_pixmap(cairoContext, gScratchBuffer, fullTargetRect.x(), fullTargetRect.y());
+ cairo_rectangle(cairoContext, fullTargetRect.x(), fullTargetRect.y(), fullTargetRect.width(), fullTargetRect.height());
+ cairo_fill(cairoContext);
+ cairo_set_source(cairoContext, previousSource.get());
+ scheduleScratchBufferPurge();
+}
+
+bool WidgetRenderingContext::paintMozillaWidget(GtkThemeWidgetType type, GtkWidgetState* state, int flags, GtkTextDirection textDirection)
+{
+ // Sometimes moz_gtk_widget_paint modifies the clipping rectangle, so we must use a copy.
+ GdkRectangle clipRect = m_paintRect;
+ m_hadError = moz_gtk_widget_paint(type, m_target, &clipRect, &m_paintRect,
+ state, flags, textDirection) != MOZ_GTK_SUCCESS;
+ return !m_hadError;
+}
+
+}
+
+#endif // GTK_API_VERSION_2
diff --git a/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp b/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp
new file mode 100644
index 0000000..e5f1823
--- /dev/null
+++ b/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * 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 "WidgetRenderingContext.h"
+
+#include "GraphicsContext.h"
+#include "IntRect.h"
+
+#ifndef GTK_API_VERSION_2
+
+namespace WebCore {
+
+WidgetRenderingContext::WidgetRenderingContext(GraphicsContext* context, const IntRect& targetRect)
+ : m_graphicsContext(context)
+ , m_targetRect(targetRect)
+ , m_paintRect(targetRect)
+ , m_hadError(false)
+ , m_target(context->platformContext())
+{
+}
+
+WidgetRenderingContext::~WidgetRenderingContext()
+{
+}
+
+bool WidgetRenderingContext::paintMozillaWidget(GtkThemeWidgetType type, GtkWidgetState* state, int flags, GtkTextDirection textDirection)
+{
+ m_hadError = moz_gtk_widget_paint(type, m_target, &m_paintRect, state, flags, textDirection) != MOZ_GTK_SUCCESS;
+ return !m_hadError;
+}
+
+}
+
+#endif // !GTK_API_VERSION_2
diff --git a/WebCore/platform/gtk/gtk3drawing.c b/WebCore/platform/gtk/gtk3drawing.c
index dda110d..880eb6d 100644
--- a/WebCore/platform/gtk/gtk3drawing.c
+++ b/WebCore/platform/gtk/gtk3drawing.c
@@ -642,8 +642,6 @@ static gint
moz_gtk_scrolled_window_paint(cairo_t* cr, GdkRectangle* rect,
GtkWidgetState* state)
{
- GtkStateType state_type = ConvertGtkState(state);
- GtkShadowType shadow_type = (state->active) ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
GtkStyle* style;
GtkAllocation allocation;
GtkWidget* widget;
@@ -659,9 +657,9 @@ moz_gtk_scrolled_window_paint(cairo_t* cr, GdkRectangle* rect,
gtk_widget_set_allocation(widget, &allocation);
style = gtk_widget_get_style(widget);
- gtk_paint_box(style, cr, state_type, shadow_type,
- widget, "scrolled_window", rect->x - 1, rect->y - 1,
- rect->width + 2, rect->height + 2);
+ gtk_paint_shadow(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_IN,
+ widget, "scrolled_window", rect->x , rect->y,
+ rect->width, rect->height);
return MOZ_GTK_SUCCESS;
}