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:
cku 2016-08-15 23:04:50 +08:00
Родитель a1bd244c06
Коммит 9ac4909e0a
1 изменённых файлов: 41 добавлений и 47 удалений

Просмотреть файл

@ -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;
}