Changeset 99539 in webkit


Ignore:
Timestamp:
Nov 8, 2011 1:32:52 AM (12 years ago)
Author:
Nikolas Zimmermann
Message:

2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com>

Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
https://bugs.webkit.org/show_bug.cgi?id=71368

Reviewed by Antti Koivisto.

Add some layout tests covering repainting of embedded SVG documents triggered by SMIL animations.

  • platform/chromium/test_expectations.txt: Fix test expectations, as described in bug 71226.
  • platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.png: Added.
  • platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.txt: Added.
  • platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.png: Added.
  • platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.txt: Added.
  • svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html: Added.
  • svg/as-image/animated-svg-as-image-same-image.html: Added.
  • svg/as-image/resources/animated-rect-same-image.svg: Copied from LayoutTests/svg/as-image/resources/animated-rect-fixed-size.svg.
  • svg/zoom/page/zoom-coords-viewattr-01-b.svg: Add comment, why scrollbars shouldn't appear anymore here.

2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com>

Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
https://bugs.webkit.org/show_bug.cgi?id=71368

Reviewed by Antti Koivisto.

Fix regressions/races introduced by r98852. SVGImage repainting didn't work under certain circumstances.
The problem was hard to reproduce on Mac ports, but easily visible on Chromium, when opening two files
that shared the same animated SVG image. The problem of sharing a single ImageObserver across multiple
instances of the same SVGImage, leads to nasty problems, that are timing dependant. changedInRect() calls
that should only by received in one document, are received in the other as well, due the shared nature
of CachedImage. To avoid these problems alltogether, a new approach is needed, that was initially suggested
by Antti.

Avoid creating multiple SVGImages and caching them for different sizes/zoom levels. Introduce SVGImageCache
which holds rendered versions of the SVGImage at certain sizes/zoom levels. It holds (ImageBuffer, Image) pairs
for each renderer, associated with a size and zoom level.

This is a major change to the cache as introduced some weeks ago. Instead of holding multiple SVGImages, each containing
a whole DOM/render tree, we now create bitmap images rendered at the requested sizes/zoom levels and cache them.

Revert ImageBySizeCache changes that were needed to make it usable wih SVGImage. Its now used only in CSSImageGeneratorValue and
thus the extra information that CSSImageGeneratorValue doesn't need can be removed again (desired/actual size differentations, and the zoom level).

Tests: svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html

svg/as-image/animated-svg-as-image-same-image.html

  • CMakeLists.txt: Add svg/graphics/SVGImageCache.* to build.
  • GNUmakefile.list.am: Ditto.
  • Target.pri: Ditto.
  • WebCore.gypi: Ditto.
  • WebCore.vcproj/WebCore.vcproj: Ditto.
  • WebCore.vcproj/copyForwardingHeaders.cmd: Copy headers from svg/graphics, as SVGImageCache is needed by CachedImage in SVG enabled builds.
  • WebCore.xcodeproj/project.pbxproj: Add svg/graphics/SVGImageCache.* to build.
  • css/CSSImageGeneratorValue.cpp: Remove zoom parameter from addClient/getImage, no need to pass 1 default values anymore. (WebCore::CSSImageGeneratorValue::addClient): (WebCore::CSSImageGeneratorValue::getImage):
  • loader/cache/CachedImage.cpp: Stop using ImageBySizeCache, and switch to the new SVGImageCache. (WebCore::CachedImage::removeClientForRenderer): (WebCore::CachedImage::lookupOrCreateImageForRenderer): (WebCore::CachedImage::setContainerSizeForRenderer): (WebCore::CachedImage::imageSizeForRenderer): (WebCore::CachedImage::clear): (WebCore::CachedImage::createImage): (WebCore::CachedImage::destroyDecodedData): (WebCore::CachedImage::decodedSizeChanged): (WebCore::CachedImage::didDraw): (WebCore::CachedImage::shouldPauseAnimation): (WebCore::CachedImage::animationAdvanced): (WebCore::CachedImage::changedInRect):
  • loader/cache/CachedImage.h:
  • page/DragController.cpp: Stop using imageForRenderer(), as it may return cached BitmapImages, that don't carry a filename extension anymore, which is required here. (WebCore::getImage):
  • rendering/ImageBySizeCache.cpp: Revert changes to ImageBySizeCache, which were needed to make it usable for SVGImages. CSSImageGenerator doesn't need it. (WebCore::ImageBySizeCache::addClient): (WebCore::ImageBySizeCache::removeClient): (WebCore::ImageBySizeCache::getImage):
  • rendering/ImageBySizeCache.h: Ditto. (WebCore::SizeAndCount::SizeAndCount):
  • rendering/RenderImage.cpp: Stop using imageForRenderer(), use cachedImage()->image(), which is guaranteed to be a SVGImage for svg images, and not a cached bitmap copy. (WebCore::RenderImage::embeddedContentBox):
  • rendering/RenderReplaced.cpp: Simplify logic to figure out the intrinsic size - the special logic for the old SVGImage cache can go away now. (WebCore::RenderReplaced::computeIntrinsicLogicalWidth): (WebCore::RenderReplaced::computeIntrinsicLogicalHeight):
  • rendering/style/StyleCachedImage.cpp: Call removeClientForRenderer(), which takes care of clearing SVGImageCache entries as well. (WebCore::StyleCachedImage::removeClient): This change is needed, as we don't want to make removeClient() virtual in CachedResource.
  • rendering/svg/RenderSVGRoot.cpp: Rename isEmbeddedThroughImageElement to isEmbeddedThroughSVGImage, as this is what it actually checks. (WebCore::RenderSVGRoot::isEmbeddedThroughSVGImage):
  • rendering/svg/RenderSVGRoot.h:
  • svg/SVGSVGElement.cpp: Fix bug that's visible now with the SVGImageCache, which was already there before, but hard to trigger. (WebCore::SVGSVGElement::currentViewBoxRect): The viewBox depends on who's asking for it: the host document or the embedded document? Take that into account.
  • svg/SVGSVGElement.h:
  • svg/graphics/SVGImage.cpp: Cleanup some code. Add new logic that draws a SVGImage into an ImageBuffer at a desired size & zoom. (WebCore::SVGImage::setContainerSize): (WebCore::SVGImage::size): (WebCore::SVGImage::drawSVGToImageBuffer):
  • svg/graphics/SVGImage.h:
  • svg/graphics/SVGImageCache.cpp: Added. SVGImageCache caches Image/ImageBuffer pairs for each _renderer_ and size/zoom level. The ImageBySizeCache only cared about size. (WebCore::SVGImageCache::SVGImageCache): (WebCore::SVGImageCache::~SVGImageCache): (WebCore::SVGImageCache::removeRendererFromCache): (WebCore::SVGImageCache::setRequestedSizeAndZoom): (WebCore::SVGImageCache::getRequestedSizeAndZoom): (WebCore::SVGImageCache::imageContentChanged): (WebCore::SVGImageCache::redrawTimerFired): (WebCore::SVGImageCache::lookupOrCreateBitmapImageForRenderer):
  • svg/graphics/SVGImageCache.h: Added. (WebCore::SVGImageCache::create): (WebCore::SVGImageCache::CachedSizeAndZoom::CachedSizeAndZoom): (WebCore::SVGImageCache::CachedImageData::CachedImageData):

2011-11-08 Nikolas Zimmermann <nzimmermann@rim.com>

Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
https://bugs.webkit.org/show_bug.cgi?id=71368

Reviewed by Antti Koivisto.

  • CMakeLists.txt: Add svg/graphics include, for SVGImageCache.h.
Location:
trunk
Files:
8 added
28 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r99538 r99539  
     12011-11-08  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
     4        https://bugs.webkit.org/show_bug.cgi?id=71368
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add some layout tests covering repainting of embedded SVG documents triggered by SMIL animations.
     9
     10        * platform/chromium/test_expectations.txt: Fix test expectations, as described in bug 71226.
     11        * platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.png: Added.
     12        * platform/mac/svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size-expected.txt: Added.
     13        * platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.png: Added.
     14        * platform/mac/svg/as-image/animated-svg-as-image-same-image-expected.txt: Added.
     15        * svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html: Added.
     16        * svg/as-image/animated-svg-as-image-same-image.html: Added.
     17        * svg/as-image/resources/animated-rect-same-image.svg: Copied from LayoutTests/svg/as-image/resources/animated-rect-fixed-size.svg.
     18        * svg/zoom/page/zoom-coords-viewattr-01-b.svg: Add comment, why scrollbars shouldn't appear anymore here.
     19
    1202011-11-08  Philippe Normand  <pnormand@igalia.com>
    221
  • trunk/LayoutTests/platform/chromium/test_expectations.txt

    r99529 r99539  
    14871487BUGCR23471 LEOPARD : fast/text/stroking.html = IMAGE
    14881488
    1489 // Failing on the bots but not locally; need investigation
    1490 BUGCR23560 MAC : svg/as-image/animated-svg-as-image.html = PASS IMAGE
    1491 
    14921489// -----------------------------------------------------------------
    14931490// END MAC PORT TESTS
     
    38503847BUGWK71215 SNOWLEOPARD DEBUG : animations/change-keyframes.html = TEXT
    38513848
    3852 BUGWK71226 : svg/as-background-image/animated-svg-as-background.html = IMAGE
    3853 BUGWK71226 : svg/zoom/page/zoom-coords-viewattr-01-b.svg = IMAGE+TEXT
    3854 BUGWK71226 MAC : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = IMAGE+TEXT
    3855 BUGWK71226 WIN LINUX : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = PASS IMAGE+TEXT
    3856 BUGWK71226 : fast/backgrounds/size/contain-and-cover-zoomed.html = IMAGE+TEXT
    3857 BUGWK71226 : fast/backgrounds/animated-svg-as-mask.html = IMAGE+TEXT IMAGE
     3849BUGWK71673 MAC : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = IMAGE+TEXT
     3850BUGWK71673 WIN LINUX : svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html = PASS IMAGE+TEXT
    38583851
    38593852BUGWK71278 SLOW WIN RELEASE : fast/events/dispatch-message-string-data.html = PASS
  • trunk/LayoutTests/svg/zoom/page/zoom-coords-viewattr-01-b.svg

    r54844 r99539  
    123123
    124124    <defs>
     125        <!-- Note that the zooming won't have any visible effect except for stroke size changes, as width/height is 100% -->
    125126        <script>var zoomCount = 2;</script>
    126127        <script xlink:href="../resources/testPageZoom.js"/>
  • trunk/Source/WebCore/CMakeLists.txt

    r99523 r99539  
    18071807        svg/animation/SVGSMILElement.cpp
    18081808        svg/graphics/SVGImage.cpp
     1809        svg/graphics/SVGImageCache.cpp
    18091810        svg/graphics/filters/SVGFEImage.cpp
    18101811        svg/graphics/filters/SVGFilter.cpp
  • trunk/Source/WebCore/ChangeLog

    r99533 r99539  
     12011-11-08  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
     4        https://bugs.webkit.org/show_bug.cgi?id=71368
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Fix regressions/races introduced by r98852. SVGImage repainting didn't work under certain circumstances.
     9        The problem was hard to reproduce on Mac ports, but easily visible on Chromium, when opening two files
     10        that shared the same animated SVG image. The problem of sharing a single ImageObserver across multiple
     11        instances of the same SVGImage, leads to nasty problems, that are timing dependant. changedInRect() calls
     12        that should only by received in one document, are received in the other as well, due the shared nature
     13        of CachedImage. To avoid these problems alltogether, a new approach is needed, that was initially suggested
     14        by Antti.
     15
     16        Avoid creating multiple SVGImages and caching them for different sizes/zoom levels. Introduce SVGImageCache
     17        which holds rendered versions of the SVGImage at certain sizes/zoom levels. It holds (ImageBuffer, Image) pairs
     18        for each renderer, associated with a size and zoom level.
     19
     20        This is a major change to the cache as introduced some weeks ago. Instead of holding multiple SVGImages, each containing
     21        a whole DOM/render tree, we now create bitmap images rendered at the requested sizes/zoom levels and cache them.
     22
     23        Revert ImageBySizeCache changes that were needed to make it usable wih SVGImage. Its now used only in CSSImageGeneratorValue and
     24        thus the extra information that CSSImageGeneratorValue doesn't need can be removed again (desired/actual size differentations, and the zoom level).
     25
     26        Tests: svg/as-image/animated-svg-as-image-no-fixed-intrinsic-size.html
     27               svg/as-image/animated-svg-as-image-same-image.html
     28
     29        * CMakeLists.txt: Add svg/graphics/SVGImageCache.* to build.
     30        * GNUmakefile.list.am: Ditto.
     31        * Target.pri: Ditto.
     32        * WebCore.gypi: Ditto.
     33        * WebCore.vcproj/WebCore.vcproj: Ditto.
     34        * WebCore.vcproj/copyForwardingHeaders.cmd: Copy headers from svg/graphics, as SVGImageCache is needed by CachedImage in SVG enabled builds.
     35        * WebCore.xcodeproj/project.pbxproj: Add svg/graphics/SVGImageCache.* to build.
     36        * css/CSSImageGeneratorValue.cpp: Remove zoom parameter from addClient/getImage, no need to pass 1 default values anymore.
     37        (WebCore::CSSImageGeneratorValue::addClient):
     38        (WebCore::CSSImageGeneratorValue::getImage):
     39        * loader/cache/CachedImage.cpp: Stop using ImageBySizeCache, and switch to the new SVGImageCache.
     40        (WebCore::CachedImage::removeClientForRenderer):
     41        (WebCore::CachedImage::lookupOrCreateImageForRenderer):
     42        (WebCore::CachedImage::setContainerSizeForRenderer):
     43        (WebCore::CachedImage::imageSizeForRenderer):
     44        (WebCore::CachedImage::clear):
     45        (WebCore::CachedImage::createImage):
     46        (WebCore::CachedImage::destroyDecodedData):
     47        (WebCore::CachedImage::decodedSizeChanged):
     48        (WebCore::CachedImage::didDraw):
     49        (WebCore::CachedImage::shouldPauseAnimation):
     50        (WebCore::CachedImage::animationAdvanced):
     51        (WebCore::CachedImage::changedInRect):
     52        * loader/cache/CachedImage.h:
     53        * page/DragController.cpp: Stop using imageForRenderer(), as it may return cached BitmapImages, that don't carry a filename extension anymore, which is required here.
     54        (WebCore::getImage):
     55        * rendering/ImageBySizeCache.cpp: Revert changes to ImageBySizeCache, which were needed to make it usable for SVGImages. CSSImageGenerator doesn't need it.
     56        (WebCore::ImageBySizeCache::addClient):
     57        (WebCore::ImageBySizeCache::removeClient):
     58        (WebCore::ImageBySizeCache::getImage):
     59        * rendering/ImageBySizeCache.h: Ditto.
     60        (WebCore::SizeAndCount::SizeAndCount):
     61        * rendering/RenderImage.cpp: Stop using imageForRenderer(), use cachedImage()->image(), which is guaranteed to be a SVGImage for svg images, and not a cached bitmap copy.
     62        (WebCore::RenderImage::embeddedContentBox):
     63        * rendering/RenderReplaced.cpp: Simplify logic to figure out the intrinsic size - the special logic for the old SVGImage cache can go away now.
     64        (WebCore::RenderReplaced::computeIntrinsicLogicalWidth):
     65        (WebCore::RenderReplaced::computeIntrinsicLogicalHeight):
     66        * rendering/style/StyleCachedImage.cpp: Call removeClientForRenderer(), which takes care of clearing SVGImageCache entries as well.
     67        (WebCore::StyleCachedImage::removeClient): This change is needed, as we don't want to make removeClient() virtual in CachedResource.
     68        * rendering/svg/RenderSVGRoot.cpp: Rename isEmbeddedThroughImageElement to isEmbeddedThroughSVGImage, as this is what it actually checks.
     69        (WebCore::RenderSVGRoot::isEmbeddedThroughSVGImage):
     70        * rendering/svg/RenderSVGRoot.h:
     71        * svg/SVGSVGElement.cpp: Fix bug that's visible now with the SVGImageCache, which was already there before, but hard to trigger.
     72        (WebCore::SVGSVGElement::currentViewBoxRect): The viewBox depends on who's asking for it: the host document or the embedded document? Take that into account.
     73        * svg/SVGSVGElement.h:
     74        * svg/graphics/SVGImage.cpp: Cleanup some code. Add new logic that draws a SVGImage into an ImageBuffer at a desired size & zoom.
     75        (WebCore::SVGImage::setContainerSize):
     76        (WebCore::SVGImage::size):
     77        (WebCore::SVGImage::drawSVGToImageBuffer):
     78        * svg/graphics/SVGImage.h:
     79        * svg/graphics/SVGImageCache.cpp: Added. SVGImageCache caches Image/ImageBuffer pairs for each _renderer_ and size/zoom level. The ImageBySizeCache only cared about size.
     80        (WebCore::SVGImageCache::SVGImageCache):
     81        (WebCore::SVGImageCache::~SVGImageCache):
     82        (WebCore::SVGImageCache::removeRendererFromCache):
     83        (WebCore::SVGImageCache::setRequestedSizeAndZoom):
     84        (WebCore::SVGImageCache::getRequestedSizeAndZoom):
     85        (WebCore::SVGImageCache::imageContentChanged):
     86        (WebCore::SVGImageCache::redrawTimerFired):
     87        (WebCore::SVGImageCache::lookupOrCreateBitmapImageForRenderer):
     88        * svg/graphics/SVGImageCache.h: Added.
     89        (WebCore::SVGImageCache::create):
     90        (WebCore::SVGImageCache::CachedSizeAndZoom::CachedSizeAndZoom):
     91        (WebCore::SVGImageCache::CachedImageData::CachedImageData):
     92
    1932011-11-07  Yury Semikhatsky  <yurys@chromium.org>
    294
  • trunk/Source/WebCore/GNUmakefile.list.am

    r99468 r99539  
    35373537        Source/WebCore/svg/graphics/filters/SVGFilter.cpp \
    35383538        Source/WebCore/svg/graphics/filters/SVGFilter.h \
     3539        Source/WebCore/svg/graphics/SVGImageCache.cpp \
     3540        Source/WebCore/svg/graphics/SVGImageCache.h \
    35393541        Source/WebCore/svg/graphics/SVGImage.cpp \
    35403542        Source/WebCore/svg/graphics/SVGImage.h \
  • trunk/Source/WebCore/Target.pri

    r99488 r99539  
    24842484    svg/graphics/filters/SVGFilter.h \
    24852485    svg/graphics/SVGImage.h \
     2486    svg/graphics/SVGImageCache.h \
    24862487    svg/properties/SVGAttributeToPropertyMap.h \
    24872488    svg/properties/SVGAnimatedEnumerationPropertyTearOff.h \
     
    33173318        svg/graphics/filters/SVGFilterBuilder.cpp \
    33183319        svg/graphics/SVGImage.cpp \
     3320        svg/graphics/SVGImageCache.cpp \
    33193321        svg/properties/SVGAttributeToPropertyMap.cpp \
    33203322        svg/properties/SVGPathSegListPropertyTearOff.cpp
  • trunk/Source/WebCore/WebCore.gypi

    r99488 r99539  
    62076207            'svg/animation/SMILTimeContainer.h',
    62086208            'svg/animation/SVGSMILElement.cpp',
     6209            'svg/graphics/SVGImageCache.cpp',
     6210            'svg/graphics/SVGImageCache.h',
    62096211            'svg/graphics/SVGImage.cpp',
    62106212            'svg/graphics/SVGImage.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r99468 r99539  
    6710267102                                >
    6710367103                                <File
     67104                                        RelativePath="..\svg\graphics\SVGImageCache.cpp"
     67105                                        >
     67106                                </File>
     67107                                <File
     67108                                        RelativePath="..\svg\graphics\SVGImageCache.h"
     67109                                        >
     67110                                </File>
     67111                                <File
    6710467112                                        RelativePath="..\svg\graphics\SVGImage.cpp"
    6710567113                                        >
  • trunk/Source/WebCore/WebCore.vcproj/copyForwardingHeaders.cmd

    r94452 r99539  
    7171xcopy /y /d "%ProjectDir%..\xml\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore"
    7272xcopy /y /d "%ProjectDir%..\svg\animation\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore"
     73xcopy /y /d "%ProjectDir%..\svg\graphics\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore"
    7374xcopy /y /d "%ProjectDir%..\svg\properties\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore"
    7475xcopy /y /d "%ProjectDir%..\svg\*.h" "%CONFIGURATIONBUILDDIR%\include\WebCore"
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r99490 r99539  
    195195                08F2F0091213E61700DCEC48 /* RenderImageResource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08F2F0071213E61700DCEC48 /* RenderImageResource.cpp */; };
    196196                08F2F00A1213E61700DCEC48 /* RenderImageResource.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F2F0081213E61700DCEC48 /* RenderImageResource.h */; settings = {ATTRIBUTES = (Private, ); }; };
     197                08F859D41463F9CD0067D933 /* SVGImageCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08F859D21463F9CD0067D933 /* SVGImageCache.cpp */; };
     198                08F859D51463F9CD0067D933 /* SVGImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 08F859D31463F9CD0067D933 /* SVGImageCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
    197199                08FB17C113BC7E9100040086 /* SVGAttributeToPropertyMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FB17C013BC7E9100040086 /* SVGAttributeToPropertyMap.cpp */; };
    198200                08FB3F8413BC754C0099FC18 /* SVGAttributeToPropertyMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 08FB3F8313BC754C0099FC18 /* SVGAttributeToPropertyMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    72257227                08F2F0071213E61700DCEC48 /* RenderImageResource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderImageResource.cpp; sourceTree = "<group>"; };
    72267228                08F2F0081213E61700DCEC48 /* RenderImageResource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderImageResource.h; sourceTree = "<group>"; };
     7229                08F859D21463F9CD0067D933 /* SVGImageCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGImageCache.cpp; sourceTree = "<group>"; };
     7230                08F859D31463F9CD0067D933 /* SVGImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageCache.h; sourceTree = "<group>"; };
    72277231                08FB17C013BC7E9100040086 /* SVGAttributeToPropertyMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGAttributeToPropertyMap.cpp; sourceTree = "<group>"; };
    72287232                08FB3F8313BC754C0099FC18 /* SVGAttributeToPropertyMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAttributeToPropertyMap.h; sourceTree = "<group>"; };
     
    1900519009                                B255990B0D00D8B900BB825C /* SVGImage.cpp */,
    1900619010                                B255990C0D00D8B900BB825C /* SVGImage.h */,
     19011                                08F859D21463F9CD0067D933 /* SVGImageCache.cpp */,
     19012                                08F859D31463F9CD0067D933 /* SVGImageCache.h */,
    1900719013                        );
    1900819014                        path = graphics;
     
    2462524631                                07846385145B1B8E00A58DF1 /* JSTrackCustom.h in Headers */,
    2462624632                                2D8FEBDD143E3EF70072502B /* CSSCrossfadeValue.h in Headers */,
     24633                                08F859D51463F9CD0067D933 /* SVGImageCache.h in Headers */,
    2462724634                                3169379C14609C6C00C01362 /* DragSession.h in Headers */,
    2462824635                                CAE9F910146441F000C245B0 /* CSSAspectRatioValue.h in Headers */,
     
    2748127488                                07689D6E145B52CC001CD132 /* JSTrackEventCustom.cpp in Sources */,
    2748227489                                2D8FEBDC143E3EF70072502B /* CSSCrossfadeValue.cpp in Sources */,
     27490                                08F859D41463F9CD0067D933 /* SVGImageCache.cpp in Sources */,
    2748327491                                CAE9F90F146441F000C245B0 /* CSSAspectRatioValue.cpp in Sources */,
    2748427492                                CDEA763014608A53008B31F1 /* PlatformClockCA.cpp in Sources */,
  • trunk/Source/WebCore/css/CSSImageGeneratorValue.cpp

    r99468 r99539  
    4949{
    5050    ref();
    51     m_imageCache.addClient(renderer, size, 1);
     51    m_imageCache.addClient(renderer, size);
    5252}
    5353
     
    6262    // If renderer is the only client, make sure we don't delete this, if the size changes (as this will result in addClient/removeClient calls).
    6363    RefPtr<CSSImageGeneratorValue> protect(this);
    64     return m_imageCache.getImage(renderer, size, 1);
     64    return m_imageCache.getImage(renderer, size);
    6565}
    6666
  • trunk/Source/WebCore/loader/cache/CachedImage.cpp

    r98852 r99539  
    9191}
    9292
     93void CachedImage::removeClientForRenderer(RenderObject* renderer)
     94{
     95#if ENABLE(SVG)
     96    if (m_svgImageCache)
     97        m_svgImageCache->removeRendererFromCache(renderer);
     98#endif
     99    removeClient(renderer);
     100}
     101
    93102void CachedImage::didAddClient(CachedResourceClient* c)
    94103{
     
    133142
    134143#if ENABLE(SVG)
    135 inline Image* CachedImage::lookupImageForSize(const IntSize& size) const
     144inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject* renderer)
    136145{
    137146    if (!m_image)
     
    139148    if (!m_image->isSVGImage())
    140149        return m_image.get();
    141     if (Image* image = m_svgImageCache.imageForSize(size))
    142         return image;
    143     return m_image.get();
    144 }
    145 
    146 inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject* renderer)
    147 {
    148     if (!m_image)
    149         return 0;
    150     if (!m_image->isSVGImage())
     150    Image* useImage = m_svgImageCache->lookupOrCreateBitmapImageForRenderer(renderer);
     151    if (useImage == Image::nullImage())
    151152        return m_image.get();
    152 
    153     // Request requested size/zoom for this renderer from the cache.
    154     IntSize size;
    155     float zoom = 1;
    156     m_svgImageCache.getRequestedSizeAndZoom(renderer, size, zoom);
    157     if (size.isEmpty())
    158         return m_image.get();
    159 
    160     if (Image* image = m_svgImageCache.getImage(renderer, size, zoom))
    161         return image;
    162 
    163     // Create and cache new image at requested size.
    164     RefPtr<Image> newImage = SVGImage::createWithDataAndSize(this, m_data.get(), size, zoom);
    165     Image* newImagePtr = newImage.get();
    166     m_svgImageCache.addClient(renderer, size, zoom);
    167     m_svgImageCache.putImage(size, newImage.release());
    168     return newImagePtr;
    169 }
    170 
     153    return useImage;
     154}
    171155#else
    172 inline Image* CachedImage::lookupImageForSize(const IntSize&) const
    173 {
    174     return m_image.get();
    175 }
    176 
    177156inline Image* CachedImage::lookupOrCreateImageForRenderer(const RenderObject*)
    178157{
     
    224203        return;
    225204    }
    226     m_svgImageCache.addClient(renderer, containerSize, containerZoom);
     205    m_svgImageCache->setRequestedSizeAndZoom(renderer, SVGImageCache::SizeAndZoom(containerSize, containerZoom));
    227206#else
    228207    UNUSED_PARAM(renderer);
     
    264243    if (m_image->isSVGImage()) {
    265244        // SVGImages already includes the zooming in its intrinsic size.
    266         IntSize size;
    267         float zoom = 1;
    268         m_svgImageCache.getRequestedSizeAndZoom(renderer, size, zoom);
    269         if (!size.isEmpty())
    270             return size;
    271         return m_image->size();
     245        SVGImageCache::SizeAndZoom sizeAndZoom = m_svgImageCache->requestedSizeAndZoom(renderer);
     246        if (sizeAndZoom.size.isEmpty())
     247            return m_image->size();
     248        if (sizeAndZoom.zoom == 1)
     249            return sizeAndZoom.size;
     250        if (multiplier == 1) {
     251            // Consumer wants unscaled coordinates.
     252            sizeAndZoom.size.setWidth(sizeAndZoom.size.width() / sizeAndZoom.zoom);
     253            sizeAndZoom.size.setHeight(sizeAndZoom.size.height() / sizeAndZoom.zoom);
     254            return sizeAndZoom.size;
     255        }
     256        return sizeAndZoom.size;
    272257    }
    273258#endif
     
    313298{
    314299    destroyDecodedData();
     300#if ENABLE(SVG)
    315301    m_svgImageCache.clear();
     302#endif
    316303    m_image = 0;
    317304    setEncodedSize(0);
     
    331318#if ENABLE(SVG)
    332319    if (m_response.mimeType() == "image/svg+xml") {
    333         m_image = SVGImage::create(this);
     320        RefPtr<SVGImage> svgImage = SVGImage::create(this);
     321        m_svgImageCache = SVGImageCache::create(svgImage.get());
     322        m_image = svgImage.release();
    334323        return;
    335324    }
     
    411400        if (!MemoryCache::shouldMakeResourcePurgeableOnEviction())
    412401            makePurgeable(true);
    413     } else if (m_image && !errorOccurred() && !m_image->isSVGImage())
     402    } else if (m_image && !errorOccurred())
    414403        m_image->destroyDecodedData();
    415404}
     
    417406void CachedImage::decodedSizeChanged(const Image* image, int delta)
    418407{
    419     if (!image)
    420         return;
    421     Image* useImage = lookupImageForSize(image->size());
    422     if (image != useImage)
     408    if (!image || image != m_image)
    423409        return;
    424410   
     
    428414void CachedImage::didDraw(const Image* image)
    429415{
    430     if (!image)
    431         return;
    432     Image* useImage = lookupImageForSize(image->size());
    433     if (image != useImage)
     416    if (!image || image != m_image)
    434417        return;
    435418   
     
    443426bool CachedImage::shouldPauseAnimation(const Image* image)
    444427{
    445     if (!image)
    446         return false;
    447     Image* useImage = lookupImageForSize(image->size());
    448     if (image != useImage)
     428    if (!image || image != m_image)
    449429        return false;
    450430   
     
    460440void CachedImage::animationAdvanced(const Image* image)
    461441{
    462     if (!image)
    463         return;
    464     Image* useImage = lookupImageForSize(image->size());
    465     if (image != useImage)
     442    if (!image || image != m_image)
    466443        return;
    467444    notifyObservers();
     
    470447void CachedImage::changedInRect(const Image* image, const IntRect& rect)
    471448{
    472     if (!image)
    473         return;
    474     Image* useImage = lookupImageForSize(image->size());
    475     if (image != useImage)
    476         return;
     449    if (!image || image != m_image)
     450        return;
     451#if ENABLE(SVG)
     452    // We have to update the cached ImageBuffers if the underlying content changed.
     453    if (image->isSVGImage()) {
     454        m_svgImageCache->imageContentChanged();
     455        return;
     456    }
     457#endif
    477458    notifyObservers(&rect);
    478459}
    479460
    480 } //namespace WebCore
     461} // namespace WebCore
  • trunk/Source/WebCore/loader/cache/CachedImage.h

    r98852 r99539  
    2626#include "CachedResource.h"
    2727#include "CachedResourceClient.h"
    28 #include "ImageBySizeCache.h"
     28#include "SVGImageCache.h"
    2929#include "ImageObserver.h"
    3030#include "IntRect.h"
     
    6868    void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
    6969
     70    void removeClientForRenderer(RenderObject*);
    7071    virtual void didAddClient(CachedResourceClient*);
    7172   
     
    9596
    9697private:
    97     Image* lookupImageForSize(const IntSize&) const;
    9898    Image* lookupOrCreateImageForRenderer(const RenderObject*);
    9999
     
    107107
    108108    RefPtr<Image> m_image;
    109     mutable ImageBySizeCache m_svgImageCache;
     109#if ENABLE(SVG)
     110    OwnPtr<SVGImageCache> m_svgImageCache;
     111#endif
    110112    Timer<CachedImage> m_decodedDataDeletionTimer;
    111113    bool m_shouldPaintBrokenImage;
  • trunk/Source/WebCore/page/DragController.cpp

    r99369 r99539  
    654654    ASSERT(element);
    655655    CachedImage* cachedImage = getCachedImage(element);
     656    // Don't use cachedImage->imageForRenderer() here as that may return BitmapImages for cached SVG Images.
     657    // Users of getImage() want access to the SVGImage, in order to figure out the filename extensions,
     658    // which would be empty when asking the cached BitmapImages.
    656659    return (cachedImage && !cachedImage->errorOccurred()) ?
    657         cachedImage->imageForRenderer(element->renderer()) : 0;
     660        cachedImage->image() : 0;
    658661}
    659662
  • trunk/Source/WebCore/rendering/ImageBySizeCache.cpp

    r98852 r99539  
    2424#include "Image.h"
    2525#include "IntSize.h"
    26 #include "IntSizeHash.h"
    2726#include "RenderObject.h"
    2827
     
    3332}
    3433
    35 void ImageBySizeCache::addClient(const RenderObject* renderer, const IntSize& size, float zoom)
     34void ImageBySizeCache::addClient(const RenderObject* renderer, const IntSize& size)
    3635{
    3736    ASSERT(renderer);
     
    4140    RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
    4241    if (it == m_clients.end())
    43         m_clients.add(renderer, SizeZoomAndCount(size, zoom, 1));
     42        m_clients.add(renderer, SizeAndCount(size, 1));
    4443    else {
    45         SizeZoomAndCount& sizeCount = it->second;
    46         sizeCount.requestedSize = size;
    47         sizeCount.requestedZoom = zoom;
     44        SizeAndCount& sizeCount = it->second;
    4845        ++sizeCount.count;
    4946    }
     
    5653    ASSERT(it != m_clients.end());
    5754
    58     SizeZoomAndCount& sizeCount = it->second;
    59     IntSize size = sizeCount.actualSize;
     55    IntSize removedImageSize;
     56    SizeAndCount& sizeCount = it->second;
     57    IntSize size = sizeCount.size;
    6058    if (!size.isEmpty()) {
    6159        m_sizes.remove(size);
     
    6866}
    6967
    70 Image* ImageBySizeCache::getImage(const RenderObject* renderer, const IntSize& size, float zoom)
     68Image* ImageBySizeCache::getImage(const RenderObject* renderer, const IntSize& size)
    7169{
    7270    RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
    7371    if (it != m_clients.end()) {
    74         SizeZoomAndCount& sizeCount = it->second;
    75         IntSize oldSize = sizeCount.actualSize;
     72        SizeAndCount& sizeCount = it->second;
     73        IntSize oldSize = sizeCount.size;
    7674        if (oldSize != size) {
    7775            removeClient(renderer);
    78             addClient(renderer, size, zoom);
     76            addClient(renderer, size);
    7977        }
    8078    }
     
    8886}
    8987
    90 void ImageBySizeCache::getRequestedSizeAndZoom(const RenderObject* renderer, IntSize& size, float& zoom)
    91 {
    92     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
    93     if (it == m_clients.end())
    94         return;
    95     SizeZoomAndCount& sizeCount = it->second;
    96     size = sizeCount.requestedSize;
    97     zoom = sizeCount.requestedZoom;
    98 }
    99 
    10088void ImageBySizeCache::putImage(const IntSize& size, PassRefPtr<Image> image)
    10189{
     
    10391}
    10492
    105 void ImageBySizeCache::clear()
    106 {
    107     m_sizes.clear();
    108     m_clients.clear();
    109     m_images.clear();
    110 }
    111 
    112 Image* ImageBySizeCache::imageForSize(const IntSize& size) const
    113 {
    114     if (size.isEmpty())
    115         return 0;
    116     HashMap<IntSize, RefPtr<Image> >::const_iterator it = m_images.find(size);
    117     if (it == m_images.end())
    118         return 0;
    119     return it->second.get();
    120 }
    121 
    122 Image* ImageBySizeCache::imageForRenderer(const RenderObject* renderer) const
    123 {
    124     if (!renderer)
    125         return 0;
    126     RenderObjectSizeCountMap::const_iterator it = m_clients.find(renderer);
    127     if (it == m_clients.end())
    128         return 0;
    129     return imageForSize(it->second.actualSize);
    130 }
    131 
    13293} // namespace WebCore
  • trunk/Source/WebCore/rendering/ImageBySizeCache.h

    r98852 r99539  
    3232class RenderObject;
    3333
    34 struct SizeZoomAndCount {
    35     SizeZoomAndCount(IntSize newSize = IntSize(), float newZoom = 0, int newCount = 0)
    36         : actualSize(newSize)
    37         , requestedSize(newSize)
    38         , actualZoom(newZoom)
    39         , requestedZoom(newZoom)
     34struct SizeAndCount {
     35    SizeAndCount(IntSize newSize = IntSize(), int newCount = 0)
     36        : size(newSize)
    4037        , count(newCount)
    4138    {
    4239    }
    4340
    44     IntSize actualSize;
    45     IntSize requestedSize;
    46     float actualZoom;
    47     float requestedZoom;
     41    IntSize size;
    4842    int count;
    4943};
    5044
    51 typedef HashMap<const RenderObject*, SizeZoomAndCount> RenderObjectSizeCountMap;
     45typedef HashMap<const RenderObject*, SizeAndCount> RenderObjectSizeCountMap;
    5246
    5347class ImageBySizeCache {
     
    5549    ImageBySizeCache();
    5650
    57     void addClient(const RenderObject*, const IntSize&, float zoom);
     51    void addClient(const RenderObject*, const IntSize&);
    5852    void removeClient(const RenderObject*);
    5953
    60     Image* getImage(const RenderObject*, const IntSize&, float zoom);
    61     void getRequestedSizeAndZoom(const RenderObject*, IntSize&, float& zoom);
    62 
     54    Image* getImage(const RenderObject*, const IntSize&);
    6355    void putImage(const IntSize&, PassRefPtr<Image>);
    6456
    65     void clear();
    66 
    67     Image* imageForSize(const IntSize&) const;
    68     Image* imageForRenderer(const RenderObject*) const;
    6957    const RenderObjectSizeCountMap& clients() const { return m_clients; }
    7058
  • trunk/Source/WebCore/rendering/RenderImage.cpp

    r99303 r99539  
    546546
    547547#if ENABLE(SVG)
    548     RefPtr<Image> image = m_imageResource->image();
    549     if (image && image->isSVGImage())
    550         return static_pointer_cast<SVGImage>(image)->embeddedContentBox();
     548    CachedImage* cachedImage = m_imageResource->cachedImage();
     549    if (cachedImage && cachedImage->image() && cachedImage->image()->isSVGImage())
     550        return static_cast<SVGImage*>(cachedImage->image())->embeddedContentBox();
    551551#endif
    552552
  • trunk/Source/WebCore/rendering/RenderReplaced.cpp

    r98852 r99539  
    201201int RenderReplaced::computeIntrinsicLogicalWidth(RenderBox* contentRenderer, bool includeMaxWidth) const
    202202{
    203     if (m_hasIntrinsicSize) {
    204         if (!contentRenderer || !contentRenderer->style()->logicalWidth().isFixed())
    205             return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth);
    206     }
     203    if (m_hasIntrinsicSize)
     204        return computeReplacedLogicalWidthRespectingMinMaxWidth(calcAspectRatioLogicalWidth(), includeMaxWidth);
    207205    ASSERT(contentRenderer);
    208206    ASSERT(contentRenderer->style());
     
    212210int RenderReplaced::computeIntrinsicLogicalHeight(RenderBox* contentRenderer) const
    213211{
    214     if (m_hasIntrinsicSize) {
    215         if (!contentRenderer || !contentRenderer->style()->logicalHeight().isFixed())
    216             return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight());
    217     }
     212    if (m_hasIntrinsicSize)
     213        return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight());
    218214    ASSERT(contentRenderer);
    219215    ASSERT(contentRenderer->style());
  • trunk/Source/WebCore/rendering/style/StyleCachedImage.cpp

    r98852 r99539  
    8787void StyleCachedImage::removeClient(RenderObject* renderer)
    8888{
    89     m_image->removeClient(renderer);
     89    m_image->removeClientForRenderer(renderer);
    9090}
    9191
  • trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp

    r98852 r99539  
    118118}
    119119
    120 bool RenderSVGRoot::isEmbeddedThroughImageElement() const
     120bool RenderSVGRoot::isEmbeddedThroughSVGImage() const
    121121{
    122122    if (!node())
  • trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h

    r98852 r99539  
    4040    virtual ~RenderSVGRoot();
    4141
    42     bool isEmbeddedThroughImageElement() const;
     42    bool isEmbeddedThroughSVGImage() const;
    4343
    4444    virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
  • trunk/Source/WebCore/svg/SVGSVGElement.cpp

    r98852 r99539  
    552552}
    553553
    554 FloatRect SVGSVGElement::currentViewBoxRect() const
    555 {
     554FloatRect SVGSVGElement::currentViewBoxRect(CalculateViewBoxMode mode) const
     555{
     556    // FIXME: The interaction of 'currentView' and embedding SVGs in other documents, is untested and unspecified.
    556557    if (useCurrentView()) {
    557558        if (SVGViewSpec* view = currentView()) // what if we should use it but it is not set?
     
    560561    }
    561562
    562     // Synthesize a viewBox if we're embedded through a <img> element, if none is present.
     563    bool isEmbeddedThroughSVGImage = renderer() && renderer()->isSVGRoot() ? toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage() : false;
     564    bool hasFixedSize = width().unitType() != LengthTypePercentage && height().unitType() != LengthTypePercentage;
     565
    563566    FloatRect useViewBox = viewBox();
    564     if (useViewBox.isEmpty() && width().unitType() != LengthTypePercentage && height().unitType() != LengthTypePercentage) {
    565         if (RenderObject* renderer = this->renderer()) {
    566             if (renderer->isSVGRoot() && toRenderSVGRoot(renderer)->isEmbeddedThroughImageElement())
    567                 useViewBox = FloatRect(0, 0, width().value(this), height().value(this));
    568         }
    569     }
     567    if (useViewBox.isEmpty()) {
     568        // If no viewBox is specified but non-relative width/height values, then we
     569        // should always synthesize a viewBox if we're embedded through a SVGImage.
     570        if (hasFixedSize && isEmbeddedThroughSVGImage)
     571            return FloatRect(0, 0, width().value(this), height().value(this));
     572        return FloatRect();
     573    }
     574
     575    // If a viewBox is specified and non-relative width/height values, then the host document only
     576    // uses the width/height values to figure out the intrinsic size when embedding us, whereas the
     577    // embedded document sees specified viewBox only.
     578    if (hasFixedSize && mode == CalculateViewBoxInHostDocument)
     579        return FloatRect(0, 0, width().value(this), height().value(this));
    570580
    571581    return useViewBox;
  • trunk/Source/WebCore/svg/SVGSVGElement.h

    r98852 r99539  
    7373
    7474    SVGViewSpec* currentView() const;
    75     FloatRect currentViewBoxRect() const;
    7675
     76    enum CalculateViewBoxMode {
     77        CalculateViewBoxInHostDocument,
     78        CalculateViewBoxInCurrentDocument
     79    };
     80
     81    FloatRect currentViewBoxRect(CalculateViewBoxMode = CalculateViewBoxInCurrentDocument) const;
    7782    float currentScale() const;
    7883    void setCurrentScale(float scale);
  • trunk/Source/WebCore/svg/graphics/SVGImage.cpp

    r99303 r99539  
    103103}
    104104
    105 PassRefPtr<SVGImage> SVGImage::createWithDataAndSize(ImageObserver* observer, SharedBuffer* data, const IntSize& size, float zoom)
    106 {
    107     ASSERT(!size.isEmpty());
    108 
    109     RefPtr<SVGImage> image = adoptRef(new SVGImage(0));
    110     image->setData(data, true);
    111     image->setContainerSize(size);
    112     image->setContainerZoom(zoom);
    113     image->setImageObserver(observer);
    114     return image.release();
    115 }
    116 
    117 void SVGImage::setContainerZoom(float containerZoom)
    118 {
    119     if (!m_page)
    120         return;
    121     Frame* frame = m_page->mainFrame();
    122     frame->setPageZoomFactor(containerZoom);
    123 }
    124 
    125 void SVGImage::setContainerSize(const IntSize& containerSize)
    126 {
    127     ASSERT(!containerSize.isEmpty());
    128     ASSERT(!imageObserver());
    129    
    130     if (!m_page)
    131         return;
    132     Frame* frame = m_page->mainFrame();
    133     SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement();
    134     if (!rootElement)
    135         return;
    136 
    137     RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
    138     if (!renderer)
    139         return;
    140     renderer->setContainerSize(containerSize);
    141     frame->view()->resize(size());
     105void SVGImage::setContainerSize(const IntSize&)
     106{
     107    ASSERT_NOT_REACHED();
    142108}
    143109
     
    175141    // Assure that a container size is always given for a non-identity zoom level.
    176142    ASSERT(renderer->style()->effectiveZoom() == 1);
    177     IntSize size = enclosingIntRect(rootElement->currentViewBoxRect()).size();
     143    IntSize size = enclosingIntRect(rootElement->currentViewBoxRect(SVGSVGElement::CalculateViewBoxInHostDocument)).size();
    178144    if (!size.isEmpty())
    179145        return size;
     
    181147    // As last resort, use CSS default intrinsic size.
    182148    return IntSize(300, 150);
     149}
     150
     151void SVGImage::drawSVGToImageBuffer(ImageBuffer* buffer, const IntSize& size, float zoom, ShouldClearBuffer shouldClear)
     152{
     153    // FIXME: This doesn't work correctly with animations. If an image contains animations, that say run for 2 seconds,
     154    // and we currently have one <img> that displays us. If we open another document referencing the same SVGImage it
     155    // will display the document at a time where animations already ran - even though it has its own ImageBuffer.
     156    // We currently don't implement SVGSVGElement::setCurrentTime, and can NOT go back in time, once animations started.
     157    // There's no way to fix this besides avoiding style/attribute mutations from SVGAnimationElement.
     158    ASSERT(buffer);
     159    ASSERT(!size.isEmpty());
     160
     161    Frame* frame = m_page->mainFrame();
     162    SVGSVGElement* rootElement = static_cast<SVGDocument*>(frame->document())->rootElement();
     163    if (!rootElement)
     164        return;
     165    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
     166    if (!renderer)
     167        return;
     168
     169    // Draw image at requested size.
     170    ImageObserver* observer = imageObserver();
     171    ASSERT(observer);
     172
     173    // Temporarily reset image observer, we don't want to receive any changeInRect() calls due this relayout.
     174    setImageObserver(0);
     175    renderer->setContainerSize(size);
     176    frame->view()->resize(this->size());
     177    if (zoom != 1)
     178        frame->setPageZoomFactor(zoom);
     179
     180    // Eventually clear image buffer.
     181    IntRect rect(IntPoint(), size);
     182    if (shouldClear == ClearImageBuffer)
     183        buffer->context()->clearRect(rect);
     184
     185    // Draw SVG on top of ImageBuffer.
     186    draw(buffer->context(), rect, rect, ColorSpaceDeviceRGB, CompositeSourceOver);
     187
     188    // Reset container size & zoom to initial state. Otherwhise the size() of this
     189    // image would return whatever last size was set by drawSVGToImageBuffer().
     190    if (zoom != 1)
     191        frame->setPageZoomFactor(1);
     192
     193    renderer->setContainerSize(IntSize());
     194    frame->view()->resize(this->size());
     195    if (frame->view()->needsLayout())
     196        frame->view()->layout();
     197
     198    setImageObserver(observer);
    183199}
    184200
  • trunk/Source/WebCore/svg/graphics/SVGImage.h

    r98852 r99539  
    3535namespace WebCore {
    3636
     37class ImageBuffer;
    3738class Page;
    3839class RenderBox;
     
    4647    }
    4748
    48     static PassRefPtr<SVGImage> createWithDataAndSize(ImageObserver*, SharedBuffer*, const IntSize&, float zoom);
     49    enum ShouldClearBuffer {
     50        ClearImageBuffer,
     51        DontClearImageBuffer
     52    };
    4953
    50     void setContainerZoom(float);
     54    void drawSVGToImageBuffer(ImageBuffer*, const IntSize&, float zoom, ShouldClearBuffer);
    5155    RenderBox* embeddedContentBox() const;
    5256
    5357    virtual bool isSVGImage() const { return true; }
     58    virtual IntSize size() const;
    5459
    5560private:
     
    6166    virtual bool usesContainerSize() const;
    6267    virtual void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
    63 
    64     virtual IntSize size() const;
    6568
    6669    virtual bool dataChanged(bool allDataReceived);
  • trunk/Source/WebKit/CMakeLists.txt

    r95310 r99539  
    3131    "${WEBCORE_DIR}/storage"
    3232    "${WEBCORE_DIR}/svg"
     33    "${WEBCORE_DIR}/svg/graphics"
    3334    "${WEBCORE_DIR}/svg/properties"
    3435    "${JAVASCRIPTCORE_DIR}"
  • trunk/Source/WebKit/ChangeLog

    r99274 r99539  
     12011-11-08  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Switch SVGImage cache to store ImageBuffers instead of whole SVGImages, including a DOM/Render tree
     4        https://bugs.webkit.org/show_bug.cgi?id=71368
     5
     6        Reviewed by Antti Koivisto.
     7
     8        * CMakeLists.txt: Add svg/graphics include, for SVGImageCache.h.
     9
    1102011-11-04  Tor Arne Vestbø  <tor.arne.vestbo@nokia.com>
    211
Note: See TracChangeset for help on using the changeset viewer.