Changeset 71791 in webkit


Ignore:
Timestamp:
Nov 10, 2010 6:28:56 PM (14 years ago)
Author:
Martin Robinson
Message:

2010-10-18 Martin Robinson <mrobinson@igalia.com>

Reviewed by Xan Lopez.

[GTK] Widgets do not support CSS transformations
https://bugs.webkit.org/show_bug.cgi?id=40139

Added a platform-specific baseline for the slider transformation
test. This baseline says "FAIL" because the test has platform-specific
offsets hard-coded. The result is only one tick off from expected though,
so it's likely correct for us.

  • platform/gtk/Skipped: Unskip.
  • platform/gtk/fast/forms/slider-transformed-expected.txt: Added.

2010-10-15 Martin Robinson <mrobinson@igalia.com>

Reviewed by Xan Lopez.

[GTK] Widgets do not support CSS transformations
https://bugs.webkit.org/show_bug.cgi?id=40139

Instead of rendering directly onto the target drawable when rendering
form controls on GTK+ 2.0, render onto an intermediate surface and use
cairo to blit the result back to the target surface. This has two
benefits. The first is that it always honors the current Cairo
transformation. The second is that since the intermediate drawable is
always a 32-bit GdkPixmap, we do not have to have a set of widgets
per-colormap any longer.

This change also begins the abstraction of widget rendering so that GTK+
2 and GTK+ 3 can use the same code path. The WidgetRenderingContext will
eventually hide all version differences from RenderThemeGtk, which can
just focus on interpreting the GtkStyle properties.

  • GNUmakefile.am: Add WidgetRenderinContext source files to the sources list.
  • platform/graphics/cairo/PlatformRefPtrCairo.cpp: (WTF::refPlatformPtr): Add a specialization for Cairo patterns. (WTF::derefPlatformPtr): Ditto.
  • platform/graphics/cairo/PlatformRefPtrCairo.h: Ditto.
  • platform/gtk/RenderThemeGtk.cpp: (WebCore::RenderThemeGtk::RenderThemeGtk): No longer keep a set of widgets per-colormap for GTK+, instead just determine if we can use RGBA colormaps and go from there. (WebCore::RenderThemeGtk::~RenderThemeGtk): Ditto. (WebCore::RenderThemeGtk::getIndicatorMetrics): Put the logic for getting toggle button indicator metrics into this helper. (WebCore::RenderThemeGtk::paintRenderObject): Now uses WidgetRenderingContext to do widget rendering. (WebCore::setToggleSize): Use the new getIndicatorMetrics helper.
  • platform/gtk/RenderThemeGtk.h: Added a member to track whether or not the widgets are using a RGBA colormap. Also remove a defunct Page* member.
  • platform/gtk/ScrollbarThemeGtk.cpp: Switch all widget drawing operations to use WidgetRenderingContext. (WebCore::ScrollbarThemeGtk::paintTrackBackground): Ditto. (WebCore::ScrollbarThemeGtk::paintScrollbarBackground): Ditto. (WebCore::ScrollbarThemeGtk::paintThumb): Ditto. (WebCore::ScrollbarThemeGtk::paint): Ditto. (WebCore::ScrollbarThemeGtk::paintButton): Ditto.
  • platform/gtk/WidgetRenderingContext.h: Added.
  • platform/gtk/WidgetRenderingContextGtk2.cpp: Added. (WebCore::purgeScratchBuffer): Added, this is similar to the scratch buffer implementation from ContextShadow. (WebCore::PurgeScratchBufferTimer::fired): Ditto. (WebCore::scheduleScratchBufferPurge): Ditto. (WebCore::getExtraSpaceForWidget): (WebCore::WidgetRenderingContext::WidgetRenderingContext): Added. (WebCore::WidgetRenderingContext::~WidgetRenderingContext): Added. (WebCore::WidgetRenderingContext::paintMozillaWidget): Added.
  • platform/gtk/WidgetRenderingContextGtk3.cpp: Added. (WebCore::WidgetRenderingContext::WidgetRenderingContext): Added. (WebCore::~WidgetRenderingContext::WidgetRenderingContext): Added. (WebCore::WidgetRenderingContext::paintMozillaWidget): Added.
