mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1224976. Recover from singular-matrix cairo errors. r=mattwoodrow
This commit is contained in:
parent
d2e0f299e2
commit
1ed2fac306
@ -590,6 +590,7 @@ NeedIntermediateSurface(const Pattern& aPattern, const DrawOptions& aOptions)
|
||||
DrawTargetCairo::DrawTargetCairo()
|
||||
: mContext(nullptr)
|
||||
, mSurface(nullptr)
|
||||
, mTransformSingular(false)
|
||||
, mLockedBits(nullptr)
|
||||
{
|
||||
}
|
||||
@ -775,6 +776,10 @@ DrawTargetCairo::DrawSurface(SourceSurface *aSurface,
|
||||
const DrawSurfaceOptions &aSurfOptions,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
AutoClearDeviceOffset clear(aSurface);
|
||||
|
||||
@ -968,6 +973,10 @@ DrawTargetCairo::FillRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
|
||||
bool restoreTransform = false;
|
||||
@ -1043,6 +1052,10 @@ DrawTargetCairo::CopySurface(SourceSurface *aSurface,
|
||||
const IntRect &aSource,
|
||||
const IntPoint &aDest)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
AutoClearDeviceOffset clear(aSurface);
|
||||
|
||||
@ -1065,6 +1078,10 @@ void
|
||||
DrawTargetCairo::CopyRect(const IntRect &aSource,
|
||||
const IntPoint &aDest)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
|
||||
IntRect source = aSource;
|
||||
@ -1097,6 +1114,10 @@ DrawTargetCairo::CopyRect(const IntRect &aSource,
|
||||
void
|
||||
DrawTargetCairo::ClearRect(const Rect& aRect)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
|
||||
if (!mContext || aRect.Width() <= 0 || aRect.Height() <= 0 ||
|
||||
@ -1119,6 +1140,10 @@ DrawTargetCairo::StrokeRect(const Rect &aRect,
|
||||
const StrokeOptions &aStrokeOptions /* = StrokeOptions() */,
|
||||
const DrawOptions &aOptions /* = DrawOptions() */)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
|
||||
cairo_new_path(mContext);
|
||||
@ -1134,6 +1159,10 @@ DrawTargetCairo::StrokeLine(const Point &aStart,
|
||||
const StrokeOptions &aStrokeOptions /* = StrokeOptions() */,
|
||||
const DrawOptions &aOptions /* = DrawOptions() */)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
|
||||
cairo_new_path(mContext);
|
||||
@ -1149,6 +1178,10 @@ DrawTargetCairo::Stroke(const Path *aPath,
|
||||
const StrokeOptions &aStrokeOptions /* = StrokeOptions() */,
|
||||
const DrawOptions &aOptions /* = DrawOptions() */)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext, aPath);
|
||||
|
||||
if (aPath->GetBackendType() != BackendType::CAIRO)
|
||||
@ -1165,6 +1198,10 @@ DrawTargetCairo::Fill(const Path *aPath,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions /* = DrawOptions() */)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext, aPath);
|
||||
|
||||
if (aPath->GetBackendType() != BackendType::CAIRO)
|
||||
@ -1193,6 +1230,10 @@ DrawTargetCairo::FillGlyphs(ScaledFont *aFont,
|
||||
const DrawOptions &aOptions,
|
||||
const GlyphRenderingOptions*)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
AutoClearDeviceOffset clear(aPattern);
|
||||
|
||||
@ -1232,6 +1273,10 @@ DrawTargetCairo::Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions /* = DrawOptions() */)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
AutoClearDeviceOffset clearSource(aSource);
|
||||
AutoClearDeviceOffset clearMask(aMask);
|
||||
@ -1270,6 +1315,10 @@ DrawTargetCairo::MaskSurface(const Pattern &aSource,
|
||||
Point aOffset,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
if (mTransformSingular) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoPrepareForDrawing prep(this, mContext);
|
||||
AutoClearDeviceOffset clearSource(aSource);
|
||||
AutoClearDeviceOffset clearMask(aMask);
|
||||
@ -1336,7 +1385,13 @@ DrawTargetCairo::PushClip(const Path *aPath)
|
||||
cairo_save(mContext);
|
||||
|
||||
PathCairo* path = const_cast<PathCairo*>(static_cast<const PathCairo*>(aPath));
|
||||
path->SetPathOnContext(mContext);
|
||||
|
||||
if (mTransformSingular) {
|
||||
cairo_new_path(mContext);
|
||||
cairo_rectangle(mContext, 0, 0, 0, 0);
|
||||
} else {
|
||||
path->SetPathOnContext(mContext);
|
||||
}
|
||||
cairo_clip_preserve(mContext);
|
||||
}
|
||||
|
||||
@ -1347,7 +1402,11 @@ DrawTargetCairo::PushClipRect(const Rect& aRect)
|
||||
cairo_save(mContext);
|
||||
|
||||
cairo_new_path(mContext);
|
||||
cairo_rectangle(mContext, aRect.X(), aRect.Y(), aRect.Width(), aRect.Height());
|
||||
if (mTransformSingular) {
|
||||
cairo_rectangle(mContext, 0, 0, 0, 0);
|
||||
} else {
|
||||
cairo_rectangle(mContext, aRect.X(), aRect.Y(), aRect.Width(), aRect.Height());
|
||||
}
|
||||
cairo_clip_preserve(mContext);
|
||||
}
|
||||
|
||||
@ -1364,9 +1423,6 @@ DrawTargetCairo::PopClip()
|
||||
cairo_restore(mContext);
|
||||
|
||||
cairo_set_matrix(mContext, &mat);
|
||||
|
||||
MOZ_ASSERT(cairo_status(mContext) || GetTransform() == Matrix(mat.xx, mat.yx, mat.xy, mat.yy, mat.x0, mat.y0),
|
||||
"Transforms are out of sync");
|
||||
}
|
||||
|
||||
already_AddRefed<PathBuilder>
|
||||
@ -1709,11 +1765,14 @@ DrawTargetCairo::WillChange(const Path* aPath /* = nullptr */)
|
||||
void
|
||||
DrawTargetCairo::SetTransform(const Matrix& aTransform)
|
||||
{
|
||||
mTransform = aTransform;
|
||||
DrawTarget::SetTransform(aTransform);
|
||||
|
||||
cairo_matrix_t mat;
|
||||
GfxMatrixToCairoMatrix(mTransform, mat);
|
||||
cairo_set_matrix(mContext, &mat);
|
||||
mTransformSingular = aTransform.IsSingular();
|
||||
if (!mTransformSingular) {
|
||||
cairo_matrix_t mat;
|
||||
GfxMatrixToCairoMatrix(mTransform, mat);
|
||||
cairo_set_matrix(mContext, &mat);
|
||||
}
|
||||
}
|
||||
|
||||
Rect
|
||||
|
@ -209,6 +209,7 @@ private: // data
|
||||
cairo_t* mContext;
|
||||
cairo_surface_t* mSurface;
|
||||
IntSize mSize;
|
||||
bool mTransformSingular;
|
||||
|
||||
uint8_t* mLockedBits;
|
||||
|
||||
|
2
layout/reftests/canvas/1224976-1-ref.html
Normal file
2
layout/reftests/canvas/1224976-1-ref.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE HTML>
|
||||
<div style="background:black; width:10px; height:10px"></div>
|
10
layout/reftests/canvas/1224976-1.html
Normal file
10
layout/reftests/canvas/1224976-1.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<canvas id="c"></canvas>
|
||||
<script>
|
||||
var ctx = c.getContext('2d');
|
||||
ctx.scale(0,1);
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(0, 0, 10, 10);
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.fillRect(0, 0, 10, 10);
|
||||
</script>
|
@ -107,3 +107,4 @@ fuzzy-if(azureQuartz,2,128) fuzzy-if(d2d,12,21) fuzzy-if(d2d&&/^Windows\x20NT\x2
|
||||
fuzzy-if(Mulet,45,2) == 1107096-invisibles.html 1107096-invisibles-ref.html
|
||||
== 1151821-1.html 1151821-1-ref.html
|
||||
== 1201272-1.html 1201272-1-ref.html
|
||||
== 1224976-1.html 1224976-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user