mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-11 16:32:59 +00:00
Bug 603488 part 2: Draw vector images using imgIContainer::Draw() r=roc
--HG-- extra : rebase_source : 008db87e0322b9e7fa15e21b2b3e51b368225e58
This commit is contained in:
parent
6921e1c6c5
commit
4fdc9b95a2
@ -358,6 +358,11 @@ public:
|
||||
mCtx->CurrentState().op);
|
||||
}
|
||||
|
||||
operator DrawTarget*()
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
DrawTarget* operator->()
|
||||
{
|
||||
return mTarget;
|
||||
@ -3094,14 +3099,17 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
|
||||
CanvasImageCache::Lookup(element, mCanvasElement, &imgSize);
|
||||
}
|
||||
|
||||
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, mTarget);
|
||||
|
||||
if (!res.mSourceSurface) {
|
||||
if (!res.mSourceSurface && !res.mDrawInfo.mImgContainer) {
|
||||
// Spec says to silently do nothing if the element is still loading.
|
||||
if (!res.mIsStillLoading) {
|
||||
error.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
@ -3126,12 +3134,16 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
|
||||
res.mCORSUsed);
|
||||
}
|
||||
|
||||
if (res.mImageRequest) {
|
||||
CanvasImageCache::NotifyDrawImage(element, mCanvasElement, res.mImageRequest,
|
||||
res.mSourceSurface, imgSize);
|
||||
}
|
||||
if (res.mSourceSurface) {
|
||||
if (res.mImageRequest) {
|
||||
CanvasImageCache::NotifyDrawImage(element, mCanvasElement, res.mImageRequest,
|
||||
res.mSourceSurface, imgSize);
|
||||
}
|
||||
|
||||
srcSurf = res.mSourceSurface;
|
||||
srcSurf = res.mSourceSurface;
|
||||
} else {
|
||||
drawInfo = res.mDrawInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (optional_argc == 0) {
|
||||
@ -3178,16 +3190,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_CLAMP is added for increased performance
|
||||
uint32_t modifiedFlags = image.mDrawingFlags | imgIContainer::FLAG_CLAMP;
|
||||
|
||||
nsresult rv = image.mImgContainer->
|
||||
Draw(context, GraphicsFilter::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);
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static bool
|
||||
IsStandardCompositeOp(CompositionOp op)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "imgIEncoder.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
class nsGlobalWindow;
|
||||
class nsXULElement;
|
||||
@ -579,6 +580,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 */
|
||||
|
Loading…
Reference in New Issue
Block a user