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

        http://bugs.webkit.org/show_bug.cgi?id=15382
        [CAIRO] Canvas pattern support

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

        Add support for canvas patterns.

        Make Image::nativeImageForCurrentFrame() public.

        Fix some typos along the way.

        The globalAlpha canvas fixes are not included in this patch as
        they're slightly more intrusive and may conflict conceptually with
        GraphicsContext::setAlpha().

        * html/CanvasPattern.cpp:
        (WebCore::CanvasPattern::CanvasPattern):
        (WebCore::CanvasPattern::~CanvasPattern):
        (WebCore::CanvasPattern::createPattern):
        * html/CanvasPattern.h:
        (WebCore::CanvasPattern::platformImage):
        * html/CanvasRenderingContext2D.cpp:
        (WebCore::CanvasRenderingContext2D::setShadow):
        (WebCore::CanvasRenderingContext2D::applyShadow):
        (WebCore::CanvasRenderingContext2D::drawImage):
        (WebCore::CanvasRenderingContext2D::createPattern):
        (WebCore::CanvasRenderingContext2D::applyStrokePattern):
        (WebCore::CanvasRenderingContext2D::applyFillPattern):
        * platform/graphics/Image.h:
        (WebCore::Image::nativeImageForCurrentFrame):

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

WebCore/ChangeLog
WebCore/html/CanvasPattern.cpp
WebCore/html/CanvasPattern.h
WebCore/html/CanvasRenderingContext2D.cpp
WebCore/platform/graphics/Image.h

index c4321c63707f56e24590ccf493207507d43e391e..c21484ff10302a08d25637a680e1fea5285ee5ca 100644 (file)
@@ -1,3 +1,39 @@
+2007-12-23  Alp Toker  <alp@atoker.com>
+
+        Reviewed by Holger Freyther.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15382
+        [CAIRO] Canvas pattern support
+
+        http://bugs.webkit.org/show_bug.cgi?id=16577
+        Merge Cairo enhancements from Apollo project
+
+        Add support for canvas patterns.
+
+        Make Image::nativeImageForCurrentFrame() public.
+
+        Fix some typos along the way.
+
+        The globalAlpha canvas fixes are not included in this patch as
+        they're slightly more intrusive and may conflict conceptually with
+        GraphicsContext::setAlpha().
+
+        * html/CanvasPattern.cpp:
+        (WebCore::CanvasPattern::CanvasPattern):
+        (WebCore::CanvasPattern::~CanvasPattern):
+        (WebCore::CanvasPattern::createPattern):
+        * html/CanvasPattern.h:
+        (WebCore::CanvasPattern::platformImage):
+        * html/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setShadow):
+        (WebCore::CanvasRenderingContext2D::applyShadow):
+        (WebCore::CanvasRenderingContext2D::drawImage):
+        (WebCore::CanvasRenderingContext2D::createPattern):
+        (WebCore::CanvasRenderingContext2D::applyStrokePattern):
+        (WebCore::CanvasRenderingContext2D::applyFillPattern):
+        * platform/graphics/Image.h:
+        (WebCore::Image::nativeImageForCurrentFrame):
+
 2007-12-23  Kevin Ollivier  <kevino@theolliviers.com>
 
         Reviewed by Eric Seidel.
index ae0dfc7d2b4fa135fd7b84158d2d5411ee4bab2f..3d17c76df196bf650e07d01206a47580a60c0dbc 100644 (file)
@@ -73,11 +73,21 @@ CanvasPattern::CanvasPattern(CGImageRef image, bool repeatX, bool repeatY)
 {
 }
 
+#elif PLATFORM(CAIRO)
+
+CanvasPattern::CanvasPattern(cairo_surface_t* surface, bool repeatX, bool repeatY)
+    : m_platformImage(surface)
+    , m_cachedImage(0)
+    , m_repeatX(repeatX)
+    , m_repeatY(repeatY)
+{
+}
+
 #endif
 
 CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeatY)
     :
