Commit 95247979 authored by simon.fraser@apple.com's avatar simon.fraser@apple.com
Browse files

2011-01-24 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Eric Seidel.

        Refcount Images used in rendering code
        https://bugs.webkit.org/show_bug.cgi?id=52701

        Change StyleImage::image(RenderObject*, const IntSize&) and
        CSSImageGeneratorValue::image(RenderObject*, const IntSize&) to
        return PassRefPtr<Image>, and adjust other code accordingly.

        This allows us to return one-time images, for example for CSS gradients
        whose appearance may change depending on factors other than the renderer
        and the destination size.

        * css/CSSCanvasValue.cpp:
        (WebCore::CSSCanvasValue::image):
        * css/CSSCanvasValue.h:
        * css/CSSGradientValue.cpp:
        (WebCore::CSSGradientValue::image):
        * css/CSSGradientValue.h:
        * css/CSSImageGeneratorValue.h:
        * rendering/RenderBoxModelObject.cpp:
        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
        (WebCore::RenderBoxModelObject::paintNinePieceImage):
        * rendering/RenderImage.cpp:
        (WebCore::RenderImage::paintReplaced):
        (WebCore::RenderImage::paintIntoRect):
        * rendering/RenderImageResource.h:
        (WebCore::RenderImageResource::image):
        * rendering/RenderImageResourceStyleImage.h:
        (WebCore::RenderImageResourceStyleImage::image):
        * rendering/RenderListMarker.cpp:
        (WebCore::RenderListMarker::paint):
        * rendering/style/StyleCachedImage.cpp:
        (WebCore::StyleCachedImage::image):
        * rendering/style/StyleCachedImage.h:
        * rendering/style/StyleGeneratedImage.cpp:
        (WebCore::StyleGeneratedImage::image):
        * rendering/style/StyleGeneratedImage.h:
        * rendering/style/StyleImage.h:
        * rendering/style/StylePendingImage.h:
        (WebCore::StylePendingImage::image):
        * rendering/svg/RenderSVGImage.cpp:
        (WebCore::RenderSVGImage::paint):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76571 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 29ae3d56
2011-01-24 Simon Fraser <simon.fraser@apple.com>
Reviewed by Eric Seidel.
Refcount Images used in rendering code
https://bugs.webkit.org/show_bug.cgi?id=52701
Change StyleImage::image(RenderObject*, const IntSize&) and
CSSImageGeneratorValue::image(RenderObject*, const IntSize&) to
return PassRefPtr<Image>, and adjust other code accordingly.
This allows us to return one-time images, for example for CSS gradients
whose appearance may change depending on factors other than the renderer
and the destination size.
* css/CSSCanvasValue.cpp:
(WebCore::CSSCanvasValue::image):
* css/CSSCanvasValue.h:
* css/CSSGradientValue.cpp:
(WebCore::CSSGradientValue::image):
* css/CSSGradientValue.h:
* css/CSSImageGeneratorValue.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
(WebCore::RenderBoxModelObject::paintNinePieceImage):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintReplaced):
(WebCore::RenderImage::paintIntoRect):
* rendering/RenderImageResource.h:
(WebCore::RenderImageResource::image):
* rendering/RenderImageResourceStyleImage.h:
(WebCore::RenderImageResourceStyleImage::image):
* rendering/RenderListMarker.cpp:
(WebCore::RenderListMarker::paint):
* rendering/style/StyleCachedImage.cpp:
(WebCore::StyleCachedImage::image):
* rendering/style/StyleCachedImage.h:
* rendering/style/StyleGeneratedImage.cpp:
(WebCore::StyleGeneratedImage::image):
* rendering/style/StyleGeneratedImage.h:
* rendering/style/StyleImage.h:
* rendering/style/StylePendingImage.h:
(WebCore::StylePendingImage::image):
* rendering/svg/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::paint):
2011-01-24 Tony Chang <tony@chromium.org>
 
