2007-01-17 Eric Seidel <eric@webkit.org>
authoreseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Jan 2007 12:10:06 +0000 (12:10 +0000)
committereseidel <eseidel@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Jan 2007 12:10:06 +0000 (12:10 +0000)
        Reviewed by mitz and rwlbuis.

        SVGs do not work as background images:
        http://bugs.webkit.org/show_bug.cgi?id=12096

        Tests updated:
        - fast/images/svg-as-background.svg: now passes
        - fast/images/svg-as-tiled-background.svg: now passes

        * platform/graphics/BitmapImage.h:
        (WebCore::BitmapImage::nativeImageForCurrentFrame):
        (WebCore::BitmapImage::mayFillWithSolidColor):
        (WebCore::BitmapImage::solidColor):
        * platform/graphics/Image.h:
        (WebCore::Image::mayFillWithSolidColor):
        (WebCore::Image::solidColor):
        (WebCore::Image::nativeImageForCurrentFrame):
        (WebCore::Image::startAnimation):
        * platform/graphics/cg/ImageCG.cpp:
        (WebCore::Image::drawPatternCallback):
        (WebCore::Image::drawPatternCombined):
        (WebCore::caculatePatternScale):
        (WebCore::Image::drawTiled):
        * platform/graphics/cg/PDFDocumentImage.cpp:
        * platform/graphics/cg/PDFDocumentImage.h:
        * platform/graphics/svg/SVGImage.cpp:
        (WebCore::SVGImage::nativeImageForCurrentFrame):
        * platform/graphics/svg/SVGImage.h:

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

13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/images/svg-as-background-expected.checksum
LayoutTests/fast/images/svg-as-background-expected.png
LayoutTests/fast/images/svg-as-tiled-background-expected.checksum
LayoutTests/fast/images/svg-as-tiled-background-expected.png
WebCore/ChangeLog
WebCore/platform/graphics/BitmapImage.h
WebCore/platform/graphics/Image.h
WebCore/platform/graphics/cg/ImageCG.cpp
WebCore/platform/graphics/cg/PDFDocumentImage.cpp
WebCore/platform/graphics/cg/PDFDocumentImage.h
WebCore/platform/graphics/svg/SVGImage.cpp
WebCore/platform/graphics/svg/SVGImage.h

index 0c12e8f..7664c95 100644 (file)
@@ -1,3 +1,15 @@
+2007-01-17  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by mitz and rwlbuis.
+        
+        SVGs don't work as background images.
+        http://bugs.webkit.org/show_bug.cgi?id=12096
+
+        * fast/images/svg-as-background-expected.checksum:
+        * fast/images/svg-as-background-expected.png:
+        * fast/images/svg-as-tiled-background-expected.checksum:
+        * fast/images/svg-as-tiled-background-expected.png:
+
 2007-01-16  Justin Garcia  <justin.garcia@apple.com>
 
         Reviewed by harrison
index 2f9c4fa..3a4f1f7 100644 (file)
@@ -1 +1 @@
-be92d79fabac3aa36ba7972abbf1815a
\ No newline at end of file
+16310588467cfc20d551635abc59b784
\ No newline at end of file
index afe260c..3db2634 100644 (file)
Binary files a/LayoutTests/fast/images/svg-as-background-expected.png and b/LayoutTests/fast/images/svg-as-background-expected.png differ
index 2f9c4fa..3a4f1f7 100644 (file)
@@ -1 +1 @@
-be92d79fabac3aa36ba7972abbf1815a
\ No newline at end of file
+16310588467cfc20d551635abc59b784
\ No newline at end of file
index afe260c..3db2634 100644 (file)
Binary files a/LayoutTests/fast/images/svg-as-tiled-background-expected.png and b/LayoutTests/fast/images/svg-as-tiled-background-expected.png differ
index 89c3fa1..24de32a 100644 (file)
@@ -1,3 +1,34 @@
+2007-01-17  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by mitz and rwlbuis.
+        
+        SVGs do not work as background images:
+        http://bugs.webkit.org/show_bug.cgi?id=12096
+
+        Tests updated:
+        - fast/images/svg-as-background.svg: now passes
+        - fast/images/svg-as-tiled-background.svg: now passes
+
+        * platform/graphics/BitmapImage.h:
+        (WebCore::BitmapImage::nativeImageForCurrentFrame):
+        (WebCore::BitmapImage::mayFillWithSolidColor):
+        (WebCore::BitmapImage::solidColor):
+        * platform/graphics/Image.h:
+        (WebCore::Image::mayFillWithSolidColor):
+        (WebCore::Image::solidColor):
+        (WebCore::Image::nativeImageForCurrentFrame):
+        (WebCore::Image::startAnimation):
+        * platform/graphics/cg/ImageCG.cpp:
+        (WebCore::Image::drawPatternCallback):
+        (WebCore::Image::drawPatternCombined):
+        (WebCore::caculatePatternScale):
+        (WebCore::Image::drawTiled):
+        * platform/graphics/cg/PDFDocumentImage.cpp:
+        * platform/graphics/cg/PDFDocumentImage.h:
+        * platform/graphics/svg/SVGImage.cpp:
+        (WebCore::SVGImage::nativeImageForCurrentFrame):
+        * platform/graphics/svg/SVGImage.h:
+
 2007-01-17  Rob Buis  <buis@kde.org>
 
         Reviewed by Eric