-#if PLATFORM(CG)
+#if PLATFORM(CG) || PLATFORM(CAIRO)
       m_platformImage(0)
     ,
 #endif
@@ -91,6 +101,10 @@ CanvasPattern::CanvasPattern(CachedImage* cachedImage, bool repeatX, bool repeat
 
 CanvasPattern::~CanvasPattern()
 {
+#if PLATFORM(CAIRO)
+    if (m_platformImage)
+        cairo_surface_destroy(m_platformImage);
+#endif
     if (m_cachedImage)
         m_cachedImage->deref(this);
 }
@@ -168,6 +182,32 @@ CGPatternRef CanvasPattern::createPattern(const CGAffineTransform& transform)
         kCGPatternTilingConstantSpacing, TRUE, &patternCallbacks);
 }
 
+#elif PLATFORM(CAIRO)
+
+cairo_pattern_t* CanvasPattern::createPattern(const cairo_matrix_t& m)
+{
+    cairo_surface_t* surface = 0;
+    if (m_platformImage) {
+        surface = m_platformImage;
+    } else {
+        if (!m_cachedImage)
+            return 0;
+        Image* image = m_cachedImage->image();
+        if (!image)
+            return 0;
+        surface = image->nativeImageForCurrentFrame();
+    }
+
+    if (!surface)
+        return 0;
+
+    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface);
+    cairo_pattern_set_matrix(pattern, &m);
+    if (m_repeatX || m_repeatY)
+        cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+    return pattern;
+}
+
 #endif
 
 }
index d384d9308290f61d8b291ab779c18068270c2a48..4990776993052ec22744f3229d9b953d8e1bd9d9 100644 (file)
@@ -32,6 +32,8 @@
 #if PLATFORM(CG)
 #include <wtf/RetainPtr.h>
 #include <ApplicationServices/ApplicationServices.h>
