зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1295094 - Part 1. Simplify the logic in nsSVGIntegrationUtils::PaintFramesWithEffects. r=mstange
MozReview-Commit-ID: HbQIrhtChCC --HG-- extra : rebase_source : 3bea6d260495c87291142249d9dc12571ee62899
This commit is contained in:
Родитель
a1bd244c06
Коммит
9ac4909e0a
|
@ -718,19 +718,46 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
|||
bool shouldGenerateMaskLayer = maskFrames.Length() == 1 && maskFrames[0];
|
||||
#endif
|
||||
|
||||
bool shouldGenerateClipMaskLayer = clipPathFrame && !isTrivialClip;
|
||||
bool shouldApplyClipPath = clipPathFrame && isTrivialClip;
|
||||
bool shouldApplyBasicShape = !clipPathFrame && svgReset->HasClipPath();
|
||||
MOZ_ASSERT_IF(shouldGenerateClipMaskLayer,
|
||||
!shouldApplyClipPath && !shouldApplyBasicShape);
|
||||
|
||||
// These are used if we require a temporary surface for a custom blend mode.
|
||||
RefPtr<gfxContext> target = &aParams.ctx;
|
||||
IntPoint targetOffset;
|
||||
|
||||
bool complexEffects = false;
|
||||
if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
// Create a temporary context to draw to so we can blend it back with
|
||||
// another operator.
|
||||
gfxRect clipRect;
|
||||
{
|
||||
gfxContextMatrixAutoSaveRestore matRestore(&context);
|
||||
|
||||
context.SetMatrix(gfxMatrix());
|
||||
clipRect = context.GetClipExtents();
|
||||
}
|
||||
|
||||
IntRect drawRect = RoundedOut(ToRect(clipRect));
|
||||
|
||||
RefPtr<DrawTarget> targetDT = context.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
if (!targetDT || !targetDT->IsValid()) {
|
||||
return DrawResult::TEMPORARY_ERROR;
|
||||
}
|
||||
target = gfxContext::CreateOrNull(targetDT);
|
||||
MOZ_ASSERT(target); // already checked the draw target above
|
||||
target->SetMatrix(context.CurrentMatrix() * gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||
targetOffset = drawRect.TopLeft();
|
||||
}
|
||||
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
bool shouldGenerateMask = (opacity != 1.0f || shouldGenerateClipMaskLayer ||
|
||||
shouldGenerateMaskLayer);
|
||||
|
||||
/* Check if we need to do additional operations on this child's
|
||||
* rendering, which necessitates rendering into another surface. */
|
||||
if (opacity != 1.0f || (clipPathFrame && !isTrivialClip)
|
||||
|| frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL
|
||||
|| shouldGenerateMaskLayer) {
|
||||
complexEffects = true;
|
||||
|
||||
if (shouldGenerateMask) {
|
||||
context.Save();
|
||||
nsRect clipRect =
|
||||
frame->GetVisualOverflowRectRelativeToSelf() + toUserSpace;
|
||||
|
@ -752,31 +779,7 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
|||
return result;
|
||||
}
|
||||
|
||||
if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
// Create a temporary context to draw to so we can blend it back with
|
||||
// another operator.
|
||||
gfxRect clipRect;
|
||||
{
|
||||
gfxContextMatrixAutoSaveRestore matRestore(&context);
|
||||
|
||||
context.SetMatrix(gfxMatrix());
|
||||
clipRect = context.GetClipExtents();
|
||||
}
|
||||
|
||||
IntRect drawRect = RoundedOut(ToRect(clipRect));
|
||||
|
||||
RefPtr<DrawTarget> targetDT = context.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
if (!targetDT || !targetDT->IsValid()) {
|
||||
context.Restore();
|
||||
return result;
|
||||
}
|
||||
target = gfxContext::CreateOrNull(targetDT);
|
||||
MOZ_ASSERT(target); // already checked the draw target above
|
||||
target->SetMatrix(context.CurrentMatrix() * gfxMatrix::Translation(-drawRect.TopLeft()));
|
||||
targetOffset = drawRect.TopLeft();
|
||||
}
|
||||
|
||||
if (clipPathFrame && !isTrivialClip) {
|
||||
if (shouldGenerateClipMaskLayer) {
|
||||
Matrix clippedMaskTransform;
|
||||
RefPtr<SourceSurface> clipMaskSurface =
|
||||
clipPathFrame->GetClipMask(context, frame, cssPxToDevPxMatrix,
|
||||
|
@ -789,19 +792,16 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
|||
}
|
||||
}
|
||||
|
||||
if (opacity != 1.0f || shouldGenerateMaskLayer ||
|
||||
(clipPathFrame && !isTrivialClip)) {
|
||||
target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity, maskSurface, maskTransform);
|
||||
}
|
||||
target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity, maskSurface, maskTransform);
|
||||
}
|
||||
|
||||
/* If this frame has only a trivial clipPath, set up cairo's clipping now so
|
||||
* we can just do normal painting and get it clipped appropriately.
|
||||
*/
|
||||
if (clipPathFrame && isTrivialClip) {
|
||||
if (shouldApplyClipPath) {
|
||||
context.Save();
|
||||
clipPathFrame->ApplyClipPath(context, frame, cssPxToDevPxMatrix);
|
||||
} else if (!clipPathFrame && svgReset->HasClipPath()) {
|
||||
} else if (shouldApplyBasicShape) {
|
||||
context.Save();
|
||||
nsCSSClipPathInstance::ApplyBasicShapeClip(context, frame);
|
||||
}
|
||||
|
@ -825,19 +825,13 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
|||
basic->SetTarget(oldCtx);
|
||||
}
|
||||
|
||||
if ((clipPathFrame && isTrivialClip) ||
|
||||
(!clipPathFrame && svgReset->HasClipPath())) {
|
||||
if (shouldApplyClipPath || shouldApplyBasicShape) {
|
||||
context.Restore();
|
||||
}
|
||||
|
||||
/* No more effects, we're done. */
|
||||
if (!complexEffects) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (opacity != 1.0f || shouldGenerateMaskLayer ||
|
||||
(clipPathFrame && !isTrivialClip)) {
|
||||
if (shouldGenerateMask) {
|
||||
target->PopGroupAndBlend();
|
||||
context.Restore();
|
||||
}
|
||||
|
||||
if (frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
|
@ -845,13 +839,13 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
|
|||
target = nullptr;
|
||||
RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();
|
||||
|
||||
gfxContextAutoSaveRestore save(&context);
|
||||
context.SetMatrix(gfxMatrix()); // This will be restored right after.
|
||||
RefPtr<gfxPattern> pattern = new gfxPattern(targetSurf, Matrix::Translation(targetOffset.x, targetOffset.y));
|
||||
context.SetPattern(pattern);
|
||||
context.Paint();
|
||||
}
|
||||
|
||||
context.Restore();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче