OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkPipeCanvas.h" | |
9 #include "SkPipeFormat.h" | |
10 | |
11 #include "SkPathEffect.h" | |
12 #include "SkShader.h" | |
13 #include "SkColorFilter.h" | |
14 #include "SkImageFilter.h" | |
15 #include "SkMaskFilter.h" | |
16 #include "SkRasterizer.h" | |
17 #include "SkStream.h" | |
18 | |
19 template <typename T> void write_rrect(T* writer, const SkRRect& rrect) { | |
20 char tmp[SkRRect::kSizeInMemory]; | |
21 rrect.writeToMemory(tmp); | |
22 writer->write(tmp, SkRRect::kSizeInMemory); | |
23 } | |
24 | |
25 template <typename T> void write_pad(T* writer, const void* buffer, size_t len) { | |
26 writer->write(buffer, len & ~3); | |
27 if (len & 3) { | |
28 const char* src = (const char*)buffer + (len & ~3); | |
29 len &= 3; | |
30 | |
31 char tmp[4]; | |
mtklein
2016/08/04 12:50:37
Or,
uint32_t tmp = 0;
memcpy(&tmp, src, len);
wri
reed1
2016/08/04 13:18:41
Nice. Considered that, but got temporarily confuse
| |
32 for (size_t i = 0; i < len; ++i) { | |
33 tmp[i] = src[i]; | |
34 } | |
35 for (size_t i = len; i < 4; ++i) { | |
36 tmp[i] = 0; | |
37 } | |
38 writer->write(tmp, 4); | |
39 } | |
40 } | |
41 | |
42 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
43 | |
44 class ScopedWriter : public SkBinaryWriteBuffer { | |
45 public: | |
46 ScopedWriter(SkPipeCanvas*) : SkBinaryWriteBuffer(0) {} | |
mtklein
2016/08/04 12:50:37
This probably doesn't need to inherit from SkBinar
reed1
2016/08/04 13:18:41
Correct, just wanted a quickie so that syntactical
| |
47 }; | |
48 | |
49 static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) { | |
50 const SkScalar kTextSize_Default = 12; | |
51 const SkScalar kTextScaleX_Default = 1; | |
52 const SkScalar kTextSkewX_Default = 0; | |
53 const SkScalar kStrokeWidth_Default = 0; | |
54 const SkScalar kStrokeMiter_Default = 4; | |
55 const SkColor kColor_Default = SK_ColorBLACK; | |
56 | |
57 unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0; | |
58 | |
59 if (kText_PaintUsage == usage) { | |
60 bits |= (paint.getTextSize() != kTextSize_Default ? kTextSize_NonD ef : 0); | |
61 bits |= (paint.getTextScaleX() != kTextScaleX_Default ? kTextSize_NonD ef : 0); | |
mtklein
2016/08/04 12:50:37
I bet scale and skew stay default with a non-defau
reed1
2016/08/04 13:18:41
That's a typo, fixed.
| |
62 bits |= (paint.getTextSkewX() != kTextSkewX_Default ? kTextSize_NonD ef : 0); | |
63 bits |= (paint.getTypeface() ? kTypeface_NonD ef : 0); | |
64 } | |
65 | |
66 if (usage & (kText_PaintUsage | kGeometry_PaintUsage)) { | |
67 bits |= (paint.getPathEffect() ? kPathEffect_NonDef : 0); | |
68 bits |= (paint.getShader() ? kShader_NonDef : 0); | |
69 bits |= (paint.getRasterizer() ? kRasterizer_NonDef : 0); | |
70 | |
71 if (paint.getStyle() != SkPaint::kFill_Style) { | |
72 bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWid th_NonDef : 0); | |
73 bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMit er_NonDef : 0); | |
74 } | |
75 } | |
76 | |
77 bits |= (paint.getXfermode() ? kXfermode_NonDef : 0); | |
78 bits |= (paint.getMaskFilter() ? kMaskFilter_NonDef : 0); | |
79 bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0); | |
80 bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0); | |
81 | |
82 return SkToU16(bits); | |
83 } | |
84 | |
85 static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, | |
86 unsigned filter, unsigned caps, unsigned joins) { | |
87 SkASSERT(kFlags_BPF + kHint_BPF + kAlign_BPF + kFilter_BPF <= 32); | |
88 | |
89 ASSERT_FITS_IN(flags, kFlags_BPF); | |
90 ASSERT_FITS_IN(hint, kHint_BPF); | |
91 ASSERT_FITS_IN(align, kAlign_BPF); | |
92 ASSERT_FITS_IN(filter, kFilter_BPF); | |
93 ASSERT_FITS_IN(caps, kCaps_BPF); | |
94 ASSERT_FITS_IN(joins, kJoins_BPF); | |
95 | |
96 // left-align the fields of "known" size, and right-align the last (flatFlag s) so it can easly | |
97 // add more bits in the future. | |
98 | |
99 uint32_t packed = 0; | |
100 int shift = 32; | |
101 | |
102 shift -= kFlags_BPF; packed |= (flags << shift); | |
103 shift -= kHint_BPF; packed |= (hint << shift); | |
104 shift -= kAlign_BPF; packed |= (align << shift); | |
105 shift -= kFilter_BPF; packed |= (filter << shift); | |
106 shift -= kCaps_BPF; packed |= (caps << shift); | |
107 shift -= kJoins_BPF; packed |= (joins << shift); | |
108 | |
109 return packed; | |
110 } | |
111 | |
112 #define CHECK_WRITE_SCALAR(bit, code) \ | |
mtklein
2016/08/04 12:50:37
Might help readability to pass nondef in too.
reed1
2016/08/04 13:18:41
... and writer? I was sort of modeling other macro
mtklein
2016/08/04 15:13:23
The rule of thumb I try to stick to is that implic
| |
113 do { if (nondef & (bit)) { writer.writeScalar(code); } } while (0) | |
114 | |
115 #define CHECK_WRITE_FLATTENABLE(bit, code) \ | |
116 do { if (nondef & (bit)) { \ | |
117 SkFlattenable* f = code; \ | |
118 SkASSERT(f != nullptr); \ | |
119 writer.writeFlattenable(f); \ | |
120 } } while (0) | |
121 | |
122 /* | |
123 * Header: | |
124 * paint flags : 32 | |
125 * non_def bits : 16 | |
126 * xfermode enum : 8 | |
127 * pad zeros : 8 | |
128 */ | |
129 static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, PaintUsage usage) { | |
130 uint32_t packedFlags = pack_paint_flags(paint.getFlags(), paint.getHinting() , | |
131 paint.getTextAlign(), paint.getFilte rQuality(), | |
132 paint.getStrokeCap(), paint.getStrok eJoin()); | |
133 writer.write32(packedFlags); | |
134 | |
135 unsigned nondef = compute_nondef(paint, usage); | |
136 SkXfermode::Mode mode; | |
137 if (SkXfermode::AsMode(paint.getXfermode(), &mode)) { | |
138 nondef &= ~kXfermode_NonDef; // don't need to store a pointer since w e have an enum | |
139 } else { | |
140 SkASSERT(nondef & kXfermode_NonDef); | |
141 mode = (SkXfermode::Mode)0; | |
142 } | |
143 const uint8_t pad = 0; | |
144 writer.write32((nondef << 16) | ((unsigned)mode << 8) | pad); | |
145 | |
146 CHECK_WRITE_SCALAR(kTextSize_NonDef, paint.getTextSize()); | |
147 CHECK_WRITE_SCALAR(kTextScaleX_NonDef, paint.getTextScaleX()); | |
148 CHECK_WRITE_SCALAR(kTextSkewX_NonDef, paint.getTextSkewX()); | |
149 CHECK_WRITE_SCALAR(kStrokeWidth_NonDef, paint.getStrokeWidth()); | |
150 CHECK_WRITE_SCALAR(kStrokeMiter_NonDef, paint.getStrokeMiter()); | |
151 | |
152 if (nondef & kColor_NonDef) { | |
153 writer.write32(paint.getColor()); | |
154 } | |
155 if (nondef & kTypeface_NonDef) { | |
156 } | |
157 | |
158 CHECK_WRITE_FLATTENABLE(kPathEffect_NonDef, paint.getPathEffect()); | |
159 CHECK_WRITE_FLATTENABLE(kShader_NonDef, paint.getShader()); | |
160 CHECK_WRITE_FLATTENABLE(kXfermode_NonDef, paint.getXfermode()); | |
161 CHECK_WRITE_FLATTENABLE(kMaskFilter_NonDef, paint.getMaskFilter()); | |
162 CHECK_WRITE_FLATTENABLE(kColorFilter_NonDef, paint.getColorFilter()); | |
163 CHECK_WRITE_FLATTENABLE(kRasterizer_NonDef, paint.getRasterizer()); | |
164 CHECK_WRITE_FLATTENABLE(kImageFilter_NonDef, paint.getImageFilter()); | |
165 } | |
166 | |
167 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
168 | |
169 SkPipeCanvas::SkPipeCanvas(int width, int height, SkWStream* stream) | |
170 : INHERITED(width, height) | |
171 , fStream(stream) | |
172 {} | |
173 | |
174 SkPipeCanvas::~SkPipeCanvas() {} | |
175 | |
176 void SkPipeCanvas::willSave() { | |
177 this->writeVerb(kSave_Verb); | |
mtklein
2016/08/04 12:50:37
We should probably funnel all verbs through the sa
reed1
2016/08/04 13:18:41
Done
| |
178 | |
179 this->INHERITED::willSave(); | |
180 } | |
181 | |
182 SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRe c& rec) { | |
183 this->INHERITED::getSaveLayerStrategy(rec); | |
184 | |
185 return kNoLayer_SaveLayerStrategy; | |
186 } | |
187 | |
188 void SkPipeCanvas::willRestore() { | |
189 this->writeVerb(kRestore_Verb); | |
190 | |
191 this->INHERITED::willRestore(); | |
192 } | |
193 | |
194 void SkPipeCanvas::didConcat(const SkMatrix& matrix) { | |
195 SkMatrix::TypeMask tm = matrix.getType(); | |
196 SkASSERT(tm != SkMatrix::kIdentity_Mask); | |
197 fStream->write32(pack_verb(kConcat_Verb, tm)); | |
198 | |
199 SkScalar tmp[9]; | |
200 if (tm & SkMatrix::kPerspective_Mask) { | |
201 matrix.get9(tmp); | |
202 fStream->write(tmp, 9 * sizeof(SkScalar)); | |
203 } else if (tm & SkMatrix::kAffine_Mask) { | |
204 tmp[0] = matrix[SkMatrix::kMScaleX]; | |
205 tmp[1] = matrix[SkMatrix::kMSkewX]; | |
206 tmp[2] = matrix[SkMatrix::kMTransX]; | |
207 tmp[3] = matrix[SkMatrix::kMScaleY]; | |
208 tmp[4] = matrix[SkMatrix::kMSkewY]; | |
209 tmp[5] = matrix[SkMatrix::kMTransY]; | |
210 fStream->write(tmp, 6 * sizeof(SkScalar)); | |
211 } else if (tm & SkMatrix::kScale_Mask) { | |
212 tmp[0] = matrix[SkMatrix::kMScaleX]; | |
213 tmp[1] = matrix[SkMatrix::kMTransX]; | |
214 tmp[2] = matrix[SkMatrix::kMScaleY]; | |
215 tmp[3] = matrix[SkMatrix::kMTransY]; | |
216 fStream->write(tmp, 4 * sizeof(SkScalar)); | |
217 } else if (tm & SkMatrix::kTranslate_Mask) { | |
218 tmp[0] = matrix[SkMatrix::kMTransX]; | |
219 tmp[1] = matrix[SkMatrix::kMTransY]; | |
220 fStream->write(tmp, 2 * sizeof(SkScalar)); | |
221 } | |
222 | |
223 this->INHERITED::didConcat(matrix); | |
224 } | |
225 | |
226 void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) { | |
227 // Can we eliminate this? | |
228 this->INHERITED::didSetMatrix(matrix); | |
229 } | |
230 | |
231 void SkPipeCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { | |
232 fStream->write32(pack_verb(kClipRect_Verb, ((unsigned)op << 1) | edgeStyle)) ; | |
mtklein
2016/08/04 12:50:37
static inline pack_clip(SkRegion::Op, ClipEdgeStyl
reed1
2016/08/04 13:18:41
Yea, there are lots of helpers like this I will wr
| |
233 fStream->write(&rect, 4 * sizeof(SkScalar)); | |
234 | |
235 this->INHERITED::onClipRect(rect, op, edgeStyle); | |
236 } | |
237 | |
238 void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeSt yle edgeStyle) { | |
239 fStream->write32(pack_verb(kClipRRect_Verb, ((unsigned)op << 1) | edgeStyle) ); | |
240 write_rrect(fStream, rrect); | |
241 | |
242 this->INHERITED::onClipRRect(rrect, op, edgeStyle); | |
243 } | |
244 | |
245 void SkPipeCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { | |
246 ScopedWriter writer(this); | |
247 writer.write32(pack_verb(kClipPath_Verb, ((unsigned)op << 1) | edgeStyle)); | |
248 writer.writePath(path); | |
249 | |
250 this->INHERITED::onClipPath(path, op, edgeStyle); | |
251 } | |
252 | |
253 void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { | |
254 ScopedWriter writer(this); | |
255 writer.write32(pack_verb(kClipRegion_Verb, (unsigned)op << 1)); | |
256 writer.writeRegion(deviceRgn); | |
257 | |
258 this->INHERITED::onClipRegion(deviceRgn, op); | |
259 } | |
260 | |
261 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
262 | |
263 void SkPipeCanvas::onDrawPaint(const SkPaint& paint) { | |
264 ScopedWriter writer(this); | |
265 writer.write32(pack_verb(kDrawPaint_Verb)); | |
266 write_paint(writer, paint, kDrawPaint_PaintUsage); | |
267 } | |
268 | |
269 void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[ ], | |
270 const SkPaint& paint) { | |
271 ScopedWriter writer(this); | |
272 writer.write32(pack_verb(kDrawPoints_Verb, mode)); | |
273 writer.write32(SkToU32(count)); | |
274 writer.write(pts, count * sizeof(SkPoint)); | |
275 write_paint(writer, paint, kGeometry_PaintUsage); | |
276 } | |
277 | |
278 void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { | |
279 ScopedWriter writer(this); | |
280 writer.write32(pack_verb(kDrawRect_Verb)); | |
281 writer.write(&rect, sizeof(SkRect)); | |
282 write_paint(writer, paint, kGeometry_PaintUsage); | |
283 } | |
284 | |
285 void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { | |
286 ScopedWriter writer(this); | |
287 writer.write32(pack_verb(kDrawOval_Verb)); | |
288 writer.write(&rect, sizeof(SkRect)); | |
289 write_paint(writer, paint, kGeometry_PaintUsage); | |
290 } | |
291 | |
292 void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { | |
293 ScopedWriter writer(this); | |
294 writer.write32(pack_verb(kDrawRRect_Verb)); | |
295 write_rrect(&writer, rrect); | |
296 write_paint(writer, paint, kGeometry_PaintUsage); | |
297 } | |
298 | |
299 void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, cons t SkPaint& paint) { | |
300 ScopedWriter writer(this); | |
301 writer.write32(pack_verb(kDrawDRRect_Verb)); | |
302 write_rrect(&writer, outer); | |
303 write_rrect(&writer, inner); | |
304 write_paint(writer, paint, kGeometry_PaintUsage); | |
305 } | |
306 | |
307 void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { | |
308 ScopedWriter writer(this); | |
309 writer.write32(pack_verb(kDrawPath_Verb)); | |
310 writer.writePath(path); | |
311 write_paint(writer, paint, kGeometry_PaintUsage); | |
312 } | |
313 | |
314 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
315 | |
316 static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) { | |
317 // If we just "make" an image, it will force a CPU copy (if its mutable), on ly to have | |
318 // us then either find it in our cache, or compress and send it. | |
319 // | |
320 // Better could be to look it up in our cache first, and only create/compres s it if we have to. | |
321 // | |
322 // But for now, just do the dumb thing... | |
323 return SkImage::MakeFromBitmap(bitmap); | |
324 } | |
325 | |
326 void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, | |
327 const SkPaint* paint) { | |
328 sk_sp<SkImage> image = make_from_bitmap(bitmap); | |
329 if (image) { | |
330 this->onDrawImage(image.get(), x, y, paint); | |
331 } | |
332 } | |
333 | |
334 void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, c onst SkRect& dst, | |
335 const SkPaint* paint, SrcRectConstraint cons traint) { | |
336 sk_sp<SkImage> image = make_from_bitmap(bitmap); | |
337 if (image) { | |
338 this->onDrawImageRect(image.get(), src, dst, paint, constraint); | |
339 } | |
340 } | |
341 | |
342 void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& cente r, | |
343 const SkRect& dst, const SkPaint* paint) { | |
344 sk_sp<SkImage> image = make_from_bitmap(bitmap); | |
345 if (image) { | |
346 this->onDrawImageNine(image.get(), center, dst, paint); | |
347 } | |
348 } | |
349 | |
350 void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top , | |
351 const SkPaint* paint) { | |
352 ScopedWriter writer(this); | |
353 writer.write32(pack_verb(kDrawImage_Verb, paint != nullptr)); | |
354 writer.writeImage(image); | |
355 writer.writeScalar(left); | |
356 writer.writeScalar(top); | |
357 if (paint) { | |
358 write_paint(writer, *paint, kImage_PaintUsage); | |
359 } | |
360 } | |
361 | |
362 void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, cons t SkRect& dst, | |
363 const SkPaint* paint, SrcRectConstraint const raint) { | |
364 ScopedWriter writer(this); | |
365 writer.write32(pack_verb(kDrawImageRect_Verb, ((src != nullptr) << 1) | (pai nt != nullptr))); | |
366 writer.writeImage(image); | |
367 if (src) { | |
368 writer.write(src, sizeof(*src)); | |
369 } | |
370 writer.write(&dst, sizeof(dst)); | |
371 if (paint) { | |
372 write_paint(writer, *paint, kImage_PaintUsage); | |
373 } | |
374 } | |
375 | |
376 void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, | |
377 const SkPaint* paint) { | |
378 ScopedWriter writer(this); | |
379 writer.write32(pack_verb(kDrawImageNine_Verb, paint != nullptr)); | |
380 writer.writeImage(image); | |
381 writer.write(¢er, sizeof(center)); | |
382 writer.write(&dst, sizeof(dst)); | |
383 if (paint) { | |
384 write_paint(writer, *paint, kImage_PaintUsage); | |
385 } | |
386 } | |
387 | |
388 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
389 | |
390 void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, S kScalar y, | |
391 const SkPaint& paint) { | |
392 SkASSERT(byteLength); | |
393 | |
394 bool compact = fits_in(byteLength, 24); | |
395 | |
396 ScopedWriter writer(this); | |
397 writer.write32(pack_verb(kDrawText_Verb, compact ? (unsigned)byteLength : 0) ); | |
398 if (!compact) { | |
399 writer.write32(SkToU32(byteLength)); | |
400 } | |
401 write_pad(&writer, text, byteLength); | |
402 writer.writeScalar(x); | |
403 writer.writeScalar(y); | |
404 write_paint(writer, paint, kText_PaintUsage); | |
405 } | |
406 | |
407 void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPo int pos[], | |
408 const SkPaint& paint) { | |
409 SkASSERT(byteLength); | |
410 | |
411 bool compact = fits_in(byteLength, 24); | |
412 | |
413 ScopedWriter writer(this); | |
414 writer.write32(pack_verb(kDrawText_Verb, compact ? (unsigned)byteLength : 0) ); | |
415 if (!compact) { | |
416 writer.write32(SkToU32(byteLength)); | |
417 } | |
418 write_pad(&writer, text, byteLength); | |
419 writer.writePointArray(pos, paint.countText(text, byteLength)); | |
420 write_paint(writer, paint, kText_PaintUsage); | |
421 } | |
422 | |
423 void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkS calar xpos[], | |
424 SkScalar constY, const SkPaint& paint) { | |
425 SkASSERT(byteLength); | |
426 | |
427 bool compact = fits_in(byteLength, 24); | |
428 | |
429 ScopedWriter writer(this); | |
430 writer.write32(pack_verb(kDrawText_Verb, compact ? (unsigned)byteLength : 0) ); | |
431 if (!compact) { | |
432 writer.write32(SkToU32(byteLength)); | |
433 } | |
434 write_pad(&writer, text, byteLength); | |
435 writer.writeScalarArray(xpos, paint.countText(text, byteLength)); | |
436 writer.writeScalar(constY); | |
437 write_paint(writer, paint, kText_PaintUsage); | |
438 } | |
439 | |
440 void SkPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const S kPath& path, | |
441 const SkMatrix* matrix, const SkPaint& paint ) { | |
442 sk_throw(); | |
443 } | |
444 | |
445 void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], | |
446 const SkRect* cull, const SkPaint& paint) { | |
447 sk_throw(); | |
448 } | |
449 | |
450 void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y , | |
451 const SkPaint &paint) { | |
452 sk_throw(); | |
453 } | |
454 | |
455 void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matri x, | |
456 const SkPaint* paint) { | |
457 sk_throw(); | |
458 } | |
459 | |
460 void SkPipeCanvas::onDrawVertices(VertexMode vmode, int vertexCount, | |
461 const SkPoint vertices[], const SkPoint texs[] , | |
462 const SkColor colors[], SkXfermode* xmode, | |
463 const uint16_t indices[], int indexCount, | |
464 const SkPaint& paint) { | |
465 sk_throw(); | |
466 } | |
467 | |
468 void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4] , | |
469 const SkPoint texCoords[4], SkXfermode* xmode, | |
470 const SkPaint& paint) { | |
471 sk_throw(); | |
472 } | |
473 | |
474 void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData * data) { | |
475 const size_t len = strlen(key); | |
476 bool compact = fits_in(len, 24); | |
477 fStream->write32(pack_verb(kDrawAnnotation_Verb, compact ? (unsigned)len : 0 )); | |
478 if (!compact) { | |
479 fStream->write32(SkToU32(len)); | |
480 } | |
481 write_pad(fStream, key, len); | |
482 if (data) { | |
483 fStream->write32(SkToU32(data->size())); | |
484 write_pad(fStream, data->data(), data->size()); | |
485 } else { | |
486 fStream->write32(0); | |
487 } | |
488 } | |
OLD | NEW |