Location:
trunk
Files:
4 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r71789 r71791  
     12010-10-18  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Xan Lopez.
     4
     5        [GTK] Widgets do not support CSS transformations
     6        https://bugs.webkit.org/show_bug.cgi?id=40139
     7
     8        Added a platform-specific baseline for the slider transformation
     9        test. This baseline says "FAIL" because the test has platform-specific
     10        offsets hard-coded. The result is only one tick off from expected though,
     11        so it's likely correct for us.
     12
     13        * platform/gtk/Skipped: Unskip.
     14        * platform/gtk/fast/forms/slider-transformed-expected.txt: Added.
     15
    1162010-11-10  Mihai Parparita  <mihaip@chromium.org>
    217
  • trunk/LayoutTests/platform/gtk/Skipped

    r71718 r71791  
    52355235fast/dom/Geolocation/disconnected-frame-permission-denied.html
    52365236
    5237 # GTK+ theme-rendered widgets do not support CSS transforms
    5238 # https://bugs.webkit.org/show_bug.cgi?id=40139
    5239 fast/forms/slider-transformed.html
    5240 fast/forms/slider-transformed.html
    5241 
    52425237# Some input type=range tests fail because of the size
    52435238# of the slider thumb in GTK+ themes.
  • trunk/WebCore/ChangeLog

    r71790 r71791  
     12010-10-15  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Xan Lopez.
     4
     5        [GTK] Widgets do not support CSS transformations
     6        https://bugs.webkit.org/show_bug.cgi?id=40139
     7
     8        Instead of rendering directly onto the target drawable when rendering
     9        form controls on GTK+ 2.0, render onto an intermediate surface and use
     10        cairo to blit the result back to the target surface. This has two
     11        benefits. The first is that it always honors the current Cairo
     12        transformation. The second is that since the intermediate drawable is
     13        always a 32-bit GdkPixmap, we do not have to have a set of widgets
     14        per-colormap any longer.
     15
     16        This change also begins the abstraction of widget rendering so that GTK+
     17        2 and GTK+ 3 can use the same code path. The WidgetRenderingContext will
     18        eventually hide all version differences from RenderThemeGtk, which can
     19        just focus on interpreting the GtkStyle properties.
     20
     21        * GNUmakefile.am: Add WidgetRenderinContext source files to the sources list.
     22        * platform/graphics/cairo/PlatformRefPtrCairo.cpp:
     23        (WTF::refPlatformPtr): Add a specialization for Cairo patterns.
     24        (WTF::derefPlatformPtr): Ditto.
     25        * platform/graphics/cairo/PlatformRefPtrCairo.h: Ditto.
     26        * platform/gtk/RenderThemeGtk.cpp:
     27        (WebCore::RenderThemeGtk::RenderThemeGtk): No longer keep a set of
     28        widgets per-colormap for GTK+, instead just determine if we can use RGBA
     29        colormaps and go from there.
     30        (WebCore::RenderThemeGtk::~RenderThemeGtk): Ditto.
     31        (WebCore::RenderThemeGtk::getIndicatorMetrics): Put the logic for
     32        getting toggle button indicator metrics into this helper.
     33        (WebCore::RenderThemeGtk::paintRenderObject): Now uses
     34        WidgetRenderingContext to do widget rendering.
     35        (WebCore::setToggleSize): Use the new getIndicatorMetrics helper.
     36        * platform/gtk/RenderThemeGtk.h: Added a member to track whether or not
     37          the widgets are using a RGBA colormap. Also remove a defunct Page*
     38          member.
     39        * platform/gtk/ScrollbarThemeGtk.cpp: Switch all widget drawing
     40        operations to use WidgetRenderingContext.
     41        (WebCore::ScrollbarThemeGtk::paintTrackBackground): Ditto.
     42        (WebCore::ScrollbarThemeGtk::paintScrollbarBackground): Ditto.
     43        (WebCore::ScrollbarThemeGtk::paintThumb): Ditto.
     44        (WebCore::ScrollbarThemeGtk::paint): Ditto.
     45        (WebCore::ScrollbarThemeGtk::paintButton): Ditto.
     46        * platform/gtk/WidgetRenderingContext.h: Added.
     47        * platform/gtk/WidgetRenderingContextGtk2.cpp: Added.
     48        (WebCore::purgeScratchBuffer): Added, this is similar to the scratch
     49        buffer implementation from ContextShadow.
     50        (WebCore::PurgeScratchBufferTimer::fired): Ditto.
     51        (WebCore::scheduleScratchBufferPurge): Ditto.
     52        (WebCore::getExtraSpaceForWidget):
     53        (WebCore::WidgetRenderingContext::WidgetRenderingContext): Added.
     54        (WebCore::WidgetRenderingContext::~WidgetRenderingContext): Added.
     55        (WebCore::WidgetRenderingContext::paintMozillaWidget): Added.
     56        * platform/gtk/WidgetRenderingContextGtk3.cpp: Added.
     57        (WebCore::WidgetRenderingContext::WidgetRenderingContext): Added.
     58        (WebCore::~WidgetRenderingContext::WidgetRenderingContext): Added.
     59        (WebCore::WidgetRenderingContext::paintMozillaWidget): Added.
     60
    1612010-11-10  Beth Dakin  <bdakin@apple.com>
    262
  • trunk/WebCore/GNUmakefile.am

    r71754 r71791  
    36323632        WebCore/platform/gtk/WheelEventGtk.cpp \
    36333633        WebCore/platform/gtk/WidgetGtk.cpp \
     3634        WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp \
     3635        WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp \
     3636        WebCore/platform/gtk/WidgetRenderingContext.h \
    36343637        WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp \
    36353638        WebCore/platform/image-decoders/bmp/BMPImageDecoder.h \
  • trunk/WebCore/platform/graphics/cairo/RefPtrCairo.cpp

    r71204 r71791  
    7777}
    7878
     79template<> void refIfNotNull(cairo_pattern_t* ptr)
     80{
     81    if (LIKELY(ptr != 0))
     82        cairo_pattern_reference(ptr);
     83}
     84
     85template<> void derefIfNotNull(cairo_pattern_t* ptr)
     86{
     87    if (LIKELY(ptr != 0))
     88        cairo_pattern_destroy(ptr);
     89}
     90
    7991#if defined(USE_FREETYPE)
    8092template<> void refIfNotNull(FcPattern* ptr)
  • trunk/WebCore/platform/graphics/cairo/RefPtrCairo.h

    r71204 r71791  
    2727typedef struct _cairo_font_face cairo_font_face_t;
    2828typedef struct _cairo_scaled_font cairo_scaled_font_t;
     29typedef struct _cairo_pattern cairo_pattern_t;
    2930
    3031#if defined(USE_FREETYPE)
     
    4647template<> void derefIfNotNull(cairo_scaled_font_t* ptr);
    4748
     49template<> void refIfNotNull(cairo_pattern_t*);
     50template<> void derefIfNotNull(cairo_pattern_t*);
     51
    4852#if defined(USE_FREETYPE)
    4953template<> void refIfNotNull(FcPattern* ptr);
  • trunk/WebCore/platform/gtk/RenderThemeGtk.cpp

    r70391 r71791  
    44 * Copyright (C) 2008 Collabora Ltd.
    55 * Copyright (C) 2009 Kenneth Rohde Christiansen
     6 * Copyright (C) 2010 Igalia S.L.
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    4142#include "TimeRanges.h"
    4243#include "UserAgentStyleSheets.h"
     44#include "WidgetRenderingContext.h"
    4345#include "gtkdrawing.h"
    4446#include <gdk/gdk.h>
     
    152154    , m_seekBackButton(0)
    153155    , m_seekForwardButton(0)
    154     , m_partsTable(adoptPlatformRef(g_hash_table_new_full(0, 0, 0, g_free)))
    155 {
     156#ifdef GTK_API_VERSION_2
     157    , m_themePartsHaveRGBAColormap(true)
     158#endif
     159{
     160
     161    memset(&m_themeParts, 0, sizeof(GtkThemeParts));
     162#ifdef GTK_API_VERSION_2
     163    GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default());
     164    if (!colormap) {
     165        m_themePartsHaveRGBAColormap = false;
     166        colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
     167    }
     168    m_themeParts.colormap = colormap;
     169#endif
     170
     171    // Initialize the Mozilla theme drawing code.
    156172    if (!mozGtkRefCount) {
    157173        moz_gtk_init();
    158 
    159         // Use the theme parts for the default drawable.
    160         moz_gtk_use_theme_parts(partsForDrawable(0));
     174        moz_gtk_use_theme_parts(&m_themeParts);
    161175    }
    162 
    163176    ++mozGtkRefCount;
    164177
     
    183196    m_seekForwardButton.clear();
    184197
    185     GList* values = g_hash_table_get_values(m_partsTable.get());
    186     for (guint i = 0; i < g_list_length(values); i++)
    187         moz_gtk_destroy_theme_parts_widgets(
    188             static_cast<GtkThemeParts*>(g_list_nth_data(values, i)));
    189 
    190198    gtk_widget_destroy(m_gtkWindow);
    191199}
    192200
    193 GtkThemeParts* RenderThemeGtk::partsForDrawable(GdkDrawable* drawable) const
    194 {
    195 #ifdef GTK_API_VERSION_2
    196     // A null drawable represents the default screen colormap.
    197     GdkColormap* colormap = 0;
    198     if (!drawable)
    199         colormap = gdk_screen_get_default_colormap(gdk_screen_get_default());
    200     else
    201         colormap = gdk_drawable_get_colormap(drawable);
    202 
    203     GtkThemeParts* parts = static_cast<GtkThemeParts*>(g_hash_table_lookup(m_partsTable.get(), colormap));
    204     if (!parts) {
    205         parts = g_new0(GtkThemeParts, 1);
    206         parts->colormap = colormap;
    207         g_hash_table_insert(m_partsTable.get(), colormap, parts);
     201void RenderThemeGtk::getIndicatorMetrics(ControlPart part, int& indicatorSize, int& indicatorSpacing) const
     202{
     203    ASSERT(part == CheckboxPart || part == RadioPart);
     204    if (part == CheckboxPart) {
     205        moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing);
     206        return;
    208207    }
    209 #else
    210     // For GTK+ 3.0 we no longer have to worry about maintaining a set of widgets per-colormap.
    211     static GtkThemeParts* parts = g_slice_new0(GtkThemeParts);
    212 #endif // GTK_API_VERSION_2
    213 
    214     return parts;
     208
     209    // RadioPart
     210    moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing);
    215211}
    216212
     
    290286}
    291287
    292 #ifdef GTK_API_VERSION_2
    293 bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection)
    294 {
    295     // Painting is disabled so just claim to have succeeded
    296     if (context->paintingDisabled())
    297         return false;
    298 
    299     PlatformRefPtr<GdkDrawable> drawable(context->gdkDrawable());
    300     GdkRectangle paintRect, clipRect;
    301     if (drawable) {
    302         AffineTransform ctm = context->getCTM();
    303         IntPoint pos = ctm.mapPoint(rect.location());
    304         paintRect = IntRect(pos.x(), pos.y(), rect.width(), rect.height());
    305 
    306         // Intersect the cairo rectangle with the target widget region. This  will
    307         // prevent the theme drawing code from drawing into regions that cairo will
    308         // clip anyway.
    309         double clipX1, clipX2, clipY1, clipY2;
    310         cairo_clip_extents(context->platformContext(), &clipX1, &clipY1, &clipX2, &clipY2);
    311         IntPoint clipPos = ctm.mapPoint(IntPoint(clipX1, clipY1));
    312 
    313         clipRect.width = clipX2 - clipX1;
    314         clipRect.height = clipY2 - clipY1;
    315         clipRect.x = clipPos.x();
    316         clipRect.y = clipPos.y();
    317         gdk_rectangle_intersect(&paintRect, &clipRect, &clipRect);
    318 
    319     } else {
    320         // In some situations, like during print previews, this GraphicsContext is not
    321         // backed by a GdkDrawable. In those situations, we render onto a pixmap and then
    322         // copy the rendered data back to the GraphicsContext via Cairo.
    323         drawable = adoptPlatformRef(gdk_pixmap_new(0, rect.width(), rect.height(), gdk_visual_get_depth(gdk_visual_get_system())));
    324         paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height());
    325     }
    326 
    327     moz_gtk_use_theme_parts(partsForDrawable(drawable.get()));
    328     bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, widgetState, flags, textDirection) == MOZ_GTK_SUCCESS;
    329 
    330     // If the drawing was successful and we rendered onto a pixmap, copy the
    331     // results back to the original GraphicsContext.
    332     if (success && !context->gdkDrawable()) {
    333         cairo_t* cairoContext = context->platformContext();
    334         cairo_save(cairoContext);
    335         gdk_cairo_set_source_pixmap(cairoContext, drawable.get(), rect.x(), rect.y());
    336         cairo_paint(cairoContext);
    337         cairo_restore(cairoContext);
    338     }
    339 
    340     return !success;
    341 }
    342 #else
    343 bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection)
    344 {
    345     // Painting is disabled so just claim to have succeeded
    346     if (context->paintingDisabled())
    347         return false;
    348 
    349     // false == success, because of awesome.
    350     GdkRectangle paintRect = rect;
    351     return moz_gtk_widget_paint(type, context->platformContext(), &paintRect, widgetState, flags, textDirection) != MOZ_GTK_SUCCESS;
    352 }
    353 #endif
    354 
    355288bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags)
    356289{
     
    383316        widgetState.depressed = false;
    384317
    385     GtkTextDirection textDirection = gtkTextDirection(renderObject->style()->direction());
    386     return paintMozillaGtkWidget(type, context, rect, &widgetState, flags, textDirection);
     318    WidgetRenderingContext widgetContext(context, rect);
     319    return !widgetContext.paintMozillaWidget(type, &widgetState, flags, gtkTextDirection(renderObject->style()->direction()));
    387320}
    388321
     
    395328    // FIXME: This is probably not correct use of indicatorSize and indicatorSpacing.
    396329    gint indicatorSize, indicatorSpacing;
    397 
    398     switch (appearance) {
    399     case CheckboxPart:
    400         if (moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
    401             return;
    402         break;
    403     case RadioPart:
    404         if (moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing) != MOZ_GTK_SUCCESS)
    405             return;
    406         break;
    407     default:
    408         return;
    409     }
     330    theme->getIndicatorMetrics(appearance, indicatorSize, indicatorSpacing);
    410331
    411332    // Other ports hard-code this to 13, but GTK+ users tend to demand the native look.
     
    615536        gtkPart = MOZ_GTK_SCALE_VERTICAL;
    616537
    617     return paintRenderObject(gtkPart, object, info.context, toRenderBox(object)->absoluteContentBox());
     538    return paintRenderObject(gtkPart, object, info.context, rect);
    618539}
    619540
  • trunk/WebCore/platform/gtk/RenderThemeGtk.h

    r70391 r71791  
    8484#endif
    8585
    86     bool paintMozillaGtkWidget(GtkThemeWidgetType, GraphicsContext*, const IntRect&, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE);
     86    void getIndicatorMetrics(ControlPart, int& indicatorSize, int& indicatorSpacing) const;
    8787
    8888    GtkWidget* gtkScrollbar();
     
    170170
    171171    bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0);
    172     GtkThemeParts* partsForDrawable(GdkDrawable*) const;
    173172
    174173    mutable GtkWidget* m_gtkWindow;
     
    194193    RefPtr<Image> m_seekBackButton;
    195194    RefPtr<Image> m_seekForwardButton;
    196     Page* m_page;
    197     PlatformRefPtr<GHashTable> m_partsTable;
    198 
     195    GtkThemeParts m_themeParts;
     196#ifdef GTK_API_VERSION_2
     197    bool m_themePartsHaveRGBAColormap;
     198#endif
     199    friend class WidgetRenderingContext;
    199200};
    200201
  • trunk/WebCore/platform/gtk/ScrollbarThemeGtk.cpp

    r69119 r71791  
    3131#include "ScrollView.h"
    3232#include "Scrollbar.h"
     33#include "WidgetRenderingContext.h"
    3334#include "gtkdrawing.h"
    3435#include <gtk/gtk.h>
     
    217218
    218219    GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_TRACK_VERTICAL : MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL;
    219     static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, fullScrollbarRect, &state, 0);
     220    WidgetRenderingContext widgetContext(context, fullScrollbarRect);
     221    widgetContext.paintMozillaWidget(type, &state, 0);
    220222}
    221223
     
    225227    GtkWidgetState state;
    226228    IntRect fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
    227     static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLED_WINDOW, context, fullScrollbarRect, &state, 0);
     229    WidgetRenderingContext widgetContext(context, fullScrollbarRect);
     230    widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLED_WINDOW, &state, 0);
    228231}
    229232
     
    241244
    242245    GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
    243     static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, rect, &state, 0);
     246    WidgetRenderingContext widgetContext(context, rect);
     247    widgetContext.paintMozillaWidget(type, &state, 0);
    244248}
    245249
     
    257261bool ScrollbarThemeGtk::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect)
    258262{
     263    if (graphicsContext->paintingDisabled())
     264        return false;
     265
    259266    // Create the ScrollbarControlPartMask based on the damageRect
    260267    ScrollbarControlPartMask scrollMask = NoPart;
     
    349356    }
    350357
    351     static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLBAR_BUTTON, context, rect, &state, flags);
     358    WidgetRenderingContext widgetContext(context, rect);
     359    widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLBAR_BUTTON, &state, flags);
    352360}
    353361
Note: See TracChangeset for help on using the changeset viewer.