michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "DrawTargetDual.h" michael@0: #include "Tools.h" michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: michael@0: class DualSurface michael@0: { michael@0: public: michael@0: inline DualSurface(SourceSurface *aSurface) michael@0: { michael@0: if (aSurface->GetType() != SurfaceType::DUAL_DT) { michael@0: mA = mB = aSurface; michael@0: return; michael@0: } michael@0: michael@0: SourceSurfaceDual *ssDual = michael@0: static_cast(aSurface); michael@0: mA = ssDual->mA; michael@0: mB = ssDual->mB; michael@0: } michael@0: michael@0: SourceSurface *mA; michael@0: SourceSurface *mB; michael@0: }; michael@0: michael@0: /* This only needs to split patterns up for SurfacePatterns. Only in that michael@0: * case can we be dealing with a 'dual' source (SourceSurfaceDual) and do michael@0: * we need to pass separate patterns into our destination DrawTargets. michael@0: */ michael@0: class DualPattern michael@0: { michael@0: public: michael@0: inline DualPattern(const Pattern &aPattern) michael@0: : mPatternsInitialized(false) michael@0: { michael@0: if (aPattern.GetType() != PatternType::SURFACE) { michael@0: mA = mB = &aPattern; michael@0: return; michael@0: } michael@0: michael@0: const SurfacePattern *surfPat = michael@0: static_cast(&aPattern); michael@0: michael@0: if (surfPat->mSurface->GetType() != SurfaceType::DUAL_DT) { michael@0: mA = mB = &aPattern; michael@0: return; michael@0: } michael@0: michael@0: const SourceSurfaceDual *ssDual = michael@0: static_cast(surfPat->mSurface.get()); michael@0: mA = new (mSurfPatA.addr()) SurfacePattern(ssDual->mA, surfPat->mExtendMode, michael@0: surfPat->mMatrix, surfPat->mFilter); michael@0: mB = new (mSurfPatB.addr()) SurfacePattern(ssDual->mB, surfPat->mExtendMode, michael@0: surfPat->mMatrix, surfPat->mFilter); michael@0: mPatternsInitialized = true; michael@0: } michael@0: michael@0: inline ~DualPattern() michael@0: { michael@0: if (mPatternsInitialized) { michael@0: mA->~Pattern(); michael@0: mB->~Pattern(); michael@0: } michael@0: } michael@0: michael@0: ClassStorage mSurfPatA; michael@0: ClassStorage mSurfPatB; michael@0: michael@0: const Pattern *mA; michael@0: const Pattern *mB; michael@0: michael@0: bool mPatternsInitialized; michael@0: }; michael@0: michael@0: void michael@0: DrawTargetDual::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource, michael@0: const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions) michael@0: { michael@0: DualSurface surface(aSurface); michael@0: mA->DrawSurface(surface.mA, aDest, aSource, aSurfOptions, aOptions); michael@0: mB->DrawSurface(surface.mB, aDest, aSource, aSurfOptions, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest, michael@0: const Color &aColor, const Point &aOffset, michael@0: Float aSigma, CompositionOp aOp) michael@0: { michael@0: DualSurface surface(aSurface); michael@0: mA->DrawSurfaceWithShadow(surface.mA, aDest, aColor, aOffset, aSigma, aOp); michael@0: mB->DrawSurfaceWithShadow(surface.mB, aDest, aColor, aOffset, aSigma, aOp); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::MaskSurface(const Pattern &aSource, michael@0: SourceSurface *aMask, michael@0: Point aOffset, michael@0: const DrawOptions &aOptions) michael@0: { michael@0: DualPattern source(aSource); michael@0: DualSurface mask(aMask); michael@0: mA->MaskSurface(*source.mA, mask.mA, aOffset, aOptions); michael@0: mB->MaskSurface(*source.mB, mask.mB, aOffset, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::CopySurface(SourceSurface *aSurface, const IntRect &aSourceRect, michael@0: const IntPoint &aDestination) michael@0: { michael@0: DualSurface surface(aSurface); michael@0: mA->CopySurface(surface.mA, aSourceRect, aDestination); michael@0: mB->CopySurface(surface.mB, aSourceRect, aDestination); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->FillRect(aRect, *pattern.mA, aOptions); michael@0: mB->FillRect(aRect, *pattern.mB, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::StrokeRect(const Rect &aRect, const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->StrokeRect(aRect, *pattern.mA, aStrokeOptions, aOptions); michael@0: mB->StrokeRect(aRect, *pattern.mB, aStrokeOptions, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::StrokeLine(const Point &aStart, const Point &aEnd, const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->StrokeLine(aStart, aEnd, *pattern.mA, aStrokeOptions, aOptions); michael@0: mB->StrokeLine(aStart, aEnd, *pattern.mB, aStrokeOptions, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::Stroke(const Path *aPath, const Pattern &aPattern, michael@0: const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->Stroke(aPath, *pattern.mA, aStrokeOptions, aOptions); michael@0: mB->Stroke(aPath, *pattern.mB, aStrokeOptions, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->Fill(aPath, *pattern.mA, aOptions); michael@0: mB->Fill(aPath, *pattern.mB, aOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer, michael@0: const Pattern &aPattern, const DrawOptions &aOptions, michael@0: const GlyphRenderingOptions *aRenderingOptions) michael@0: { michael@0: DualPattern pattern(aPattern); michael@0: mA->FillGlyphs(aScaledFont, aBuffer, *pattern.mA, aOptions, aRenderingOptions); michael@0: mB->FillGlyphs(aScaledFont, aBuffer, *pattern.mB, aOptions, aRenderingOptions); michael@0: } michael@0: michael@0: void michael@0: DrawTargetDual::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions) michael@0: { michael@0: DualPattern source(aSource); michael@0: DualPattern mask(aMask); michael@0: mA->Mask(*source.mA, *mask.mA, aOptions); michael@0: mB->Mask(*source.mB, *mask.mB, aOptions); michael@0: } michael@0: michael@0: TemporaryRef michael@0: DrawTargetDual::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const michael@0: { michael@0: RefPtr dtA = mA->CreateSimilarDrawTarget(aSize, aFormat); michael@0: RefPtr dtB = mB->CreateSimilarDrawTarget(aSize, aFormat); michael@0: michael@0: return new DrawTargetDual(dtA, dtB); michael@0: } michael@0: michael@0: } michael@0: }