diff options
author | Russell Brenner <russellbrenner@google.com> | 2010-11-18 17:33:13 -0800 |
---|---|---|
committer | Russell Brenner <russellbrenner@google.com> | 2010-12-02 13:47:21 -0800 |
commit | 6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch) | |
tree | 103a13998c33944d6ab3b8318c509a037e639460 /WebCore/platform/gtk | |
parent | bdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff) | |
download | external_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.c | 2 | ||||
-rw-r--r-- | WebCore/platform/gtk/LocalizedStringsGtk.cpp | 26 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.cpp | 137 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.h | 11 | ||||
-rw-r--r-- | WebCore/platform/gtk/ScrollbarThemeGtk.cpp | 17 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContext.h | 56 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp | 170 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp | 52 | ||||
-rw-r--r-- | WebCore/platform/gtk/gtk3drawing.c | 8 |
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; } |