mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 603488 - Part 2: Draw vector images using imgIContainer::Draw(). r=roc
This commit is contained in:
parent
f466248eb7
commit
824097167f
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user