1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "DrawTargetTiled.h"
14 DrawTargetTiled::DrawTargetTiled()
19 DrawTargetTiled::Init(const TileSet
& aTiles
)
21 if (!aTiles
.mTileCount
) {
25 mTiles
.reserve(aTiles
.mTileCount
);
26 for (size_t i
= 0; i
< aTiles
.mTileCount
; ++i
) {
27 mTiles
.push_back(aTiles
.mTiles
[i
]);
28 if (!aTiles
.mTiles
[i
].mDrawTarget
) {
31 if (mTiles
[0].mDrawTarget
->GetFormat() != mTiles
.back().mDrawTarget
->GetFormat() ||
32 mTiles
[0].mDrawTarget
->GetBackendType() != mTiles
.back().mDrawTarget
->GetBackendType()) {
35 uint32_t newXMost
= max(mRect
.XMost(),
36 mTiles
[i
].mTileOrigin
.x
+ mTiles
[i
].mDrawTarget
->GetSize().width
);
37 uint32_t newYMost
= max(mRect
.YMost(),
38 mTiles
[i
].mTileOrigin
.y
+ mTiles
[i
].mDrawTarget
->GetSize().height
);
39 mRect
.x
= min(mRect
.x
, mTiles
[i
].mTileOrigin
.x
);
40 mRect
.y
= min(mRect
.y
, mTiles
[i
].mTileOrigin
.y
);
41 mRect
.width
= newXMost
- mRect
.x
;
42 mRect
.height
= newYMost
- mRect
.y
;
44 mFormat
= mTiles
[0].mDrawTarget
->GetFormat();
48 class SnapshotTiled
: public SourceSurface
51 SnapshotTiled(const vector
<Tile
>& aTiles
, const IntRect
& aRect
)
54 for (size_t i
= 0; i
< aTiles
.size(); i
++) {
55 mSnapshots
.push_back(aTiles
[i
].mDrawTarget
->Snapshot());
56 mOrigins
.push_back(aTiles
[i
].mTileOrigin
);
60 virtual SurfaceType
GetType() const { return SurfaceType::TILED
; }
61 virtual IntSize
GetSize() const { return IntSize(mRect
.XMost(), mRect
.YMost()); }
62 virtual SurfaceFormat
GetFormat() const { return mSnapshots
[0]->GetFormat(); }
64 virtual TemporaryRef
<DataSourceSurface
> GetDataSurface()
66 RefPtr
<DataSourceSurface
> surf
= Factory::CreateDataSourceSurface(GetSize(), GetFormat());
67 if (MOZ2D_WARN_IF(!surf
)) {
71 DataSourceSurface::MappedSurface mappedSurf
;
72 surf
->Map(DataSourceSurface::MapType::WRITE
, &mappedSurf
);
75 RefPtr
<DrawTarget
> dt
=
76 Factory::CreateDrawTargetForData(BackendType::CAIRO
, mappedSurf
.mData
,
77 GetSize(), mappedSurf
.mStride
, GetFormat());
79 for (size_t i
= 0; i
< mSnapshots
.size(); i
++) {
80 RefPtr
<DataSourceSurface
> dataSurf
= mSnapshots
[i
]->GetDataSurface();
81 dt
->CopySurface(dataSurf
, IntRect(IntPoint(0, 0), mSnapshots
[i
]->GetSize()), mOrigins
[i
]);
89 vector
<RefPtr
<SourceSurface
>> mSnapshots
;
90 vector
<IntPoint
> mOrigins
;
94 TemporaryRef
<SourceSurface
>
95 DrawTargetTiled::Snapshot()
97 return new SnapshotTiled(mTiles
, mRect
);
100 #define TILED_COMMAND(command) \
102 DrawTargetTiled::command() \
104 for (size_t i = 0; i < mTiles.size(); i++) { \
107 mTiles[i].mDrawTarget->command(); \
110 #define TILED_COMMAND1(command, type1) \
112 DrawTargetTiled::command(type1 arg1) \
114 for (size_t i = 0; i < mTiles.size(); i++) { \
117 mTiles[i].mDrawTarget->command(arg1); \
120 #define TILED_COMMAND3(command, type1, type2, type3) \
122 DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3) \
124 for (size_t i = 0; i < mTiles.size(); i++) { \
127 mTiles[i].mDrawTarget->command(arg1, arg2, arg3); \
130 #define TILED_COMMAND4(command, type1, type2, type3, type4) \
132 DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
134 for (size_t i = 0; i < mTiles.size(); i++) { \
137 mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4); \
140 #define TILED_COMMAND5(command, type1, type2, type3, type4, type5) \
142 DrawTargetTiled::command(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
144 for (size_t i = 0; i < mTiles.size(); i++) { \
147 mTiles[i].mDrawTarget->command(arg1, arg2, arg3, arg4, arg5); \
152 TILED_COMMAND5(DrawSurface
, SourceSurface
*, const Rect
&,
153 const Rect
&, const DrawSurfaceOptions
&,
155 TILED_COMMAND4(DrawFilter
, FilterNode
*, const Rect
&, const Point
&, const DrawOptions
&)
156 TILED_COMMAND1(ClearRect
, const Rect
&)
157 TILED_COMMAND4(MaskSurface
, const Pattern
&, SourceSurface
*, Point
, const DrawOptions
&)
158 TILED_COMMAND3(FillRect
, const Rect
&, const Pattern
&, const DrawOptions
&)
159 TILED_COMMAND4(StrokeRect
, const Rect
&, const Pattern
&, const StrokeOptions
&, const DrawOptions
&)
160 TILED_COMMAND5(StrokeLine
, const Point
&, const Point
&, const Pattern
&, const StrokeOptions
&, const DrawOptions
&)
161 TILED_COMMAND4(Stroke
, const Path
*, const Pattern
&, const StrokeOptions
&, const DrawOptions
&)
162 TILED_COMMAND3(Fill
, const Path
*, const Pattern
&, const DrawOptions
&)
163 TILED_COMMAND5(FillGlyphs
, ScaledFont
*, const GlyphBuffer
&, const Pattern
&, const DrawOptions
&, const GlyphRenderingOptions
*)
164 TILED_COMMAND3(Mask
, const Pattern
&, const Pattern
&, const DrawOptions
&)
165 TILED_COMMAND1(PushClip
, const Path
*)
166 TILED_COMMAND1(PushClipRect
, const Rect
&)
167 TILED_COMMAND(PopClip
)
170 DrawTargetTiled::CopySurface(SourceSurface
*aSurface
,
171 const IntRect
&aSourceRect
,
172 const IntPoint
&aDestination
)
174 // CopySurface ignores the transform, account for that here.
175 for (size_t i
= 0; i
< mTiles
.size(); i
++) {
176 IntRect src
= aSourceRect
;
177 src
.x
+= mTiles
[i
].mTileOrigin
.x
;
178 src
.width
-= mTiles
[i
].mTileOrigin
.x
;
179 src
.y
= mTiles
[i
].mTileOrigin
.y
;
180 src
.height
-= mTiles
[i
].mTileOrigin
.y
;
182 if (src
.width
<= 0 || src
.height
<= 0) {
186 mTiles
[i
].mDrawTarget
->CopySurface(aSurface
, src
, aDestination
);
191 DrawTargetTiled::SetTransform(const Matrix
& aTransform
)
193 for (size_t i
= 0; i
< mTiles
.size(); i
++) {
194 Matrix mat
= aTransform
;
195 mat
.PostTranslate(Float(-mTiles
[i
].mTileOrigin
.x
), Float(-mTiles
[i
].mTileOrigin
.y
));
196 mTiles
[i
].mDrawTarget
->SetTransform(mat
);
198 DrawTarget::SetTransform(aTransform
);