DrawTarget* ContentClientIncremental::BorrowDrawTargetForPainting(const PaintState& aPaintState, RotatedContentBuffer::DrawIterator* aIter) { if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) { return nullptr; } if (aIter) { if (aIter->mCount++ > 0) { return nullptr; } aIter->mDrawRegion = aPaintState.mRegionToDraw; } DrawTarget* result = nullptr; nsIntRect drawBounds = aPaintState.mRegionToDraw.GetBounds(); MOZ_ASSERT(!mLoanedDrawTarget); // BeginUpdate is allowed to modify the given region, // if it wants more to be repainted than we request. if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) { nsIntRegion drawRegionCopy = aPaintState.mRegionToDraw; RefPtr<DrawTarget> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy); RefPtr<DrawTarget> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw); if (onBlack && onWhite) { NS_ASSERTION(aPaintState.mRegionToDraw == drawRegionCopy, "BeginUpdate should always modify the draw region in the same way!"); FillSurface(onBlack, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0)); FillSurface(onWhite, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0)); mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlack, onWhite); } else { mLoanedDrawTarget = nullptr; } } else { mLoanedDrawTarget = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw); } if (!mLoanedDrawTarget) { NS_WARNING("unable to get context for update"); return nullptr; } result = mLoanedDrawTarget; mLoanedTransform = mLoanedDrawTarget->GetTransform(); mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y); result->SetTransform(mLoanedTransform); mLoanedTransform.Translate(drawBounds.x, drawBounds.y); if (mContentType == gfxContentType::COLOR_ALPHA) { gfxUtils::ClipToRegion(result, aPaintState.mRegionToDraw); nsIntRect bounds = aPaintState.mRegionToDraw.GetBounds(); result->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height)); } return result; }
void gfxSurfaceDrawable::DrawInternal(gfxContext* aContext, const gfxRect& aFillRect, const IntRect& aSamplingRect, bool aRepeat, const GraphicsFilter& aFilter, gfxFloat aOpacity, const gfxMatrix& aTransform) { ExtendMode extend = ExtendMode::CLAMP; if (aRepeat) { extend = ExtendMode::REPEAT; } Matrix patternTransform = ToMatrix(aTransform * mTransform); patternTransform.Invert(); SurfacePattern pattern(mSourceSurface, extend, patternTransform, ToFilter(aFilter), aSamplingRect); Rect fillRect = ToRect(aFillRect); DrawTarget* dt = aContext->GetDrawTarget(); if (aContext->CurrentOperator() == gfxContext::OPERATOR_CLEAR) { dt->ClearRect(fillRect); } else if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE && aOpacity == 1.0) { // Emulate cairo operator source which is bound by mask! dt->ClearRect(fillRect); dt->FillRect(fillRect, pattern); } else { dt->FillRect(fillRect, pattern, DrawOptions(aOpacity, CompositionOpForOp(aContext->CurrentOperator()), aContext->CurrentAntialiasMode())); } }
bool gfxSurfaceDrawable::Draw(gfxContext* aContext, const gfxRect& aFillRect, bool aRepeat, const GraphicsFilter& aFilter, const gfxMatrix& aTransform) { ExtendMode extend = ExtendMode::CLAMP; if (aRepeat) { extend = ExtendMode::REPEAT; } Matrix patternTransform = ToMatrix(aTransform * mTransform); patternTransform.Invert(); SurfacePattern pattern(mSourceSurface, extend, patternTransform, ToFilter(aFilter)); Rect fillRect = ToRect(aFillRect); DrawTarget* dt = aContext->GetDrawTarget(); if (aContext->CurrentOperator() == gfxContext::OPERATOR_CLEAR) { dt->ClearRect(fillRect); } else if (aContext->CurrentOperator() == gfxContext::OPERATOR_SOURCE) { // Emulate cairo operator source which is bound by mask! dt->ClearRect(fillRect); dt->FillRect(fillRect, pattern); } else { CompositionOp op = CompositionOpForOp(aContext->CurrentOperator()); AntialiasMode aaMode = aContext->CurrentAntialiasMode() == gfxContext::MODE_ALIASED ? AntialiasMode::NONE : AntialiasMode::SUBPIXEL; dt->FillRect(fillRect, pattern, DrawOptions(1.0f, op, aaMode)); } return true; }