Bug 603488 - Part 2: Draw vector images using imgIContainer::Draw(). r=roc

This commit is contained in:
James Kolb 2013-07-13 15:13:54 -04:00
parent f466248eb7
commit 824097167f
2 changed files with 78 additions and 15 deletions

View File

@ -356,6 +356,11 @@ public:
mCtx->CurrentState().op);
}
operator DrawTarget*()
{
return mTarget;
}
DrawTarget* operator->()
{
return mTarget;
@ -3042,14 +3047,17 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
}
}
nsLayoutUtils::DirectDrawInfo drawInfo;
if (!srcSurf) {
// The canvas spec says that drawImage should draw the first frame
// of animated images
uint32_t sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME;
// of animated images. We also don't want to rasterize vector images.
uint32_t sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME |
nsLayoutUtils::SFE_NO_RASTERIZING_VECTORS;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(element, sfeFlags);
if (!res.mSurface) {
if (!res.mSurface && !res.mDrawInfo.mImgContainer) {
// Spec says to silently do nothing if the element is still loading.
if (!res.mIsStillLoading) {
error.Throw(NS_ERROR_NOT_AVAILABLE);
@ -3058,7 +3066,7 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
}
// Ignore cairo surfaces that are bad! See bug 666312.
if (res.mSurface->CairoStatus()) {
if (res.mSurface && res.mSurface->CairoStatus()) {
return;
}
@ -3070,12 +3078,16 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
res.mCORSUsed);
}
if (res.mImageRequest) {
CanvasImageCache::NotifyDrawImage(element, mCanvasElement,
res.mImageRequest, res.mSurface, imgSize);
}
if (res.mSurface) {
if (res.mImageRequest) {
CanvasImageCache::NotifyDrawImage(element, mCanvasElement,
res.mImageRequest, res.mSurface, imgSize);
}
srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
} else {
drawInfo = res.mDrawInfo;
}
}
if (optional_argc == 0) {
@ -3122,16 +3134,62 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
bounds = mTarget->GetTransform().TransformBounds(bounds);
}
AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
DrawSurface(srcSurf,
mgfx::Rect(dx, dy, dw, dh),
mgfx::Rect(sx, sy, sw, sh),
DrawSurfaceOptions(filter),
DrawOptions(CurrentState().globalAlpha, UsedOperation()));
if (srcSurf) {
AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)->
DrawSurface(srcSurf,
mgfx::Rect(dx, dy, dw, dh),
mgfx::Rect(sx, sy, sw, sh),
DrawSurfaceOptions(filter),
DrawOptions(CurrentState().globalAlpha, UsedOperation()));
} else {
DrawDirectlyToCanvas(drawInfo, &bounds, dx, dy, dw, dh,
sx, sy, sw, sh, imgSize);
}
RedrawUser(gfxRect(dx, dy, dw, dh));
}
void
CanvasRenderingContext2D::DrawDirectlyToCanvas(
const nsLayoutUtils::DirectDrawInfo& image,
mgfx::Rect* bounds, double dx, double dy,
double dw, double dh, double sx, double sy,
double sw, double sh, gfxIntSize imgSize)
{
gfxMatrix contextMatrix;
AdjustedTarget tempTarget(this, bounds->IsEmpty() ? nullptr: bounds);
// get any already existing transforms on the context. Include transformations used for context shadow
if (tempTarget) {
Matrix matrix = tempTarget->GetTransform();
contextMatrix = gfxMatrix(matrix._11, matrix._12, matrix._21,
matrix._22, matrix._31, matrix._32);
}
gfxMatrix transformMatrix;
transformMatrix.Translate(gfxPoint(sx, sy));
if (dw > 0 && dh > 0) {
transformMatrix.Scale(sw/dw, sh/dh);
}
transformMatrix.Translate(gfxPoint(-dx, -dy));
nsRefPtr<gfxContext> context = new gfxContext(tempTarget);
context->SetMatrix(contextMatrix);
// FLAG_CAMP is added for increased performance
uint32_t modifiedFlags = image.mDrawingFlags | imgIContainer::FLAG_CLAMP;
nsresult rv = image.mImgContainer->
Draw(context, gfxPattern::FILTER_GOOD, transformMatrix,
gfxRect(gfxPoint(dx, dy), gfxIntSize(dw, dh)),
nsIntRect(nsIntPoint(0, 0), gfxIntSize(imgSize.width, imgSize.height)),
gfxIntSize(imgSize.width, imgSize.height), nullptr, image.mWhichFrame,
modifiedFlags);
NS_ENSURE_SUCCESS_VOID(rv);
}
void
CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
ErrorResult& error)

View File

@ -548,6 +548,11 @@ protected:
double dx, double dy, double dw, double dh,
uint8_t optional_argc, mozilla::ErrorResult& error);
void DrawDirectlyToCanvas(const nsLayoutUtils::DirectDrawInfo& image,
mozilla::gfx::Rect* bounds, double dx, double dy,
double dw, double dh, double sx, double sy,
double sw, double sh, gfxIntSize imgSize);
nsString& GetFont()
{
/* will initilize the value if not set, else does nothing */