index 337a610..8ae38d3 100644 (file)
@@ -115,12 +115,10 @@ public:
     virtual bool getHBITMAP(HBITMAP);
 #endif
 
-    NativeImagePtr nativeImageForCurrentFrame() { return frameAtIndex(currentFrame()); }
+    virtual NativeImagePtr nativeImageForCurrentFrame() { return frameAtIndex(currentFrame()); }
 
 private:
     virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator);
-    virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator);
-    virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator); 
     
     size_t currentFrame() const { return m_currentFrame; }
     size_t frameCount();
@@ -139,7 +137,7 @@ private:
 
     // Animation.
     bool shouldAnimate();
-    void startAnimation();
+    virtual void startAnimation();
     void advanceAnimation(Timer<BitmapImage>*);
     
     // Handle platform-specific data
@@ -149,8 +147,8 @@ private:
     // Checks to see if the image is a 1x1 solid color.  We optimize these images and just do a fill rect instead.
     void checkForSolidColor();
     
-    bool mayFillWithSolidColor() const { return m_isSolidColor && m_currentFrame == 0; }
-    Color solidColor() const { return m_solidColor; }
+    virtual bool mayFillWithSolidColor() const { return m_isSolidColor && m_currentFrame == 0; }
+    virtual Color solidColor() const { return m_solidColor; }
     
     ImageSource m_source;
     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
index 1eeb981..5197a58 100644 (file)
@@ -39,12 +39,17 @@ class NSImage;
 #endif
 #endif
 
+#if PLATFORM(CG)
+struct CGContext;
+#endif
+
 #if PLATFORM(WIN)
 typedef struct HBITMAP__ *HBITMAP;
 #endif
 
 namespace WebCore {
 
+class AffineTransform;
 class FloatPoint;
 class FloatRect;
 class FloatSize;
@@ -104,8 +109,24 @@ public:
 
 private:
     virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator) = 0;
-    virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator) = 0;
-    virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator) = 0;
+    void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator);
+    void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator);
+    
+    // Supporting tiled drawing
+    virtual bool mayFillWithSolidColor() const { return false; }
+    virtual Color solidColor() const { return Color(); }
+    
+    virtual NativeImagePtr nativeImageForCurrentFrame() { return 0; }
+    
+    virtual void startAnimation() { }
+    
+#if PLATFORM(CG)
+    // These are private to CG.  Ideally they would be only in the .cpp file, but the callback requires access
+    // to the private function nativeImageForCurrentFrame()
+    void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform,
+                     const FloatPoint& phase, CompositeOperator, const FloatRect& destRect);
+    static void drawPatternCallback(void* info, CGContext*);
+#endif
     
     Vector<char> m_data; // The encoded raw data for the image. 
     ImageAnimationObserver* m_animationObserver;
index 0769ad2..6b3c525 100644 (file)
@@ -28,6 +28,7 @@
 
 #if PLATFORM(CG)
 
+#include "AffineTransform.h"
 #include "FloatRect.h"
 #include "GraphicsContext.h"
 #include "PDFDocumentImage.h"
@@ -173,21 +174,25 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const Fl
 
 }
 
-static void drawPattern(void* info, CGContextRef context)
+void Image::drawPatternCallback(void* info, CGContextRef context)
 {
-    BitmapImage* data = (BitmapImage*)info;
+    Image* data = (Image*)info;
     CGImageRef image = data->nativeImageForCurrentFrame();
     float w = CGImageGetWidth(image);
     float h = CGImageGetHeight(image);
-    CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect
-        (0, data->size().height() - h, w, h)), image);    
+    CGContextDrawImage(context, GraphicsContext(context).roundToDevicePixels(FloatRect(0, data->size().height() - h, w, h)), image);
 }
 