+#elif PLATFORM(CAIRO)
+#include <cairo.h>
 #endif
 
 namespace WebCore {
@@ -47,22 +49,30 @@ namespace WebCore {
 
 #if PLATFORM(CG)
         CanvasPattern(CGImageRef, bool repeatX, bool repeatY);
+#elif PLATFORM(CAIRO)
+        CanvasPattern(cairo_surface_t*, bool repeatX, bool repeatY);
 #endif
         CanvasPattern(CachedImage*, bool repeatX, bool repeatY);
         ~CanvasPattern();
 
 #if PLATFORM(CG)
         CGImageRef platformImage() const { return m_platformImage.get(); }
+#elif PLATFORM(CAIRO)
+        cairo_surface_t* platformImage() const { return m_platformImage; }
 #endif
         CachedImage* cachedImage() const { return m_cachedImage; }
 
 #if PLATFORM(CG)
         CGPatternRef createPattern(const CGAffineTransform&);
+#elif PLATFORM(CAIRO)
+        cairo_pattern_t* createPattern(const cairo_matrix_t&);
 #endif
 
     private:
 #if PLATFORM(CG)
         const RetainPtr<CGImageRef> m_platformImage;
+#elif PLATFORM(CAIRO)
+        cairo_surface_t* const m_platformImage;
 #endif
         CachedImage* const m_cachedImage;
         const bool m_repeatX;
index f7b0833dbb09b43ef141574470eb849df4f9e9ac..b89297f5c5da22c8451b9c61f0c6327a46f2dc92 100644 (file)
@@ -725,7 +725,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
         return;
     // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
-    RGBA32 rgba = 0; // default is transparant black
+    RGBA32 rgba = 0; // default is transparent black
     CSSParser::parseColor(rgba, color);
     const CGFloat components[4] = {
         ((rgba >> 16) & 0xFF) / 255.0f,
@@ -816,7 +816,7 @@ void CanvasRenderingContext2D::applyShadow()
         return;
     // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
-    RGBA32 rgba = 0; // default is transparant black
+    RGBA32 rgba = 0; // default is transparent black
     if (!state().m_shadowColor.isEmpty())
         CSSParser::parseColor(rgba, state().m_shadowColor);
     const CGFloat components[4] = {
@@ -977,21 +977,13 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatR
     if (!image)
         return;
     willDraw(dstRect);
-
-    float iw = cairo_image_surface_get_width(image);
-    float ih = cairo_image_surface_get_height(image);
-
-    if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) {
-        cairo_t* cr = c->platformContext();
-        cairo_save(cr);
-        cairo_set_source_surface(cr, image, srcRect.x(), srcRect.y());
-        cairo_surface_destroy(image);
-        cairo_rectangle(cr, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height());
-        cairo_fill(cr);
-        cairo_restore(cr);
-    } else
-        notImplemented();
-
+    cairo_t* cr = c->platformContext();
+    cairo_save(cr);
+    cairo_set_source_surface(cr, image, srcRect.x(), srcRect.y());
+    cairo_surface_destroy(image);
+    cairo_rectangle(cr, dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height());
+    cairo_fill(cr);
+    cairo_restore(cr);
 #endif
 }
 
@@ -1068,6 +1060,13 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElem
     PassRefPtr<CanvasPattern> pattern = new CanvasPattern(image, repeatX, repeatY);
     CGImageRelease(image);
     return pattern;
+#elif PLATFORM(CAIRO)
+    cairo_surface_t* surface = canvas->createPlatformImage();
+    if (!surface)
+        return 0;
+    PassRefPtr<CanvasPattern> pattern = new CanvasPattern(surface, repeatX, repeatY);
+    cairo_surface_destroy(surface);
+    return pattern;
 #else
     notImplemented();
     return 0;
@@ -1121,7 +1120,20 @@ void CanvasRenderingContext2D::applyStrokePattern()
 #elif PLATFORM(QT)
     fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyStrokePattern\n");
 #elif PLATFORM(CAIRO)
-    notImplemented();
+    CanvasPattern* pattern = state().m_strokeStyle->pattern();
+    if (!pattern)
+        return;
+
+    cairo_t* cr = c->platformContext();
+    cairo_matrix_t m;
+    cairo_get_matrix(cr, &m);
+
+    cairo_pattern_t* platformPattern = pattern->createPattern(m);
+    if (!platformPattern)
+        return;
+
+    cairo_set_source(cr, platformPattern);
+    cairo_pattern_destroy(platformPattern);
 #endif
     state().m_appliedStrokePattern = true;
 }
@@ -1158,6 +1170,21 @@ void CanvasRenderingContext2D::applyFillPattern()
     state().m_fillStylePatternTransform = m;
 #elif PLATFORM(QT)
     fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyFillPattern\n");
+#elif PLATFORM(CAIRO)
+    CanvasPattern* pattern = state().m_fillStyle->pattern();
+    if (!pattern)
+        return;
+
+    cairo_t* cr = c->platformContext();
+    cairo_matrix_t m;
+    cairo_get_matrix(cr, &m);
+
+    cairo_pattern_t* platformPattern = pattern->createPattern(m);
+    if (!platformPattern)
+        return;
+
+    cairo_set_source(cr, platformPattern);
+    cairo_pattern_destroy(platformPattern);
 #endif
     state().m_appliedFillPattern = true;
 }
index db3a2b5f6c4f246fa5f201f70dfc9f897ef1b7d7..6ffe163ab8020cbf91b98e07dfca5e0b211299e6 100644 (file)
@@ -111,6 +111,8 @@ public:
     ImageObserver* imageObserver() const { return m_imageObserver; }
 
     enum TileRule { StretchTile, RoundTile, RepeatTile };
+
+    virtual NativeImagePtr nativeImageForCurrentFrame() { return 0; }
     
 #if PLATFORM(MAC)
     // Accessors for native image formats.
@@ -146,8 +148,6 @@ private:
     virtual bool mayFillWithSolidColor() const { return false; }
     virtual Color solidColor() const { return Color(); }
     
-    virtual NativeImagePtr nativeImageForCurrentFrame() { return 0; }
-    
     virtual void startAnimation() { }
     
     virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,