Changeset 141303 in webkit


Ignore:
Timestamp:
Jan 30, 2013, 1:09:52 PM (12 years ago)
Author:
pdr@google.com
Message:

Track scale and zoom together when drawing SVG images
https://bugs.webkit.org/show_bug.cgi?id=108108

Reviewed by Tim Horton.

Source/WebCore:

This patch refactors SVGImage::drawSVGToImageBuffer to take a single zoomAndScale parameter
and removes two messy calls to setPageZoomFactor. This patch makes progress towards an
SVG image cache keyed on just container size and scale.

This refactoring is covered by existing tests.

  • loader/cache/CachedImage.cpp:

(WebCore::CachedImage::setContainerSizeForRenderer):
(WebCore::CachedImage::imageSizeForRenderer):

This complex logic has been refactored out of CachedImage and into SVGImageCache.
In addition to the code move, we no longer divide by the zoom factor because the
container size is stored without zoom.

  • svg/graphics/SVGImage.cpp:

(WebCore::SVGImage::drawSVGToImageBuffer):

This method signature has changed to take a FloatSize for the container size and
a combined zoom and scale parameter (zoomAndScale). A FloatSize is needed for the
container size because we now store the container size unzoomed, and in this process
we do not want to lose precision.

The messy setPageZoomFactor calls have also been removed which cleans this function up.

  • svg/graphics/SVGImage.h:
  • svg/graphics/SVGImageCache.cpp:

(WebCore::SVGImageCache::setContainerSizeForRenderer):

This function now stores the container size unzoomed. The container size was changed
to a FloatSize so that precision is not lost.

(WebCore::SVGImageCache::imageSizeForRenderer):

Note that the ImageBuffer size will stay the same. We now store the size as:

containerSize (without zoom) * zoom * scale

Previously this was:

containerSize (with zoom) * scale

(WebCore::SVGImageCache::redraw):
(WebCore::SVGImageCache::lookupOrCreateBitmapImageForRenderer):

  • svg/graphics/SVGImageCache.h:

(WebCore::SVGImageCache::SizeAndScales::SizeAndScales):
(SizeAndScales):
(SVGImageCache):

LayoutTests:

  • platform/chromium/TestExpectations:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r141299 r141303  
     12013-01-30  Philip Rogers  <pdr@google.com>
     2
     3        Track scale and zoom together when drawing SVG images
     4        https://bugs.webkit.org/show_bug.cgi?id=108108
     5
     6        Reviewed by Tim Horton.
     7
     8        * platform/chromium/TestExpectations:
     9
    1102013-01-30  Zan Dobersek  <zdobersek@igalia.com>
    211
  • trunk/LayoutTests/platform/chromium/TestExpectations

    r141286 r141303  
    36543654webkit.org/b/94002 [ Win7 Debug ] inspector/debugger/event-listener-breakpoints.html [ Pass Timeout Failure ]
    36553655
     3656# Requires a rebasline after webkit.org/b/108108
     3657webkit.org/b/108108 svg/zoom/page/zoom-background-images.html [ ImageOnlyFailure Pass ]
     3658webkit.org/b/108108 svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ ImageOnlyFailure Pass ]
     3659webkit.org/b/108108 svg/zoom/page/zoom-svg-as-background-with-relative-size.html [ ImageOnlyFailure Pass ]
     3660webkit.org/b/108108 fast/backgrounds/size/contain-and-cover-zoomed.html [ ImageOnlyFailure Pass ]
     3661
    36563662# Flaky
    36573663webkit.org/b/99389 [ Win ] inspector/debugger/xhr-breakpoints.html [ Pass Failure ]
  • trunk/Source/WebCore/ChangeLog

    r141300 r141303  
     12013-01-30  Philip Rogers  <pdr@google.com>
     2
     3        Track scale and zoom together when drawing SVG images
     4        https://bugs.webkit.org/show_bug.cgi?id=108108
     5
     6        Reviewed by Tim Horton.
     7
     8        This patch refactors SVGImage::drawSVGToImageBuffer to take a single zoomAndScale parameter
     9        and removes two messy calls to setPageZoomFactor. This patch makes progress towards an
     10        SVG image cache keyed on just container size and scale.
     11
     12        This refactoring is covered by existing tests.
     13
     14        * loader/cache/CachedImage.cpp:
     15        (WebCore::CachedImage::setContainerSizeForRenderer):
     16        (WebCore::CachedImage::imageSizeForRenderer):
     17
     18            This complex logic has been refactored out of CachedImage and into SVGImageCache.
     19            In addition to the code move, we no longer divide by the zoom factor because the
     20            container size is stored without zoom.
     21
     22        * svg/graphics/SVGImage.cpp:
     23        (WebCore::SVGImage::drawSVGToImageBuffer):
     24
     25            This method signature has changed to take a FloatSize for the container size and
     26            a combined zoom and scale parameter (zoomAndScale). A FloatSize is needed for the
     27            container size because we now store the container size unzoomed, and in this process
     28            we do not want to lose precision.
     29
     30            The messy setPageZoomFactor calls have also been removed which cleans this function up.
     31
     32        * svg/graphics/SVGImage.h:
     33        * svg/graphics/SVGImageCache.cpp:
     34        (WebCore::SVGImageCache::setContainerSizeForRenderer):
     35
     36            This function now stores the container size unzoomed. The container size was changed
     37            to a FloatSize so that precision is not lost.
     38
     39        (WebCore::SVGImageCache::imageSizeForRenderer):
     40
     41            Note that the ImageBuffer size will stay the same. We now store the size as:
     42                containerSize (without zoom) * zoom * scale
     43            Previously this was:
     44                containerSize (with zoom) * scale
     45
     46        (WebCore::SVGImageCache::redraw):
     47        (WebCore::SVGImageCache::lookupOrCreateBitmapImageForRenderer):
     48        * svg/graphics/SVGImageCache.h:
     49        (WebCore::SVGImageCache::SizeAndScales::SizeAndScales):
     50        (SizeAndScales):
     51        (SVGImageCache):
     52
    1532013-01-30  Benjamin Poulain  <benjamin@webkit.org>
    254
  • trunk/Source/WebCore/loader/cache/CachedImage.cpp

    r140722 r141303  
    226226    }
    227227
    228     m_svgImageCache->setRequestedSizeAndScales(renderer, SVGImageCache::SizeAndScales(containerSize, containerZoom));
     228    m_svgImageCache->setContainerSizeForRenderer(renderer, containerSize, containerZoom);
    229229#else
    230230    UNUSED_PARAM(containerZoom);
     
    268268    if (m_image->isBitmapImage() && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation))
    269269        imageSize = static_cast<BitmapImage*>(m_image.get())->sizeRespectingOrientation();
     270#if ENABLE(SVG)
     271    else if (m_image->isSVGImage()) {
     272        imageSize = m_svgImageCache->imageSizeForRenderer(renderer);
     273    }
     274#endif
    270275    else
    271276        imageSize = m_image->size();
    272 
    273 #if ENABLE(SVG)
    274     if (m_image->isSVGImage()) {
    275         SVGImageCache::SizeAndScales sizeAndScales = m_svgImageCache->requestedSizeAndScales(renderer);
    276         if (!sizeAndScales.size.isEmpty()) {
    277             float scale = sizeAndScales.scale;
    278             if (!scale) {
    279                 Page* page = renderer->document()->page();
    280                 scale = page->deviceScaleFactor() * page->pageScaleFactor();
    281             }
    282 
    283             imageSize.setWidth(scale * sizeAndScales.size.width() / sizeAndScales.zoom);
    284             imageSize.setHeight(scale * sizeAndScales.size.height() / sizeAndScales.zoom);
    285         }
    286     }
    287 #endif
    288277
    289278    if (multiplier == 1.0f)
  • trunk/Source/WebCore/svg/graphics/SVGImage.cpp

    r137011 r141303  
    100100}
    101101
    102 void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, float scale, ShouldClearBuffer shouldClear)
     102void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const FloatSize& size, float zoomAndScale, ShouldClearBuffer shouldClear)
    103103{
    104104    // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds,
     
    131131    frame->view()->beginDisableRepaints();
    132132
    133     renderer->setContainerSize(size);
     133    IntSize containerSize = roundedIntSize(size);
     134    renderer->setContainerSize(containerSize);
    134135    frame->view()->resize(this->size());
    135136
    136     if (zoom != 1)
    137         frame->setPageZoomFactor(zoom);
    138 
    139     // Eventually clear image buffer.
    140     IntRect rect(IntPoint(), size);
    141 
    142     FloatRect scaledRect(rect);
    143     scaledRect.scale(scale);
    144 
     137    FloatSize scaledContainerSize(size);
     138    scaledContainerSize.scale(zoomAndScale);
     139    IntRect destRect = IntRect(IntPoint(), expandedIntSize(scaledContainerSize));
    145140    if (shouldClear == ClearImageBuffer)
    146         buffer->context()->clearRect(enclosingIntRect(scaledRect));
     141        buffer->context()->clearRect(destRect);
    147142
    148143    // Draw SVG on top of ImageBuffer.
    149     draw(buffer->context(), enclosingIntRect(scaledRect), rect, ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal);
    150 
    151     // Reset container size & zoom to initial state. Otherwhise the size() of this
    152     // image would return whatever last size was set by drawSVGToImageBuffer().
    153     if (zoom != 1)
    154         frame->setPageZoomFactor(1);
    155 
    156     // Renderer may have been recreated by frame->setPageZoomFactor(zoom). So fetch it again.
    157     renderer = toRenderSVGRoot(rootElement->renderer());
    158     if (renderer)
    159         renderer->setContainerSize(IntSize());
    160 
    161     frame->view()->resize(this->size());
     144    draw(buffer->context(), destRect, IntRect(IntPoint(), containerSize), ColorSpaceDeviceRGB, CompositeSourceOver, BlendModeNormal);
     145
    162146    if (frame->view()->needsLayout())
    163147        frame->view()->layout();
  • trunk/Source/WebCore/svg/graphics/SVGImage.h

    r137011 r141303  
    5252    };
    5353
    54     void drawSVGToImageBuffer(ImageBuffer*, const IntSize&, float zoom, float scale, ShouldClearBuffer);
     54    void drawSVGToImageBuffer(ImageBuffer*, const FloatSize&, float, ShouldClearBuffer);
    5555    RenderBox* embeddedContentBox() const;
    5656    FrameView* frameView() const;
  • trunk/Source/WebCore/svg/graphics/SVGImageCache.cpp

    r139236 r141303  
    7676}
    7777
    78 void SVGImageCache::setRequestedSizeAndScales(const CachedImageClient* client, const SizeAndScales& sizeAndScales)
     78void SVGImageCache::setContainerSizeForRenderer(const CachedImageClient* client, const IntSize& containerSize, float containerZoom)
    7979{
    8080    ASSERT(client);
    81     ASSERT(!sizeAndScales.size.isEmpty());
    82     m_sizeAndScalesMap.set(client, sizeAndScales);
    83 }
    84 
    85 SVGImageCache::SizeAndScales SVGImageCache::requestedSizeAndScales(const CachedImageClient* client) const
    86 {
    87     if (!client)
    88         return SizeAndScales();
    89     SizeAndScalesMap::const_iterator it = m_sizeAndScalesMap.find(client);
     81    ASSERT(!containerSize.isEmpty());
     82
     83    FloatSize containerSizeWithoutZoom(containerSize);
     84    containerSizeWithoutZoom.scale(1 / containerZoom);
     85    m_sizeAndScalesMap.set(client, SizeAndScales(containerSizeWithoutZoom, containerZoom));
     86}
     87
     88IntSize SVGImageCache::imageSizeForRenderer(const RenderObject* renderer) const
     89{
     90    IntSize imageSize = m_svgImage->size();
     91
     92    if (!renderer)
     93        return imageSize;
     94    SizeAndScalesMap::const_iterator it = m_sizeAndScalesMap.find(renderer);
    9095    if (it == m_sizeAndScalesMap.end())
    91         return SizeAndScales();
    92     return it->value;
     96        return imageSize;
     97
     98    SizeAndScales sizeAndScales = it->value;
     99    if (!sizeAndScales.size.isEmpty()) {
     100        float scale = sizeAndScales.scale;
     101        if (!scale) {
     102            Page* page = renderer->document()->page();
     103            scale = page->deviceScaleFactor() * page->pageScaleFactor();
     104        }
     105
     106        imageSize.setWidth(scale * sizeAndScales.size.width());
     107        imageSize.setHeight(scale * sizeAndScales.size.height());
     108    }
     109    return imageSize;
    93110}
    94111
     
    114131        ASSERT(data.buffer);
    115132        ASSERT(data.image);
    116         m_svgImage->drawSVGToImageBuffer(data.buffer, data.sizeAndScales.size, data.sizeAndScales.zoom, data.sizeAndScales.scale, SVGImage::ClearImageBuffer);
     133        m_svgImage->drawSVGToImageBuffer(data.buffer, data.sizeAndScales.size, data.sizeAndScales.zoom * data.sizeAndScales.scale, SVGImage::ClearImageBuffer);
    117134        data.image = data.buffer->copyImage(CopyBackingStore);
    118135        data.imageNeedsUpdate = false;
     
    151168        return Image::nullImage();
    152169
    153     IntSize size = sizeIt->value.size;
     170    FloatSize size = sizeIt->value.size;
    154171    float zoom = sizeIt->value.zoom;
    155172    float scale = sizeIt->value.scale;
     
    180197
    181198    FloatSize scaledSize(size);
    182     scaledSize.scale(scale);
     199    scaledSize.scale(scale * zoom);
    183200
    184201    // Create and cache new image and image buffer at requested size.
     
    187204        return Image::nullImage();
    188205
    189     m_svgImage->drawSVGToImageBuffer(newBuffer.get(), size, zoom, scale, SVGImage::DontClearImageBuffer);
     206    m_svgImage->drawSVGToImageBuffer(newBuffer.get(), size, scale * zoom, SVGImage::DontClearImageBuffer);
    190207
    191208    RefPtr<Image> newImage = newBuffer->copyImage(CopyBackingStore);
  • trunk/Source/WebCore/svg/graphics/SVGImageCache.h

    r139236 r141303  
    2222
    2323#if ENABLE(SVG)
     24#include "FloatSize.h"
    2425#include "Image.h"
    2526#include "IntSize.h"
     
    5455        }
    5556
    56         SizeAndScales(const IntSize& newSize, float newZoom, float newScale)
     57        SizeAndScales(const FloatSize& newSize, float newZoom, float newScale)
    5758            : size(newSize)
    5859            , zoom(newZoom)
     
    6162        }
    6263
    63         SizeAndScales(const IntSize& newSize, float newZoom)
     64        SizeAndScales(const FloatSize& newSize, float newZoom)
    6465            : size(newSize)
    6566            , zoom(newZoom)
     
    6869        }
    6970
    70         IntSize size;
     71        FloatSize size; // This is the container size without zoom.
    7172        float zoom;
    7273        float scale; // A scale of 0 indicates that the default scale should be used.
     
    7576    void removeClientFromCache(const CachedImageClient*);
    7677
    77     void setRequestedSizeAndScales(const CachedImageClient*, const SizeAndScales&);
    78     SizeAndScales requestedSizeAndScales(const CachedImageClient*) const;
     78    void setContainerSizeForRenderer(const CachedImageClient*, const IntSize&, float);
     79    IntSize imageSizeForRenderer(const RenderObject*) const;
    7980
    8081    Image* lookupOrCreateBitmapImageForRenderer(const RenderObject*);
Note: See TracChangeset for help on using the changeset viewer.