-static const CGPatternCallbacks patternCallbacks = { 0, drawPattern, NULL };
-
-
-static inline void drawPattern(GraphicsContext* ctxt, CGPatternRef pattern, CGPoint phase, CompositeOperator op, const FloatRect& destRect)
+void Image::drawPatternCombined(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
+                                const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
 {
+    static const CGPatternCallbacks patternCallbacks = { 0, drawPatternCallback, NULL };
+    CGPatternRef pattern = CGPatternCreate(this, tileRect,
+                                           CGAffineTransform(patternTransform), tileRect.width(), tileRect.height(), 
+                                           kCGPatternTilingConstantSpacing, true, &patternCallbacks);
+    if (!pattern)
+        return;
+    
     CGContextRef context = ctxt->platformContext();
     ctxt->save();
     
@@ -206,12 +211,29 @@ static inline void drawPattern(GraphicsContext* ctxt, CGPatternRef pattern, CGPo
     CGContextFillRect(context, destRect);
     
     ctxt->restore();
+    CGPatternRelease(pattern);
+}
+
+static inline FloatSize caculatePatternScale(const FloatRect& dstRect, const FloatRect& srcRect, Image::TileRule hRule, Image::TileRule vRule)
+{
+    float scaleX = 1.0f, scaleY = 1.0f;
+    
+    if (hRule == Image::StretchTile)
+        scaleX = dstRect.width() / srcRect.width();
+    if (vRule == Image::StretchTile)
+        scaleY = dstRect.height() / srcRect.height();
+    
+    if (hRule == Image::RepeatTile)
+        scaleX = scaleY;
+    if (vRule == Image::RepeatTile)
+        scaleY = scaleX;
+    
+    return FloatSize(scaleX, scaleY);
 }
 
-void BitmapImage::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, CompositeOperator op)
+void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, CompositeOperator op)
 {    
-    CGImageRef image = frameAtIndex(m_currentFrame);
-    if (!image)
+    if (!nativeImageForCurrentFrame())
         return;
     
     if (mayFillWithSolidColor()) {
@@ -222,7 +244,7 @@ void BitmapImage::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, co
     FloatSize intrinsicTileSize = size();
     FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(),
                     scaledTileSize.height() / intrinsicTileSize.height());
-    CGAffineTransform patternTransform = CGAffineTransformMakeScale(scale.width(), scale.height());
+    AffineTransform patternTransform = AffineTransform().scale(scale.width(), scale.height());
 
     FloatRect oneTileRect;
     oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), scaledTileSize.width()) - scaledTileSize.width(), scaledTileSize.width()));
@@ -240,40 +262,16 @@ void BitmapImage::drawTiled(GraphicsContext* ctxt, const FloatRect& destRect, co
         return;
     }
 
-    CGPatternRef pattern = CGPatternCreate(this, CGRectMake(0, 0, intrinsicTileSize.width(), intrinsicTileSize.height()),
-                                           patternTransform, intrinsicTileSize.width(), intrinsicTileSize.height(), 
-                                           kCGPatternTilingConstantSpacing, true, &patternCallbacks);
-    
-    if (pattern) {
-        drawPattern(ctxt, pattern, oneTileRect.location(), op, destRect);
-        CGPatternRelease(pattern);
-    }
+    FloatRect tileRect(FloatPoint(), intrinsicTileSize);    
+    drawPatternCombined(ctxt, tileRect, patternTransform, oneTileRect.location(), op, destRect);
     
     startAnimation();
 }
 
-static inline FloatSize caculatePatternScale(const FloatRect& dstRect, const FloatRect& srcRect, Image::TileRule hRule, Image::TileRule vRule)
-{
-    float scaleX = 1.0f, scaleY = 1.0f;
-    
-    if (hRule == Image::StretchTile)
-        scaleX = dstRect.width() / srcRect.width();
-    if (vRule == Image::StretchTile)
-        scaleY = dstRect.height() / srcRect.height();
-    
-    if (hRule == Image::RepeatTile)
-        scaleX = scaleY;
-    if (vRule == Image::RepeatTile)
-        scaleY = scaleX;
-    
-    return FloatSize(scaleX, scaleY);
-}
-
 // FIXME: Merge with the other drawTiled eventually, since we need a combination of both for some things.
