Chromium Code Reviews| 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 |