Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1082)

Unified Diff: Source/core/html/canvas/CanvasRenderingContext2D.cpp

Issue 181693006: Refactoring source image usage in CanvasRenderingContext2D (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: applied last corrections Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/html/canvas/CanvasRenderingContext2D.cpp
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
index 12d8c84c69d0c765b3d1978a0f1fd6f8b5212665..957104bfc191a181dbfdd1af98ee347138d0e7c5 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -63,7 +63,6 @@
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/DrawLooper.h"
#include "platform/text/TextRun.h"
-#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/CheckedArithmetic.h"
#include "wtf/MathExtras.h"
#include "wtf/OwnPtr.h"
@@ -290,8 +289,9 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_strokeStyle = style.release();
@@ -322,8 +322,9 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_fillStyle = style.release();
@@ -1305,26 +1306,6 @@ enum ImageSizeType {
ImageSizeBeforeDevicePixelRatio
};
-static LayoutSize sizeFor(HTMLImageElement* image, ImageSizeType sizeType)
-{
- LayoutSize size;
- ImageResource* cachedImage = image->cachedImage();
- if (cachedImage) {
- size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
-
- if (sizeType == ImageSizeAfterDevicePixelRatio && image->renderer() && image->renderer()->isRenderImage() && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
- size.scale(toRenderImage(image->renderer())->imageDevicePixelRatio());
- }
- return size;
-}
-
-static IntSize sizeFor(HTMLVideoElement* video)
-{
- if (MediaPlayer* player = video->player())
- return player->naturalSize();
- return IntSize();
-}
-
static inline FloatRect normalizeRect(const FloatRect& rect)
{
return FloatRect(min(rect.x(), rect.maxX()),
@@ -1352,341 +1333,126 @@ static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s
dstRect->move(offset);
}
-void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode)
+static bool checkImageSource(CanvasImageSource* imageSource, ExceptionState& exceptionState)
{
- if (!image)
- return;
-
- GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
- FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
- return;
-
- if (rectContainsTransformedRect(dstRect, clipBounds)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(op)) {
- fullCanvasCompositedDrawImage(image, dstRect, srcRect, op);
- didDraw(clipBounds);
- } else if (op == CompositeCopy) {
- clearCanvas();
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else {
- FloatRect dirtyRect;
- if (computeDirtyRect(dstRect, &dirtyRect)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(dirtyRect);
- }
+ if (!imageSource) {
+ // FIXME: Message should mention ImageBitmap once that feature ships.
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, String("HTMLImageElement, HTMLCanvasElement or HTMLVideoElement")));
+ return false;
}
+ return true;
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, float x, float y, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, float x, float y, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageBitmap"));
+ if (!checkImageSource(imageSource, exceptionState))
return;
- }
- drawImage(bitmap, x, y, bitmap->width(), bitmap->height(), exceptionState);
+ FloatSize destRectSize = imageSource->defaultDestinationSize();
+ drawImage(imageSource, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float x, float y, float width, float height, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageBitmap"));
+ if (!checkImageSource(imageSource, exceptionState))
return;
- }
- if (!bitmap->bitmapRect().width() || !bitmap->bitmapRect().height())
- return;
-
- drawImage(bitmap, 0, 0, bitmap->width(), bitmap->height(), x, y, width, height, exceptionState);
+ FloatSize sourceRectSize = imageSource->sourceSize();
+ drawImage(imageSource, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageBitmap"));
- return;
- }
-
- FloatRect srcRect(sx, sy, sw, sh);
- FloatRect dstRect(dx, dy, dw, dh);
- FloatRect bitmapRect = bitmap->bitmapRect();
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
-
- if (!dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height())
- return;
-
- ASSERT(bitmap->height() && bitmap->width());
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- // Clip the rects to where the user thinks that the image is situated.
- clipRectsToImageRect(IntRect(IntPoint(), bitmap->size()), &normalizedSrcRect, &normalizedDstRect);
-
- FloatRect intersectRect = intersection(bitmapRect, normalizedSrcRect);
- FloatRect actualSrcRect(intersectRect);
-
- IntPoint bitmapOffset = bitmap->bitmapOffset();
- actualSrcRect.move(bitmapOffset - bitmapRect.location());
- FloatRect imageRect = FloatRect(bitmapOffset, bitmapRect.size());
-
- FloatRect actualDstRect(FloatPoint(intersectRect.location() - normalizedSrcRect.location()), bitmapRect.size());
- actualDstRect.scale(normalizedDstRect.width() / normalizedSrcRect.width() * intersectRect.width() / bitmapRect.width(),
- normalizedDstRect.height() / normalizedSrcRect.height() * intersectRect.height() / bitmapRect.height());
- actualDstRect.moveBy(normalizedDstRect.location());
-
- if (!imageRect.intersects(actualSrcRect))
- return;
-
- RefPtr<Image> imageForRendering = bitmap->bitmapImage();
- if (!imageForRendering)
- return;
-
- drawImageInternal(imageForRendering.get(), actualSrcRect, actualDstRect, state().m_globalComposite, state().m_globalBlend);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLImageElement"));
- return;
- }
- LayoutSize destRectSize = sizeFor(image, ImageSizeAfterDevicePixelRatio);
- drawImage(image, x, y, destRectSize.width().toFloat(), destRectSize.height().toFloat(), exceptionState);
+ GraphicsContext* c = drawingContext(); // Do not exit yet if !c because we may need to throw exceptions first
+ CompositeOperator op = c ? c->compositeOperation() : CompositeSourceOver;
+ blink::WebBlendMode blendMode = c ? c->blendModeOperation() : blink::WebBlendModeNormal;
+ drawImageInternal(imageSource, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState, op, blendMode);
}
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLImageElement"));
- return;
- }
- LayoutSize sourceRectSize = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- drawImage(image, FloatRect(0, 0, sourceRectSize.width().toFloat(), sourceRectSize.height().toFloat()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
+void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
+ float dx, float dy, float dw, float dh, ExceptionState& exceptionState,
+ CompositeOperator op, blink::WebBlendMode blendMode)
{
- drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_globalBlend, exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLImageElement"));
- return;
- }
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
+ if (!checkImageSource(imageSource, exceptionState))
return;
- ImageResource* cachedImage = image->cachedImage();
- if (!cachedImage || !image->complete())
- return;
+ RefPtr<Image> image;
+ SourceImageStatus sourceImageStatus;
+ if (!imageSource->isVideoElement()) {
+ SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolatile : DontCopySourceImage; // Thunking for ==
+ image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus);
+ if (sourceImageStatus == UndecodableSourceImageStatus)
+ exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
+ if (!image || !image->width() || !image->height())
+ return;
+ }
- LayoutSize size = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- if (!size.width() || !size.height() || !dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height())
+ if (!state().m_invertibleCTM)
return;
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- FloatRect imageRect = FloatRect(FloatPoint(), size);
- if (!imageRect.intersects(normalizedSrcRect))
+ if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::isfinite(dh)
+ || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)
+ || !dw || !dh || !sw || !sh)
return;
- clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect);
-
- checkOrigin(image);
-
- Image* imageForRendering = cachedImage->imageForRenderer(image->renderer());
-
- // For images that depend on an unavailable container size, we need to fall back to the intrinsic
- // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage
- // FIXME: Without a specified image size this should resolve against the canvas element's size, see: crbug.com/230163.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
-
- drawImageInternal(imageForRendering, normalizedSrcRect, normalizedDstRect, op, blendMode);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(), x, y, sourceCanvas->width(), sourceCanvas->height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas->height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
- const FloatRect& dstRect, ExceptionState& exceptionState)
-{
- if (!sourceCanvas) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLCanvasElement"));
+ FloatRect clipBounds;
+ if (!drawingContext()->getTransformedClipBounds(&clipBounds))
return;
- }
- FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
+ FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
+ FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
- if (!srcCanvasRect.width() || !srcCanvasRect.height() || !srcRect.width() || !srcRect.height())
- return;
+ clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &srcRect, &dstRect);
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
+ imageSource->adjustDrawRects(&srcRect, &dstRect);
- if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
+ if (srcRect.isEmpty())
return;
- clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
if (!c)
return;
- if (!state().m_invertibleCTM)
- return;
-
- // FIXME: Do this through platform-independent GraphicsContext API.
- ImageBuffer* buffer = sourceCanvas->buffer();
- if (!buffer)
- return;
-
- FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
- return;
-
- checkOrigin(sourceCanvas);
-
- // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
- // as that will do a readback to software.
- CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
- // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
- if (sourceContext && sourceContext->is3d())
- sourceContext->paintRenderingResultsToCanvas();
- if (rectContainsTransformedRect(normalizedDstRect, clipBounds)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite);
- didDraw(clipBounds);
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
+ FloatRect dirtyRect = clipBounds;
+ if (imageSource->isVideoElement()) {
+ drawVideo(static_cast<HTMLVideoElement*>(imageSource), srcRect, dstRect);
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
} else {
- FloatRect dirtyRect;
- if (computeDirtyRect(normalizedDstRect, clipBounds, &dirtyRect)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(dirtyRect);
+ if (rectContainsTransformedRect(dstRect, clipBounds)) {
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else if (isFullCanvasCompositeMode(op)) {
+ fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op);
+ } else if (op == CompositeCopy) {
+ clearCanvas();
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else {
+ FloatRect dirtyRect;
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
}
- }
- // Flush canvas's ImageBuffer when drawImage from WebGL to HW accelerated 2d canvas
- if (sourceContext && sourceContext->is3d() && is2d() && isAccelerated() && canvas()->buffer())
- canvas()->buffer()->flush();
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLVideoElement"));
- return;
+ if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && canvas()->buffer())
+ canvas()->buffer()->flush();
}
- IntSize size = sizeFor(video);
- drawImage(video, x, y, size.width(), size.height(), exceptionState);
-}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLVideoElement"));
- return;
- }
- IntSize size = sizeFor(video);
- drawImage(video, FloatRect(0, 0, size.width(), size.height()), FloatRect(x, y, width, height), exceptionState);
-}
+ if (canvas()->originClean() && imageSource->wouldTaintOrigin(canvas()->securityOrigin()))
+ canvas()->setOriginTainted();
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
+ didDraw(dirtyRect);
}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcRect, FloatRect dstRect)
{
- if (!video) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLVideoElement"));
- return;
- }
-
- if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
- return;
- if (!srcRect.width() || !srcRect.height())
- return;
-
- FloatRect videoRect = FloatRect(FloatPoint(), sizeFor(video));
-
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
- return;
-
- clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
-
- checkOrigin(video);
-
- FloatRect dirtyRect;
- if (!computeDirtyRect(normalizedDstRect, &dirtyRect))
- return;
-
GraphicsContextStateSaver stateSaver(*c);
- c->clip(normalizedDstRect);
- c->translate(normalizedDstRect.x(), normalizedDstRect.y());
- c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), normalizedDstRect.height() / normalizedSrcRect.height()));
- c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y());
- video->paintCurrentFrameInContext(c, IntRect(IntPoint(), sizeFor(video)));
+ c->clip(dstRect);
+ c->translate(dstRect.x(), dstRect.y());
+ c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
+ c->translate(-srcRect.x(), -srcRect.y());
+ video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())));
stateSaver.restore();
-
- didDraw(dirtyRect);
}
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
@@ -1699,7 +1465,7 @@ void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blendOp != blink::WebBlendModeNormal)
op = CompositeSourceOver;
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, blink::WebBlendModeNormal, IGNORE_EXCEPTION);
+ drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, op, blendOp);
}
void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1737,11 +1503,6 @@ static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
context->drawImage(image, dest, src, op);
}
-static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
-{
- context->drawImageBuffer(imageBuffer, dest, src, op);
-}
-
template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
ASSERT(isFullCanvasCompositeMode(op));
@@ -1817,50 +1578,41 @@ PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float
return gradient.release();
}
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(CanvasImageSource* imageSource,
const String& repetitionType, ExceptionState& exceptionState)
{
- if (!image) {
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLImageElement"));
+ if (!checkImageSource(imageSource, exceptionState))
return nullptr;
- }
bool repeatX, repeatY;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
if (exceptionState.hadException())
return nullptr;
- if (!image->complete())
- return nullptr;
-
- ImageResource* cachedImage = image->cachedImage();
- Image* imageForRendering = cachedImage ? cachedImage->imageForRenderer(image->renderer()) : 0;
- if (!imageForRendering)
- return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
-
- // We need to synthesize a container size if a renderer is not available to provide one.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
+ SourceImageStatus status;
+ RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(CopySourceImageIfVolatile, &status);
- bool originClean = cachedImage->isAccessAllowed(canvas()->securityOrigin());
- return CanvasPattern::create(imageForRendering, repeatX, repeatY, originClean);
-}
-
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
- const String& repetitionType, ExceptionState& exceptionState)
-{
- if (!canvas)
- exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLCanvasElement"));
- else if (!canvas->width() || !canvas->height())
- exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", canvas->width() ? "height" : "width"));
-
- if (exceptionState.hadException())
+ switch (status) {
+ case NormalSourceImageStatus:
+ break;
+ case ZeroSizeCanvasSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", imageSource->sourceSize().width() ? "height" : "width"));
return nullptr;
-
- bool repeatX, repeatY;
- CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
- if (exceptionState.hadException())
+ case UndecodableSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, "Source image is in the 'broken' state.");
return nullptr;
- return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+ case InvalidSourceImageStatus:
+ imageForRendering = Image::nullImage();
+ break;
+ case IncompleteSourceImageStatus:
+ return nullptr;
+ default:
+ case ExternalSourceImageStatus: // should not happen when mode is CopySourceImageIfVolatile
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+ ASSERT(imageForRendering);
+
+ return CanvasPattern::create(imageForRendering.release(), repeatX, repeatY, !imageSource->wouldTaintOrigin(canvas()->securityOrigin()));
}
bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, FloatRect* dirtyRect)
« no previous file with comments | « Source/core/html/canvas/CanvasRenderingContext2D.h ('k') | Source/core/html/canvas/CanvasRenderingContext2D.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698