-void BitmapImage::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator op)
+void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator op)
 {    
-    CGImageRef image = frameAtIndex(m_currentFrame);
-    if (!image)
+    if (!nativeImageForCurrentFrame())
         return;
 
     if (mayFillWithSolidColor()) {
@@ -281,25 +279,20 @@ void BitmapImage::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, con
         return;
     }
     
-    // Optimization: Cache the CGPatternRef
     FloatSize scale = caculatePatternScale(dstRect, srcRect, hRule, vRule);
-    CGPatternRef pattern = CGPatternCreate(this, srcRect, CGAffineTransformMakeScale(scale.width(), scale.height()),
-                                           srcRect.width(), srcRect.height(),
-                                           kCGPatternTilingConstantSpacing, true, &patternCallbacks);
-    if (pattern) {    
-        // We want to construct the phase such that the pattern is centered (when stretch is not
-        // set for a particular rule).
-        float hPhase = scale.width() * srcRect.x();
-        float vPhase = scale.height() * (srcRect.height() - srcRect.y());
-        if (hRule == Image::RepeatTile)
-            hPhase -= fmodf(dstRect.width(), scale.width() * srcRect.width()) / 2.0f;
-        if (vRule == Image::RepeatTile)
-            vPhase -= fmodf(dstRect.height(), scale.height() * srcRect.height()) / 2.0f;
-        
-        CGPoint patternPhase = CGPointMake(dstRect.x() - hPhase, dstRect.y() - vPhase);
-        drawPattern(ctxt, pattern, patternPhase, op, dstRect);
-        CGPatternRelease(pattern);
-    }
+    AffineTransform patternTransform = AffineTransform().scale(scale.width(), scale.height());
+
+    // We want to construct the phase such that the pattern is centered (when stretch is not
+    // set for a particular rule).
+    float hPhase = scale.width() * srcRect.x();
+    float vPhase = scale.height() * (srcRect.height() - srcRect.y());
+    if (hRule == Image::RepeatTile)
+        hPhase -= fmodf(dstRect.width(), scale.width() * srcRect.width()) / 2.0f;
+    if (vRule == Image::RepeatTile)
+        vPhase -= fmodf(dstRect.height(), scale.height() * srcRect.height()) / 2.0f;
+    FloatPoint patternPhase(dstRect.x() - hPhase, dstRect.y() - vPhase);
+    
+    drawPatternCombined(ctxt, srcRect, patternTransform, patternPhase, op, dstRect);
 
     startAnimation();
 }
index cb8364b..7e9f896 100644 (file)
@@ -153,16 +153,6 @@ void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect,
     context->restore();
 }
 
-void PDFDocumentImage::drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator)
-{
-    // FIXME: implement to support background images
-}
-
-void PDFDocumentImage::drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator)
-{
-    // FIXME: implement to support background images
-}
-
 }
 
 #endif // PLATFORM(CG)
index 9f96ab0..5bec1bf 100644 (file)
@@ -47,8 +47,6 @@ namespace WebCore {
 
     private:
         virtual void draw(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator);
-        virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator);
-        virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator);
         
         void setCurrentPage(int);
         int pageCount() const;
index 9b6e8a6..ddfe985 100644 (file)
@@ -102,14 +102,16 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl
     context->restore();
 }
 
-void SVGImage::drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator)
+NativeImagePtr SVGImage::nativeImageForCurrentFrame()
 {
-    // FIXME: implement to support background images
-}
-
-void SVGImage::drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator)
-{
-    // FIXME: implement to support background images
+    // FIXME: In order to support dynamic SVGs we need to have a way to invalidate this
+    // frame cache, or better yet, not use a cache for tiled drawing at all, instead
+    // having a tiled drawing callback (hopefully non-virtual).
+    if (!m_frameCache) {
+        m_frameCache.set(ImageBuffer::create(size(), false).release());
+        ImageBuffer::renderSubtreeToImage(m_frameCache.get(), m_frame->renderer());
+    }
+    return m_frameCache->cgImage();
 }
 
 bool SVGImage::setData(bool allDataReceived)
index 6533cec..6f7b127 100644 (file)
@@ -29,6 +29,7 @@
 #ifdef SVG_SUPPORT
 
 #include "Image.h"
+#include "ImageBuffer.h"
 #include "IntSize.h"
 #include <wtf/OwnPtr.h>
 
@@ -52,14 +53,15 @@ namespace WebCore {
         
 private:
         virtual void draw(GraphicsContext*, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator);
-        virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatPoint& srcPoint, const FloatSize& tileSize, CompositeOperator);
-        virtual void drawTiled(GraphicsContext*, const FloatRect& dstRect, const FloatRect& srcRect, TileRule hRule, TileRule vRule, CompositeOperator);
+        
+        virtual NativeImagePtr nativeImageForCurrentFrame();
         
         SVGDocument* m_document;
         OwnPtr<Page> m_page;
         RefPtr<Frame> m_frame;
         RefPtr<FrameView> m_frameView;
         IntSize m_minSize;
+        OwnPtr<ImageBuffer> m_frameCache;
     };
 }