Unreviewed, round ascent and descent to match old code.
......@@ -83,7 +83,7 @@ HTMLCanvasElement* CSSCanvasValue::element(Document* document)
return m_element;
}
Image* CSSCanvasValue::image(RenderObject* renderer, const IntSize& /*size*/)
PassRefPtr<Image> CSSCanvasValue::image(RenderObject* renderer, const IntSize& /*size*/)
{
ASSERT(m_clients.contains(renderer));
HTMLCanvasElement* elt = element(renderer->document());
......
......@@ -40,7 +40,7 @@ public:
virtual String cssText() const;
virtual Image* image(RenderObject*, const IntSize&);
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&);
virtual bool isFixedSize() const { return true; }
virtual IntSize fixedSize(const RenderObject*);
......
......@@ -41,7 +41,7 @@ using namespace std;
namespace WebCore {
Image* CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
PassRefPtr<Image> CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
{
if (!m_clients.contains(renderer))
return 0;
......@@ -58,10 +58,9 @@ Image* CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
// We need to create an image.
RefPtr<Image> newImage = GeneratedImage::create(createGradient(renderer, size), size);
result = newImage.get();
putImage(size, newImage.release());
putImage(size, newImage);
return result;
return newImage.release();
}
// Should only ever be called for deprecated gradients.
......
......@@ -46,7 +46,7 @@ struct CSSGradientColorStop {
class CSSGradientValue : public CSSImageGeneratorValue {
public:
virtual Image* image(RenderObject*, const IntSize&);
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&);
void setFirstX(PassRefPtr<CSSPrimitiveValue> val) { m_firstX = val; }
void setFirstY(PassRefPtr<CSSPrimitiveValue> val) { m_firstY = val; }
......
......@@ -44,7 +44,7 @@ public:
void addClient(RenderObject*, const IntSize&);
void removeClient(RenderObject*);
virtual Image* image(RenderObject*, const IntSize&) = 0;
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) = 0;
StyleGeneratedImage* generatedImage();
......
......@@ -693,9 +693,9 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
phase += destRect.location() - destOrigin;
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
Image* image = bg->image(clientForBackgroundImage, tileSize);
bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, bgLayer, tileSize);
context->drawTiledImage(image, style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
RefPtr<Image> image = bg->image(clientForBackgroundImage, tileSize);
bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, tileSize);
context->drawTiledImage(image.get(), style()->colorSpace(), destRect, phase, tileSize, compositeOp, useLowQualityScaling);
}
}
......@@ -897,7 +897,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
bool drawMiddle = (imageWidth - leftSlice - rightSlice) > 0 && (w - leftWidth - rightWidth) > 0 &&
(imageHeight - topSlice - bottomSlice) > 0 && (h - topWidth - bottomWidth) > 0;
Image* image = styleImage->image(this, imageSize);
RefPtr<Image> image = styleImage->image(this, imageSize);
ColorSpace colorSpace = style->colorSpace();
if (drawLeft) {
......@@ -906,18 +906,18 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top left corner rect is (tx, ty, leftWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (0, 0, leftSlice, topSlice)
if (drawTop)
graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty, leftWidth, topWidth),
graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx, ty, leftWidth, topWidth),
IntRect(0, 0, leftSlice, topSlice), op);
// The bottom left corner rect is (tx, ty + h - bottomWidth, leftWidth, bottomWidth)
// The rect to use from within the image is (0, imageHeight - bottomSlice, leftSlice, botomSlice)
if (drawBottom)
graphicsContext->drawImage(image, colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx, ty + h - bottomWidth, leftWidth, bottomWidth),
IntRect(0, imageHeight - bottomSlice, leftSlice, bottomSlice), op);
// Paint the left edge.
// Have to scale and tile into the border rect.
graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx, ty + topWidth, leftWidth,
graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx, ty + topWidth, leftWidth,
h - topWidth - bottomWidth),
IntRect(0, topSlice, leftSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
......@@ -928,17 +928,17 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// The top right corner rect is (tx + w - rightWidth, ty, rightWidth, topWidth)
// The rect to use from within the image is obtained from our slice, and is (imageWidth - rightSlice, 0, rightSlice, topSlice)
if (drawTop)
graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty, rightWidth, topWidth),
IntRect(imageWidth - rightSlice, 0, rightSlice, topSlice), op);
// The bottom right corner rect is (tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth)
// The rect to use from within the image is (imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice)
if (drawBottom)
graphicsContext->drawImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
graphicsContext->drawImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty + h - bottomWidth, rightWidth, bottomWidth),
IntRect(imageWidth - rightSlice, imageHeight - bottomSlice, rightSlice, bottomSlice), op);
// Paint the right edge.
graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + w - rightWidth, ty + topWidth, rightWidth,
h - topWidth - bottomWidth),
IntRect(imageWidth - rightSlice, topSlice, rightSlice, imageHeight - topSlice - bottomSlice),
Image::StretchTile, (Image::TileRule)vRule, op);
......@@ -946,20 +946,20 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
// Paint the top edge.
if (drawTop)
graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty, w - leftWidth - rightWidth, topWidth),
IntRect(leftSlice, 0, imageWidth - rightSlice - leftSlice, topSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the bottom edge.
if (drawBottom)
graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty + h - bottomWidth,
w - leftWidth - rightWidth, bottomWidth),
IntRect(leftSlice, imageHeight - bottomSlice, imageWidth - rightSlice - leftSlice, bottomSlice),
(Image::TileRule)hRule, Image::StretchTile, op);
// Paint the middle.
if (drawMiddle)
graphicsContext->drawTiledImage(image, colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
graphicsContext->drawTiledImage(image.get(), colorSpace, IntRect(tx + leftWidth, ty + topWidth, w - leftWidth - rightWidth,
h - topWidth - bottomWidth),
IntRect(leftSlice, topSlice, imageWidth - rightSlice - leftSlice, imageHeight - topSlice - bottomSlice),
(Image::TileRule)hRule, (Image::TileRule)vRule, op);
......
......@@ -267,7 +267,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
int usableWidth = cWidth - 2;
int usableHeight = cHeight - 2;
Image* image = m_imageResource->image();
RefPtr<Image> image = m_imageResource->image();
if (m_imageResource->errorOccurred() && !image->isNull() && usableWidth >= image->width() && usableHeight >= image->height()) {
// Center the error image, accounting for border and padding.
......@@ -279,7 +279,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
centerY = 0;
imageX = leftBorder + leftPad + centerX + 1;
imageY = topBorder + topPad + centerY + 1;
context->drawImage(image, style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
context->drawImage(image.get(), style()->colorSpace(), IntPoint(tx + imageX, ty + imageY));
errorPictureDrawn = true;
}
......@@ -304,7 +304,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
}
}
} else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
Image* img = m_imageResource->image(cWidth, cHeight);
RefPtr<Image> img = m_imageResource->image(cWidth, cHeight);
if (!img || img->isNull())
return;
......@@ -370,14 +370,14 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const IntRect& rect)
if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || rect.width() <= 0 || rect.height() <= 0)
return;
Image* img = m_imageResource->image(rect.width(), rect.height());
RefPtr<Image> img = m_imageResource->image(rect.width(), rect.height());
if (!img || img->isNull())
return;
HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image(), 0, rect.size());
context->drawImage(m_imageResource->image(rect.width(), rect.height()), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
bool useLowQualityScaling = shouldPaintAtLowQuality(context, m_imageResource->image().get(), 0, rect.size());
context->drawImage(m_imageResource->image(rect.width(), rect.height()).get(), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling);
}
int RenderImage::minimumReplacedHeight() const
......
......@@ -28,6 +28,7 @@
#include "CachedImage.h"
#include "CachedResourceHandle.h"
#include "Image.h"
#include "StyleImage.h"
namespace WebCore {
......@@ -53,7 +54,7 @@ public:
void resetAnimation();
virtual Image* image(int /* width */ = 0, int /* height */ = 0) { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
virtual PassRefPtr<Image> image(int /* width */ = 0, int /* height */ = 0) const { return m_cachedImage ? m_cachedImage->image() : nullImage(); }
virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
virtual void setImageContainerSize(const IntSize& size) const;
......
......@@ -46,7 +46,7 @@ public:
virtual void shutdown();
virtual bool hasImage() const { return true; }
virtual Image* image(int width = 0, int height = 0) { return m_styleImage->image(m_renderer, IntSize(width, height)); }
virtual PassRefPtr<Image> image(int width = 0, int height = 0) const { return m_styleImage->image(m_renderer, IntSize(width, height)); }
virtual bool errorOccurred() const { return m_styleImage->errorOccurred(); }
virtual void setImageContainerSize(const IntSize& size) const { m_styleImage->setImageContainerSize(size); }
......
......@@ -1130,7 +1130,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
if (style()->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
paintCustomHighlight(tx, ty, style()->highlight(), true);
#endif
context->drawImage(m_image->image(this, marker.size()), style()->colorSpace(), marker);
context->drawImage(m_image->image(this, marker.size()).get(), style()->colorSpace(), marker);
if (selectionState() != SelectionNone) {
IntRect selRect = localSelectionRect();
selRect.move(boxOrigin.x(), boxOrigin.y());
......
......@@ -84,7 +84,7 @@ void StyleCachedImage::removeClient(RenderObject* renderer)
return m_image->removeClient(renderer);
}
Image* StyleCachedImage::image(RenderObject*, const IntSize&) const
PassRefPtr<Image> StyleCachedImage::image(RenderObject*, const IntSize&) const
{
return m_image->image();
}
......
......@@ -52,7 +52,7 @@ public:
virtual void setImageContainerSize(const IntSize&);
virtual void addClient(RenderObject*);
virtual void removeClient(RenderObject*);
virtual Image* image(RenderObject*, const IntSize&) const;
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
private:
StyleCachedImage(CachedImage* image)
......
......@@ -72,7 +72,7 @@ void StyleGeneratedImage::removeClient(RenderObject* renderer)
m_generator->removeClient(renderer);
}
Image* StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const
PassRefPtr<Image> StyleGeneratedImage::image(RenderObject* renderer, const IntSize& size) const
{
return m_generator->image(renderer, size);
}
......
......@@ -51,7 +51,7 @@ public:
virtual void setImageContainerSize(const IntSize&);
virtual void addClient(RenderObject*);
virtual void removeClient(RenderObject*);
virtual Image* image(RenderObject*, const IntSize&) const;
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
private:
StyleGeneratedImage(CSSImageGeneratorValue* val, bool fixedSize)
......
......@@ -25,6 +25,7 @@
#define StyleImage_h
#include "CSSValue.h"
#include "Image.h"
#include "IntSize.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
......@@ -33,7 +34,6 @@
namespace WebCore {
class CSSValue;
class Image;
class RenderObject;
typedef void* WrappedImagePtr;
......@@ -59,7 +59,7 @@ public:
virtual void setImageContainerSize(const IntSize&) = 0;
virtual void addClient(RenderObject*) = 0;
virtual void removeClient(RenderObject*) = 0;
virtual Image* image(RenderObject*, const IntSize&) const = 0;
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const = 0;
virtual WrappedImagePtr data() const = 0;
virtual bool isCachedImage() const { return false; }
......
......@@ -26,6 +26,7 @@
#ifndef StylePendingImage_h
#define StylePendingImage_h
#include "Image.h"
#include "StyleImage.h"
namespace WebCore {
......@@ -52,7 +53,7 @@ public:
virtual void setImageContainerSize(const IntSize&) { }
virtual void addClient(RenderObject*) { }
virtual void removeClient(RenderObject*) { }
virtual Image* image(RenderObject*, const IntSize&) const
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const
{
ASSERT_NOT_REACHED();
return 0;
......
......@@ -122,7 +122,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
PaintInfo savedInfo(childPaintInfo);
if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
Image* image = m_imageResource->image();
RefPtr<Image> image = m_imageResource->image();
FloatRect destRect = m_objectBoundingBox;
FloatRect srcRect(0, 0, image->width(), image->height());
......@@ -130,7 +130,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
if (imageElement->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
childPaintInfo.context->drawImage(image, ColorSpaceDeviceRGB, destRect, srcRect);
childPaintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
}
SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment