2007-12-23 Alp Toker <alp@atoker.com>
authoralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Dec 2007 00:47:05 +0000 (00:47 +0000)
committeralp@webkit.org <alp@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Dec 2007 00:47:05 +0000 (00:47 +0000)
        Reviewed by Holger Freyther.

        http://bugs.webkit.org/show_bug.cgi?id=16577
        Merge Cairo enhancements from Apollo project

        This patch is based on initial merging work by Brent Fulgham. Adobe's
        code has been modified in a few places to better suit the existing
        coding style.

        Implement more clipping and drawing functions.

        Save and restore the fill rule manually when clipping.

        Avoid image surface creation when the image buffer has height zero.

        * platform/graphics/cairo/GraphicsContextCairo.cpp:
        (WebCore::GraphicsContext::clip):
        (WebCore::GraphicsContext::addInnerRoundedRectClip):
        (WebCore::GraphicsContext::addPath):
        (WebCore::GraphicsContext::clipOut):
        (WebCore::GraphicsContext::clipOutEllipseInRect):
        (WebCore::GraphicsContext::fillRoundedRect):
        * platform/graphics/cairo/ImageSourceCairo.cpp:
        (WebCore::ImageSource::createFrameAtIndex):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28969 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
WebCore/platform/graphics/cairo/ImageSourceCairo.cpp

index 95377e1d55f9b26222eed97eacaca3fcafab4249..b5b7cdd648a099d13fdff78319d8b295f49e30f4 100644 (file)
@@ -1,3 +1,30 @@
+2007-12-23  Alp Toker  <alp@atoker.com>
+
+        Reviewed by Holger Freyther.
+
+        http://bugs.webkit.org/show_bug.cgi?id=16577
+        Merge Cairo enhancements from Apollo project
+
+        This patch is based on initial merging work by Brent Fulgham. Adobe's
+        code has been modified in a few places to better suit the existing
+        coding style.
+
+        Implement more clipping and drawing functions.
+
+        Save and restore the fill rule manually when clipping.
+
+        Avoid image surface creation when the image buffer has height zero.
+
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::addInnerRoundedRectClip):
+        (WebCore::GraphicsContext::addPath):
+        (WebCore::GraphicsContext::clipOut):
+        (WebCore::GraphicsContext::clipOutEllipseInRect):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        * platform/graphics/cairo/ImageSourceCairo.cpp:
+        (WebCore::ImageSource::createFrameAtIndex):
+
 2007-12-23  Nikolas Zimmermann  <zimmermann@kde.org>
 
         Reviewed by Mark.
index 29365c3755ea04216fa675a342d3a7ec806644ca..19a566f4b41499b03f32cbbcc1435f5f33fcac75 100644 (file)
@@ -409,7 +409,10 @@ void GraphicsContext::clip(const IntRect& rect)
 
     cairo_t* cr = m_data->cr;
     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
+    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
+    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
     cairo_clip(cr);
+    cairo_set_fill_rule(cr, savedFillRule);
 }
 
 void GraphicsContext::drawFocusRing(const Color& color)
@@ -603,20 +606,24 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
         return;
 
     clip(rect);
-    Path path;
 
-    path.addEllipse(rect);
-
-    IntRect inner(rect);
-    inner.inflate(-thickness);
-    path.addEllipse(inner);
+    Path p;
+    FloatRect r(rect);
+    // Add outer ellipse
+    p.addEllipse(r);
+    // Add inner ellipse
+    r.inflate(-thickness);
+    p.addEllipse(r);
+    addPath(p);
 
     cairo_t* cr = m_data->cr;
+    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
-
-    clip(path);
+    cairo_clip(cr);
+    cairo_set_fill_rule(cr, savedFillRule);
 }
 
+
 void GraphicsContext::setShadow(IntSize const&, int, Color const&)
 {
     notImplemented();
@@ -790,7 +797,7 @@ void GraphicsContext::addPath(const Path& path)
         return;
 
     cairo_t* cr = m_data->cr;
-    cairo_path_t *p = cairo_copy_path(path.platformPath()->m_cr);
+    cairo_path_tp = cairo_copy_path(path.platformPath()->m_cr);
     cairo_append_path(cr, p);
     cairo_path_destroy(p);
 }
@@ -801,15 +808,30 @@ void GraphicsContext::clip(const Path& path)
         return;
 
     cairo_t* cr = m_data->cr;
-    cairo_path_t *p = cairo_copy_path(path.platformPath()->m_cr);
+    cairo_path_tp = cairo_copy_path(path.platformPath()->m_cr);
     cairo_append_path(cr, p);
     cairo_path_destroy(p);
+    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
+    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
     cairo_clip(cr);
+    cairo_set_fill_rule(cr, savedFillRule);
 }
 
-void GraphicsContext::clipOut(const Path&)
+void GraphicsContext::clipOut(const Path& path)
 {
-    notImplemented();
+    if (paintingDisabled())
+        return;
+
+    cairo_t* cr = m_data->cr;
+    double x1, y1, x2, y2;
+    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
+    addPath(path);
+
+    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
+    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+    cairo_clip(cr);
+    cairo_set_fill_rule(cr, savedFillRule);
 }
 
 void GraphicsContext::rotate(float radians)
@@ -828,19 +850,44 @@ void GraphicsContext::scale(const FloatSize& size)
     cairo_scale(m_data->cr, size.width(), size.height());
 }
 
-void GraphicsContext::clipOut(const IntRect&)
+void GraphicsContext::clipOut(const IntRect& r)
 {
-    notImplemented();
+    if (paintingDisabled())
+        return;
+
+    cairo_t* cr = m_data->cr;
+    double x1, y1, x2, y2;
+    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+    cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1);
+    cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
+    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
+    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
+    cairo_clip(cr);
+    cairo_set_fill_rule(cr, savedFillRule);
 }
 
-void GraphicsContext::clipOutEllipseInRect(const IntRect&)
+void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
 {
-    notImplemented();
+    if (paintingDisabled())
+        return;
+
+    Path p;
+    p.addEllipse(r);
+    clipOut(p);
 }
 
-void GraphicsContext::fillRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color&)
+void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
 {
-    notImplemented();
+    if (paintingDisabled())
+        return;
+
+    cairo_t* cr = m_data->cr;
+    cairo_save(cr);
+    beginPath();
+    addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
+    setColor(cr, color);
+    cairo_fill(cr);
+    cairo_restore(cr);
 }
 
 #if PLATFORM(GTK)
index 84c1c12096e8c9a5fd0e8ad528694896b2e6e3af..36dfc9dfff26ed6418b191a06d35dc1d9f79d2df 100644 (file)
@@ -159,6 +159,11 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
     if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty)
         return 0;
 
+    // Cairo does not like zero height images.
+    // If we have a zero height image, just pretend we don't have enough data yet.
+    if (!buffer->height())
+        return 0;
+
     return cairo_image_surface_create_for_data((unsigned char*)buffer->bytes().data(),
                                                CAIRO_FORMAT_ARGB32,
                                                size().width(),