OLD | NEW |
| (Empty) |
1 /* libs/graphics/effects/SkLayerRasterizer.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkLayerRasterizer.h" | |
19 #include "SkBuffer.h" | |
20 #include "SkDraw.h" | |
21 #include "SkMask.h" | |
22 #include "SkMaskFilter.h" | |
23 #include "SkPaint.h" | |
24 #include "SkPath.h" | |
25 #include "SkRegion.h" | |
26 #include "SkXfermode.h" | |
27 #include <new> | |
28 | |
29 struct SkLayerRasterizer_Rec { | |
30 SkPaint fPaint; | |
31 SkVector fOffset; | |
32 }; | |
33 | |
34 SkLayerRasterizer::SkLayerRasterizer() : fLayers(sizeof(SkLayerRasterizer_Rec)) | |
35 { | |
36 } | |
37 | |
38 SkLayerRasterizer::~SkLayerRasterizer() | |
39 { | |
40 SkDeque::Iter iter(fLayers); | |
41 SkLayerRasterizer_Rec* rec; | |
42 | |
43 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
44 rec->fPaint.~SkPaint(); | |
45 } | |
46 | |
47 void SkLayerRasterizer::addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy) | |
48 { | |
49 SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back(); | |
50 | |
51 new (&rec->fPaint) SkPaint(paint); | |
52 rec->fOffset.set(dx, dy); | |
53 } | |
54 | |
55 static bool compute_bounds(const SkDeque& layers, const SkPath& path, const SkMa
trix& matrix, | |
56 const SkIRect* clipBounds, SkIRect* bounds) | |
57 { | |
58 SkDeque::Iter iter(layers); | |
59 SkLayerRasterizer_Rec* rec; | |
60 | |
61 bounds->set(SK_MaxS32, SK_MaxS32, SK_MinS32, SK_MinS32); | |
62 | |
63 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
64 { | |
65 const SkPaint& paint = rec->fPaint; | |
66 SkPath fillPath, devPath; | |
67 const SkPath* p = &path; | |
68 | |
69 if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) | |
70 { | |
71 paint.getFillPath(path, &fillPath); | |
72 p = &fillPath; | |
73 } | |
74 if (p->isEmpty()) | |
75 continue; | |
76 | |
77 // apply the matrix and offset | |
78 { | |
79 SkMatrix m = matrix; | |
80 m.preTranslate(rec->fOffset.fX, rec->fOffset.fY); | |
81 p->transform(m, &devPath); | |
82 } | |
83 | |
84 SkMask mask; | |
85 if (!SkDraw::DrawToMask(devPath, clipBounds, paint.getMaskFilter(), &mat
rix, | |
86 &mask, SkMask::kJustComputeBounds_CreateMode)) | |
87 return false; | |
88 | |
89 bounds->join(mask.fBounds); | |
90 } | |
91 return true; | |
92 } | |
93 | |
94 bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, | |
95 const SkIRect* clipBounds, | |
96 SkMask* mask, SkMask::CreateMode mode) | |
97 { | |
98 if (fLayers.empty()) | |
99 return false; | |
100 | |
101 if (SkMask::kJustRenderImage_CreateMode != mode) | |
102 { | |
103 if (!compute_bounds(fLayers, path, matrix, clipBounds, &mask->fBounds)) | |
104 return false; | |
105 } | |
106 | |
107 if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) | |
108 { | |
109 mask->fFormat = SkMask::kA8_Format; | |
110 mask->fRowBytes = SkToU16(mask->fBounds.width()); | |
111 size_t size = mask->computeImageSize(); | |
112 if (0 == size) { | |
113 return false; // too big to allocate, abort | |
114 } | |
115 mask->fImage = SkMask::AllocImage(size); | |
116 memset(mask->fImage, 0, size); | |
117 } | |
118 | |
119 if (SkMask::kJustComputeBounds_CreateMode != mode) | |
120 { | |
121 SkBitmap device; | |
122 SkDraw draw; | |
123 SkMatrix translatedMatrix; // this translates us to our local pixels | |
124 SkMatrix drawMatrix; // this translates the path by each layer's
offset | |
125 SkRegion rectClip; | |
126 | |
127 rectClip.setRect(0, 0, mask->fBounds.width(), mask->fBounds.height()); | |
128 | |
129 translatedMatrix = matrix; | |
130 translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), | |
131 -SkIntToScalar(mask->fBounds.fTop)); | |
132 | |
133 device.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), mask->fBou
nds.height(), mask->fRowBytes); | |
134 device.setPixels(mask->fImage); | |
135 | |
136 draw.fBitmap = &device; | |
137 draw.fMatrix = &drawMatrix; | |
138 draw.fClip = &rectClip; | |
139 // we set the matrixproc in the loop, as the matrix changes each time (p
otentially) | |
140 draw.fBounder = NULL; | |
141 | |
142 SkDeque::Iter iter(fLayers); | |
143 SkLayerRasterizer_Rec* rec; | |
144 | |
145 while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { | |
146 drawMatrix = translatedMatrix; | |
147 drawMatrix.preTranslate(rec->fOffset.fX, rec->fOffset.fY); | |
148 draw.drawPath(path, rec->fPaint); | |
149 } | |
150 } | |
151 return true; | |
152 } | |
153 | |
154 /////////// Routines for flattening ///////////////// | |
155 | |
156 static void paint_read(SkPaint* paint, SkFlattenableReadBuffer& buffer) | |
157 { | |
158 paint->setAntiAlias(buffer.readBool()); | |
159 paint->setStyle((SkPaint::Style)buffer.readU8()); | |
160 paint->setAlpha(buffer.readU8()); | |
161 | |
162 if (paint->getStyle() != SkPaint::kFill_Style) | |
163 { | |
164 paint->setStrokeWidth(buffer.readScalar()); | |
165 paint->setStrokeMiter(buffer.readScalar()); | |
166 paint->setStrokeCap((SkPaint::Cap)buffer.readU8()); | |
167 paint->setStrokeJoin((SkPaint::Join)buffer.readU8()); | |
168 } | |
169 | |
170 paint->setMaskFilter((SkMaskFilter*)buffer.readFlattenable())->safeUnref(); | |
171 paint->setPathEffect((SkPathEffect*)buffer.readFlattenable())->safeUnref(); | |
172 paint->setRasterizer((SkRasterizer*)buffer.readFlattenable())->safeUnref(); | |
173 paint->setXfermode((SkXfermode*)buffer.readFlattenable())->safeUnref(); | |
174 } | |
175 | |
176 static void paint_write(const SkPaint& paint, SkFlattenableWriteBuffer& buffer) | |
177 { | |
178 buffer.writeBool(paint.isAntiAlias()); | |
179 buffer.write8(paint.getStyle()); | |
180 buffer.write8(paint.getAlpha()); | |
181 | |
182 if (paint.getStyle() != SkPaint::kFill_Style) | |
183 { | |
184 buffer.writeScalar(paint.getStrokeWidth()); | |
185 buffer.writeScalar(paint.getStrokeMiter()); | |
186 buffer.write8(paint.getStrokeCap()); | |
187 buffer.write8(paint.getStrokeJoin()); | |
188 } | |
189 | |
190 buffer.writeFlattenable(paint.getMaskFilter()); | |
191 buffer.writeFlattenable(paint.getPathEffect()); | |
192 buffer.writeFlattenable(paint.getRasterizer()); | |
193 buffer.writeFlattenable(paint.getXfermode()); | |
194 } | |
195 | |
196 SkLayerRasterizer::SkLayerRasterizer(SkFlattenableReadBuffer& buffer) | |
197 : SkRasterizer(buffer), fLayers(sizeof(SkLayerRasterizer_Rec)) | |
198 { | |
199 int count = buffer.readS32(); | |
200 | |
201 for (int i = 0; i < count; i++) | |
202 { | |
203 SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back()
; | |
204 | |
205 #if 0 | |
206 new (&rec->fPaint) SkPaint(buffer); | |
207 #else | |
208 new (&rec->fPaint) SkPaint; | |
209 paint_read(&rec->fPaint, buffer); | |
210 #endif | |
211 rec->fOffset.fX = buffer.readScalar(); | |
212 rec->fOffset.fY = buffer.readScalar(); | |
213 } | |
214 } | |
215 | |
216 void SkLayerRasterizer::flatten(SkFlattenableWriteBuffer& buffer) | |
217 { | |
218 this->INHERITED::flatten(buffer); | |
219 | |
220 buffer.write32(fLayers.count()); | |
221 | |
222 SkDeque::Iter iter(fLayers); | |
223 const SkLayerRasterizer_Rec* rec; | |
224 | |
225 while ((rec = (const SkLayerRasterizer_Rec*)iter.next()) != NULL) | |
226 { | |
227 #if 0 | |
228 rec->fPaint.flatten(buffer); | |
229 #else | |
230 paint_write(rec->fPaint, buffer); | |
231 #endif | |
232 buffer.writeScalar(rec->fOffset.fX); | |
233 buffer.writeScalar(rec->fOffset.fY); | |
234 } | |
235 } | |
236 | |
237 SkFlattenable* SkLayerRasterizer::CreateProc(SkFlattenableReadBuffer& buffer) | |
238 { | |
239 return SkNEW_ARGS(SkLayerRasterizer, (buffer)); | |
240 } | |
241 | |
242 SkFlattenable::Factory SkLayerRasterizer::getFactory() | |
243 { | |
244 return CreateProc; | |
245 } | |
246 | |
OLD | NEW |