c6c5cf3c818f7c69df98b6fd14ea2185d89c0b21
[platform/upstream/libSkiaSharp.git] / src / core / SkDraw.cpp
1 /*
2  * Copyright 2006 The Android Open Source Project
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 #define __STDC_LIMIT_MACROS
8
9 #include "SkDraw.h"
10 #include "SkBlendModePriv.h"
11 #include "SkBlitter.h"
12 #include "SkCanvas.h"
13 #include "SkColorPriv.h"
14 #include "SkDevice.h"
15 #include "SkDeviceLooper.h"
16 #include "SkFindAndPlaceGlyph.h"
17 #include "SkFixed.h"
18 #include "SkMaskFilter.h"
19 #include "SkMatrix.h"
20 #include "SkPaint.h"
21 #include "SkPathEffect.h"
22 #include "SkRasterClip.h"
23 #include "SkRasterizer.h"
24 #include "SkRRect.h"
25 #include "SkScan.h"
26 #include "SkShader.h"
27 #include "SkSmallAllocator.h"
28 #include "SkString.h"
29 #include "SkStroke.h"
30 #include "SkStrokeRec.h"
31 #include "SkTemplates.h"
32 #include "SkTextMapStateProc.h"
33 #include "SkTLazy.h"
34 #include "SkUtils.h"
35 #include "SkVertState.h"
36 #include "SkXfermode.h"
37
38 #include "SkBitmapProcShader.h"
39 #include "SkDrawProcs.h"
40 #include "SkMatrixUtils.h"
41
42 //#define TRACE_BITMAP_DRAWS
43
44 // Helper function to fix code gen bug on ARM64.
45 // See SkFindAndPlaceGlyph.h for more details.
46 void FixGCC49Arm64Bug(int v) { }
47
48 /** Helper for allocating small blitters on the stack.
49  */
50 class SkAutoBlitterChoose : SkNoncopyable {
51 public:
52     SkAutoBlitterChoose() {
53         fBlitter = nullptr;
54     }
55     SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix,
56                         const SkPaint& paint, bool drawCoverage = false) {
57         fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
58     }
59
60     SkBlitter*  operator->() { return fBlitter; }
61     SkBlitter*  get() const { return fBlitter; }
62
63     void choose(const SkPixmap& dst, const SkMatrix& matrix,
64                 const SkPaint& paint, bool drawCoverage = false) {
65         SkASSERT(!fBlitter);
66         fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
67     }
68
69 private:
70     // Owned by fAllocator, which will handle the delete.
71     SkBlitter*          fBlitter;
72     SkTBlitterAllocator fAllocator;
73 };
74 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose)
75
76 /**
77  *  Since we are providing the storage for the shader (to avoid the perf cost
78  *  of calling new) we insist that in our destructor we can account for all
79  *  owners of the shader.
80  */
81 class SkAutoBitmapShaderInstall : SkNoncopyable {
82 public:
83     SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint,
84                               const SkMatrix* localMatrix = nullptr)
85             : fPaint(paint) /* makes a copy of the paint */ {
86         fPaint.setShader(SkMakeBitmapShader(src, SkShader::kClamp_TileMode,
87                                             SkShader::kClamp_TileMode, localMatrix,
88                                             kNever_SkCopyPixelsMode,
89                                             &fAllocator));
90         // we deliberately left the shader with an owner-count of 2
91         fPaint.getShader()->ref();
92         SkASSERT(2 == fPaint.getShader()->getRefCnt());
93     }
94
95     ~SkAutoBitmapShaderInstall() {
96         // since fAllocator will destroy shader, we insist that owners == 2
97         SkASSERT(2 == fPaint.getShader()->getRefCnt());
98
99         fPaint.setShader(nullptr); // unref the shader by 1
100
101     }
102
103     // return the new paint that has the shader applied
104     const SkPaint& paintWithShader() const { return fPaint; }
105
106 private:
107     // copy of caller's paint (which we then modify)
108     SkPaint             fPaint;
109     // Stores the shader.
110     SkTBlitterAllocator fAllocator;
111 };
112 #define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderInstall)
113
114 ///////////////////////////////////////////////////////////////////////////////
115
116 SkDraw::SkDraw() {
117     sk_bzero(this, sizeof(*this));
118 }
119
120 bool SkDraw::computeConservativeLocalClipBounds(SkRect* localBounds) const {
121     if (fRC->isEmpty()) {
122         return false;
123     }
124
125     SkMatrix inverse;
126     if (!fMatrix->invert(&inverse)) {
127         return false;
128     }
129
130     SkIRect devBounds = fRC->getBounds();
131     // outset to have slop for antialasing and hairlines
132     devBounds.outset(1, 1);
133     inverse.mapRect(localBounds, SkRect::Make(devBounds));
134     return true;
135 }
136
137 ///////////////////////////////////////////////////////////////////////////////
138
139 typedef void (*BitmapXferProc)(void* pixels, size_t bytes, uint32_t data);
140
141 static void D_Clear_BitmapXferProc(void* pixels, size_t bytes, uint32_t) {
142     sk_bzero(pixels, bytes);
143 }
144
145 static void D_Dst_BitmapXferProc(void*, size_t, uint32_t data) {}
146
147 static void D32_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
148     sk_memset32((uint32_t*)pixels, data, SkToInt(bytes >> 2));
149 }
150
151 static void D16_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
152     sk_memset16((uint16_t*)pixels, data, SkToInt(bytes >> 1));
153 }
154
155 static void DA8_Src_BitmapXferProc(void* pixels, size_t bytes, uint32_t data) {
156     memset(pixels, data, bytes);
157 }
158
159 static BitmapXferProc ChooseBitmapXferProc(const SkPixmap& dst, const SkPaint& paint,
160                                            uint32_t* data) {
161     // todo: we can apply colorfilter up front if no shader, so we wouldn't
162     // need to abort this fastpath
163     if (paint.getShader() || paint.getColorFilter()) {
164         return nullptr;
165     }
166
167     SkBlendMode mode = paint.getBlendMode();
168     SkColor color = paint.getColor();
169
170     // collaps modes based on color...
171     if (SkBlendMode::kSrcOver == mode) {
172         unsigned alpha = SkColorGetA(color);
173         if (0 == alpha) {
174             mode = SkBlendMode::kDst;
175         } else if (0xFF == alpha) {
176             mode = SkBlendMode::kSrc;
177         }
178     }
179
180     switch (mode) {
181         case SkBlendMode::kClear:
182 //            SkDebugf("--- D_Clear_BitmapXferProc\n");
183             return D_Clear_BitmapXferProc;  // ignore data
184         case SkBlendMode::kDst:
185 //            SkDebugf("--- D_Dst_BitmapXferProc\n");
186             return D_Dst_BitmapXferProc;    // ignore data
187         case SkBlendMode::kSrc: {
188             /*
189                 should I worry about dithering for the lower depths?
190             */
191             SkPMColor pmc = SkPreMultiplyColor(color);
192             switch (dst.colorType()) {
193                 case kN32_SkColorType:
194                     if (data) {
195                         *data = pmc;
196                     }
197 //                    SkDebugf("--- D32_Src_BitmapXferProc\n");
198                     return D32_Src_BitmapXferProc;
199                 case kRGB_565_SkColorType:
200                     if (data) {
201                         *data = SkPixel32ToPixel16(pmc);
202                     }
203 //                    SkDebugf("--- D16_Src_BitmapXferProc\n");
204                     return D16_Src_BitmapXferProc;
205                 case kAlpha_8_SkColorType:
206                     if (data) {
207                         *data = SkGetPackedA32(pmc);
208                     }
209 //                    SkDebugf("--- DA8_Src_BitmapXferProc\n");
210                     return DA8_Src_BitmapXferProc;
211                 default:
212                     break;
213             }
214             break;
215         }
216         default:
217             break;
218     }
219     return nullptr;
220 }
221
222 static void CallBitmapXferProc(const SkPixmap& dst, const SkIRect& rect, BitmapXferProc proc,
223                                uint32_t procData) {
224     int shiftPerPixel;
225     switch (dst.colorType()) {
226         case kN32_SkColorType:
227             shiftPerPixel = 2;
228             break;
229         case kRGB_565_SkColorType:
230             shiftPerPixel = 1;
231             break;
232         case kAlpha_8_SkColorType:
233             shiftPerPixel = 0;
234             break;
235         default:
236             SkDEBUGFAIL("Can't use xferproc on this config");
237             return;
238     }
239
240     uint8_t* pixels = (uint8_t*)dst.writable_addr();
241     SkASSERT(pixels);
242     const size_t rowBytes = dst.rowBytes();
243     const int widthBytes = rect.width() << shiftPerPixel;
244
245     // skip down to the first scanline and X position
246     pixels += rect.fTop * rowBytes + (rect.fLeft << shiftPerPixel);
247     for (int scans = rect.height() - 1; scans >= 0; --scans) {
248         proc(pixels, widthBytes, procData);
249         pixels += rowBytes;
250     }
251 }
252
253 void SkDraw::drawPaint(const SkPaint& paint) const {
254     SkDEBUGCODE(this->validate();)
255
256     if (fRC->isEmpty()) {
257         return;
258     }
259
260     SkIRect    devRect;
261     devRect.set(0, 0, fDst.width(), fDst.height());
262
263     if (fRC->isBW()) {
264         /*  If we don't have a shader (i.e. we're just a solid color) we may
265             be faster to operate directly on the device bitmap, rather than invoking
266             a blitter. Esp. true for xfermodes, which require a colorshader to be
267             present, which is just redundant work. Since we're drawing everywhere
268             in the clip, we don't have to worry about antialiasing.
269         */
270         uint32_t procData = 0;  // to avoid the warning
271         BitmapXferProc proc = ChooseBitmapXferProc(fDst, paint, &procData);
272         if (proc) {
273             if (D_Dst_BitmapXferProc == proc) { // nothing to do
274                 return;
275             }
276
277             SkRegion::Iterator iter(fRC->bwRgn());
278             while (!iter.done()) {
279                 CallBitmapXferProc(fDst, iter.rect(), proc, procData);
280                 iter.next();
281             }
282             return;
283         }
284     }
285
286     // normal case: use a blitter
287     SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
288     SkScan::FillIRect(devRect, *fRC, blitter.get());
289 }
290
291 ///////////////////////////////////////////////////////////////////////////////
292
293 struct PtProcRec {
294     SkCanvas::PointMode fMode;
295     const SkPaint*  fPaint;
296     const SkRegion* fClip;
297     const SkRasterClip* fRC;
298
299     // computed values
300     SkFixed fRadius;
301
302     typedef void (*Proc)(const PtProcRec&, const SkPoint devPts[], int count,
303                          SkBlitter*);
304
305     bool init(SkCanvas::PointMode, const SkPaint&, const SkMatrix* matrix,
306               const SkRasterClip*);
307     Proc chooseProc(SkBlitter** blitter);
308
309 private:
310     SkAAClipBlitterWrapper fWrapper;
311 };
312
313 static void bw_pt_rect_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
314                                  int count, SkBlitter* blitter) {
315     SkASSERT(rec.fClip->isRect());
316     const SkIRect& r = rec.fClip->getBounds();
317
318     for (int i = 0; i < count; i++) {
319         int x = SkScalarFloorToInt(devPts[i].fX);
320         int y = SkScalarFloorToInt(devPts[i].fY);
321         if (r.contains(x, y)) {
322             blitter->blitH(x, y, 1);
323         }
324     }
325 }
326
327 static void bw_pt_rect_16_hair_proc(const PtProcRec& rec,
328                                     const SkPoint devPts[], int count,
329                                     SkBlitter* blitter) {
330     SkASSERT(rec.fRC->isRect());
331     const SkIRect& r = rec.fRC->getBounds();
332     uint32_t value;
333     const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
334     SkASSERT(dst);
335
336     uint16_t* addr = dst->writable_addr16(0, 0);
337     size_t    rb = dst->rowBytes();
338
339     for (int i = 0; i < count; i++) {
340         int x = SkScalarFloorToInt(devPts[i].fX);
341         int y = SkScalarFloorToInt(devPts[i].fY);
342         if (r.contains(x, y)) {
343             ((uint16_t*)((char*)addr + y * rb))[x] = SkToU16(value);
344         }
345     }
346 }
347
348 static void bw_pt_rect_32_hair_proc(const PtProcRec& rec,
349                                     const SkPoint devPts[], int count,
350                                     SkBlitter* blitter) {
351     SkASSERT(rec.fRC->isRect());
352     const SkIRect& r = rec.fRC->getBounds();
353     uint32_t value;
354     const SkPixmap* dst = blitter->justAnOpaqueColor(&value);
355     SkASSERT(dst);
356
357     SkPMColor* addr = dst->writable_addr32(0, 0);
358     size_t     rb = dst->rowBytes();
359
360     for (int i = 0; i < count; i++) {
361         int x = SkScalarFloorToInt(devPts[i].fX);
362         int y = SkScalarFloorToInt(devPts[i].fY);
363         if (r.contains(x, y)) {
364             ((SkPMColor*)((char*)addr + y * rb))[x] = value;
365         }
366     }
367 }
368
369 static void bw_pt_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
370                             int count, SkBlitter* blitter) {
371     for (int i = 0; i < count; i++) {
372         int x = SkScalarFloorToInt(devPts[i].fX);
373         int y = SkScalarFloorToInt(devPts[i].fY);
374         if (rec.fClip->contains(x, y)) {
375             blitter->blitH(x, y, 1);
376         }
377     }
378 }
379
380 static void bw_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
381                               int count, SkBlitter* blitter) {
382     for (int i = 0; i < count; i += 2) {
383         SkScan::HairLine(&devPts[i], 2, *rec.fRC, blitter);
384     }
385 }
386
387 static void bw_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
388                               int count, SkBlitter* blitter) {
389     SkScan::HairLine(devPts, count, *rec.fRC, blitter);
390 }
391
392 // aa versions
393
394 static void aa_line_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
395                               int count, SkBlitter* blitter) {
396     for (int i = 0; i < count; i += 2) {
397         SkScan::AntiHairLine(&devPts[i], 2, *rec.fRC, blitter);
398     }
399 }
400
401 static void aa_poly_hair_proc(const PtProcRec& rec, const SkPoint devPts[],
402                               int count, SkBlitter* blitter) {
403     SkScan::AntiHairLine(devPts, count, *rec.fRC, blitter);
404 }
405
406 // square procs (strokeWidth > 0 but matrix is square-scale (sx == sy)
407
408 static void bw_square_proc(const PtProcRec& rec, const SkPoint devPts[],
409                            int count, SkBlitter* blitter) {
410     const SkFixed radius = rec.fRadius;
411     for (int i = 0; i < count; i++) {
412         SkFixed x = SkScalarToFixed(devPts[i].fX);
413         SkFixed y = SkScalarToFixed(devPts[i].fY);
414
415         SkXRect r;
416         r.fLeft = x - radius;
417         r.fTop = y - radius;
418         r.fRight = x + radius;
419         r.fBottom = y + radius;
420
421         SkScan::FillXRect(r, *rec.fRC, blitter);
422     }
423 }
424
425 static void aa_square_proc(const PtProcRec& rec, const SkPoint devPts[],
426                            int count, SkBlitter* blitter) {
427     const SkFixed radius = rec.fRadius;
428     for (int i = 0; i < count; i++) {
429         SkFixed x = SkScalarToFixed(devPts[i].fX);
430         SkFixed y = SkScalarToFixed(devPts[i].fY);
431
432         SkXRect r;
433         r.fLeft = x - radius;
434         r.fTop = y - radius;
435         r.fRight = x + radius;
436         r.fBottom = y + radius;
437
438         SkScan::AntiFillXRect(r, *rec.fRC, blitter);
439     }
440 }
441
442 // If this guy returns true, then chooseProc() must return a valid proc
443 bool PtProcRec::init(SkCanvas::PointMode mode, const SkPaint& paint,
444                      const SkMatrix* matrix, const SkRasterClip* rc) {
445     if ((unsigned)mode > (unsigned)SkCanvas::kPolygon_PointMode) {
446         return false;
447     }
448
449     if (paint.getPathEffect()) {
450         return false;
451     }
452     SkScalar width = paint.getStrokeWidth();
453     if (0 == width) {
454         fMode = mode;
455         fPaint = &paint;
456         fClip = nullptr;
457         fRC = rc;
458         fRadius = SK_FixedHalf;
459         return true;
460     }
461     if (paint.getStrokeCap() != SkPaint::kRound_Cap &&
462         matrix->isScaleTranslate() && SkCanvas::kPoints_PointMode == mode) {
463         SkScalar sx = matrix->get(SkMatrix::kMScaleX);
464         SkScalar sy = matrix->get(SkMatrix::kMScaleY);
465         if (SkScalarNearlyZero(sx - sy)) {
466             if (sx < 0) {
467                 sx = -sx;
468             }
469
470             fMode = mode;
471             fPaint = &paint;
472             fClip = nullptr;
473             fRC = rc;
474             fRadius = SkScalarToFixed(SkScalarMul(width, sx)) >> 1;
475             return true;
476         }
477     }
478     return false;
479 }
480
481 PtProcRec::Proc PtProcRec::chooseProc(SkBlitter** blitterPtr) {
482     Proc proc = nullptr;
483
484     SkBlitter* blitter = *blitterPtr;
485     if (fRC->isBW()) {
486         fClip = &fRC->bwRgn();
487     } else {
488         fWrapper.init(*fRC, blitter);
489         fClip = &fWrapper.getRgn();
490         blitter = fWrapper.getBlitter();
491         *blitterPtr = blitter;
492     }
493
494     // for our arrays
495     SkASSERT(0 == SkCanvas::kPoints_PointMode);
496     SkASSERT(1 == SkCanvas::kLines_PointMode);
497     SkASSERT(2 == SkCanvas::kPolygon_PointMode);
498     SkASSERT((unsigned)fMode <= (unsigned)SkCanvas::kPolygon_PointMode);
499
500     if (fPaint->isAntiAlias()) {
501         if (0 == fPaint->getStrokeWidth()) {
502             static const Proc gAAProcs[] = {
503                 aa_square_proc, aa_line_hair_proc, aa_poly_hair_proc
504             };
505             proc = gAAProcs[fMode];
506         } else if (fPaint->getStrokeCap() != SkPaint::kRound_Cap) {
507             SkASSERT(SkCanvas::kPoints_PointMode == fMode);
508             proc = aa_square_proc;
509         }
510     } else {    // BW
511         if (fRadius <= SK_FixedHalf) {    // small radii and hairline
512             if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) {
513                 uint32_t value;
514                 const SkPixmap* bm = blitter->justAnOpaqueColor(&value);
515                 if (bm && kRGB_565_SkColorType == bm->colorType()) {
516                     proc = bw_pt_rect_16_hair_proc;
517                 } else if (bm && kN32_SkColorType == bm->colorType()) {
518                     proc = bw_pt_rect_32_hair_proc;
519                 } else {
520                     proc = bw_pt_rect_hair_proc;
521                 }
522             } else {
523                 static Proc gBWProcs[] = {
524                     bw_pt_hair_proc, bw_line_hair_proc, bw_poly_hair_proc
525                 };
526                 proc = gBWProcs[fMode];
527             }
528         } else {
529             proc = bw_square_proc;
530         }
531     }
532     return proc;
533 }
534
535 // each of these costs 8-bytes of stack space, so don't make it too large
536 // must be even for lines/polygon to work
537 #define MAX_DEV_PTS     32
538
539 void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
540                         const SkPoint pts[], const SkPaint& paint,
541                         bool forceUseDevice) const {
542     // if we're in lines mode, force count to be even
543     if (SkCanvas::kLines_PointMode == mode) {
544         count &= ~(size_t)1;
545     }
546
547     if ((long)count <= 0) {
548         return;
549     }
550
551     SkASSERT(pts != nullptr);
552     SkDEBUGCODE(this->validate();)
553
554      // nothing to draw
555     if (fRC->isEmpty()) {
556         return;
557     }
558
559     PtProcRec rec;
560     if (!forceUseDevice && rec.init(mode, paint, fMatrix, fRC)) {
561         SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
562
563         SkPoint             devPts[MAX_DEV_PTS];
564         const SkMatrix*     matrix = fMatrix;
565         SkBlitter*          bltr = blitter.get();
566         PtProcRec::Proc     proc = rec.chooseProc(&bltr);
567         // we have to back up subsequent passes if we're in polygon mode
568         const size_t backup = (SkCanvas::kPolygon_PointMode == mode);
569
570         do {
571             int n = SkToInt(count);
572             if (n > MAX_DEV_PTS) {
573                 n = MAX_DEV_PTS;
574             }
575             matrix->mapPoints(devPts, pts, n);
576             proc(rec, devPts, n, bltr);
577             pts += n - backup;
578             SkASSERT(SkToInt(count) >= n);
579             count -= n;
580             if (count > 0) {
581                 count += backup;
582             }
583         } while (count != 0);
584     } else {
585         switch (mode) {
586             case SkCanvas::kPoints_PointMode: {
587                 // temporarily mark the paint as filling.
588                 SkPaint newPaint(paint);
589                 newPaint.setStyle(SkPaint::kFill_Style);
590
591                 SkScalar width = newPaint.getStrokeWidth();
592                 SkScalar radius = SkScalarHalf(width);
593
594                 if (newPaint.getStrokeCap() == SkPaint::kRound_Cap) {
595                     SkPath      path;
596                     SkMatrix    preMatrix;
597
598                     path.addCircle(0, 0, radius);
599                     for (size_t i = 0; i < count; i++) {
600                         preMatrix.setTranslate(pts[i].fX, pts[i].fY);
601                         // pass true for the last point, since we can modify
602                         // then path then
603                         path.setIsVolatile((count-1) == i);
604                         if (fDevice) {
605                             fDevice->drawPath(*this, path, newPaint, &preMatrix,
606                                               (count-1) == i);
607                         } else {
608                             this->drawPath(path, newPaint, &preMatrix,
609                                            (count-1) == i);
610                         }
611                     }
612                 } else {
613                     SkRect  r;
614
615                     for (size_t i = 0; i < count; i++) {
616                         r.fLeft = pts[i].fX - radius;
617                         r.fTop = pts[i].fY - radius;
618                         r.fRight = r.fLeft + width;
619                         r.fBottom = r.fTop + width;
620                         if (fDevice) {
621                             fDevice->drawRect(*this, r, newPaint);
622                         } else {
623                             this->drawRect(r, newPaint);
624                         }
625                     }
626                 }
627                 break;
628             }
629             case SkCanvas::kLines_PointMode:
630                 if (2 == count && paint.getPathEffect()) {
631                     // most likely a dashed line - see if it is one of the ones
632                     // we can accelerate
633                     SkStrokeRec rec(paint);
634                     SkPathEffect::PointData pointData;
635
636                     SkPath path;
637                     path.moveTo(pts[0]);
638                     path.lineTo(pts[1]);
639
640                     SkRect cullRect = SkRect::Make(fRC->getBounds());
641
642                     if (paint.getPathEffect()->asPoints(&pointData, path, rec,
643                                                         *fMatrix, &cullRect)) {
644                         // 'asPoints' managed to find some fast path
645
646                         SkPaint newP(paint);
647                         newP.setPathEffect(nullptr);
648                         newP.setStyle(SkPaint::kFill_Style);
649
650                         if (!pointData.fFirst.isEmpty()) {
651                             if (fDevice) {
652                                 fDevice->drawPath(*this, pointData.fFirst, newP);
653                             } else {
654                                 this->drawPath(pointData.fFirst, newP);
655                             }
656                         }
657
658                         if (!pointData.fLast.isEmpty()) {
659                             if (fDevice) {
660                                 fDevice->drawPath(*this, pointData.fLast, newP);
661                             } else {
662                                 this->drawPath(pointData.fLast, newP);
663                             }
664                         }
665
666                         if (pointData.fSize.fX == pointData.fSize.fY) {
667                             // The rest of the dashed line can just be drawn as points
668                             SkASSERT(pointData.fSize.fX == SkScalarHalf(newP.getStrokeWidth()));
669
670                             if (SkPathEffect::PointData::kCircles_PointFlag & pointData.fFlags) {
671                                 newP.setStrokeCap(SkPaint::kRound_Cap);
672                             } else {
673                                 newP.setStrokeCap(SkPaint::kButt_Cap);
674                             }
675
676                             if (fDevice) {
677                                 fDevice->drawPoints(*this,
678                                                     SkCanvas::kPoints_PointMode,
679                                                     pointData.fNumPoints,
680                                                     pointData.fPoints,
681                                                     newP);
682                             } else {
683                                 this->drawPoints(SkCanvas::kPoints_PointMode,
684                                                  pointData.fNumPoints,
685                                                  pointData.fPoints,
686                                                  newP,
687                                                  forceUseDevice);
688                             }
689                             break;
690                         } else {
691                             // The rest of the dashed line must be drawn as rects
692                             SkASSERT(!(SkPathEffect::PointData::kCircles_PointFlag &
693                                       pointData.fFlags));
694
695                             SkRect r;
696
697                             for (int i = 0; i < pointData.fNumPoints; ++i) {
698                                 r.set(pointData.fPoints[i].fX - pointData.fSize.fX,
699                                       pointData.fPoints[i].fY - pointData.fSize.fY,
700                                       pointData.fPoints[i].fX + pointData.fSize.fX,
701                                       pointData.fPoints[i].fY + pointData.fSize.fY);
702                                 if (fDevice) {
703                                     fDevice->drawRect(*this, r, newP);
704                                 } else {
705                                     this->drawRect(r, newP);
706                                 }
707                             }
708                         }
709
710                         break;
711                     }
712                 }
713                 // couldn't take fast path so fall through!
714             case SkCanvas::kPolygon_PointMode: {
715                 count -= 1;
716                 SkPath path;
717                 SkPaint p(paint);
718                 p.setStyle(SkPaint::kStroke_Style);
719                 size_t inc = (SkCanvas::kLines_PointMode == mode) ? 2 : 1;
720                 path.setIsVolatile(true);
721                 for (size_t i = 0; i < count; i += inc) {
722                     path.moveTo(pts[i]);
723                     path.lineTo(pts[i+1]);
724                     if (fDevice) {
725                         fDevice->drawPath(*this, path, p, nullptr, true);
726                     } else {
727                         this->drawPath(path, p, nullptr, true);
728                     }
729                     path.rewind();
730                 }
731                 break;
732             }
733         }
734     }
735 }
736
737 static inline SkPoint compute_stroke_size(const SkPaint& paint, const SkMatrix& matrix) {
738     SkASSERT(matrix.rectStaysRect());
739     SkASSERT(SkPaint::kFill_Style != paint.getStyle());
740
741     SkVector size;
742     SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
743     matrix.mapVectors(&size, &pt, 1);
744     return SkPoint::Make(SkScalarAbs(size.fX), SkScalarAbs(size.fY));
745 }
746
747 static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
748                            SkPoint* strokeSize) {
749     if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
750         paint.getStrokeMiter() < SK_ScalarSqrt2) {
751         return false;
752     }
753
754     *strokeSize = compute_stroke_size(paint, matrix);
755     return true;
756 }
757
758 SkDraw::RectType SkDraw::ComputeRectType(const SkPaint& paint,
759                                          const SkMatrix& matrix,
760                                          SkPoint* strokeSize) {
761     RectType rtype;
762     const SkScalar width = paint.getStrokeWidth();
763     const bool zeroWidth = (0 == width);
764     SkPaint::Style style = paint.getStyle();
765
766     if ((SkPaint::kStrokeAndFill_Style == style) && zeroWidth) {
767         style = SkPaint::kFill_Style;
768     }
769
770     if (paint.getPathEffect() || paint.getMaskFilter() ||
771         paint.getRasterizer() || !matrix.rectStaysRect() ||
772         SkPaint::kStrokeAndFill_Style == style) {
773         rtype = kPath_RectType;
774     } else if (SkPaint::kFill_Style == style) {
775         rtype = kFill_RectType;
776     } else if (zeroWidth) {
777         rtype = kHair_RectType;
778     } else if (easy_rect_join(paint, matrix, strokeSize)) {
779         rtype = kStroke_RectType;
780     } else {
781         rtype = kPath_RectType;
782     }
783     return rtype;
784 }
785
786 static const SkPoint* rect_points(const SkRect& r) {
787     return SkTCast<const SkPoint*>(&r);
788 }
789
790 static SkPoint* rect_points(SkRect& r) {
791     return SkTCast<SkPoint*>(&r);
792 }
793
794 void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
795                       const SkMatrix* paintMatrix, const SkRect* postPaintRect) const {
796     SkDEBUGCODE(this->validate();)
797
798     // nothing to draw
799     if (fRC->isEmpty()) {
800         return;
801     }
802
803     const SkMatrix* matrix;
804     SkMatrix combinedMatrixStorage;
805     if (paintMatrix) {
806         SkASSERT(postPaintRect);
807         combinedMatrixStorage.setConcat(*fMatrix, *paintMatrix);
808         matrix = &combinedMatrixStorage;
809     } else {
810         SkASSERT(!postPaintRect);
811         matrix = fMatrix;
812     }
813
814     SkPoint strokeSize;
815     RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
816
817     if (kPath_RectType == rtype) {
818         SkDraw draw(*this);
819         if (paintMatrix) {
820             draw.fMatrix = matrix;
821         }
822         SkPath  tmp;
823         tmp.addRect(prePaintRect);
824         tmp.setFillType(SkPath::kWinding_FillType);
825         draw.drawPath(tmp, paint, nullptr, true);
826         return;
827     }
828
829     SkRect devRect;
830     const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
831     // skip the paintMatrix when transforming the rect by the CTM
832     fMatrix->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
833     devRect.sort();
834
835     // look for the quick exit, before we build a blitter
836     SkRect bbox = devRect;
837     if (paint.getStyle() != SkPaint::kFill_Style) {
838         // extra space for hairlines
839         if (paint.getStrokeWidth() == 0) {
840             bbox.outset(1, 1);
841         } else {
842             // For kStroke_RectType, strokeSize is already computed.
843             const SkPoint& ssize = (kStroke_RectType == rtype)
844                 ? strokeSize
845                 : compute_stroke_size(paint, *fMatrix);
846             bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
847         }
848     }
849
850     SkIRect ir = bbox.roundOut();
851     if (fRC->quickReject(ir)) {
852         return;
853     }
854
855     SkDeviceLooper looper(fDst, *fRC, ir, paint.isAntiAlias());
856     while (looper.next()) {
857         SkRect localDevRect;
858         looper.mapRect(&localDevRect, devRect);
859         SkMatrix localMatrix;
860         looper.mapMatrix(&localMatrix, *matrix);
861
862         SkAutoBlitterChoose blitterStorage(looper.getPixmap(), localMatrix, paint);
863         const SkRasterClip& clip = looper.getRC();
864         SkBlitter*          blitter = blitterStorage.get();
865
866         // we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
867         // case we are also hairline (if we've gotten to here), which devolves to
868         // effectively just kFill
869         switch (rtype) {
870             case kFill_RectType:
871                 if (paint.isAntiAlias()) {
872                     SkScan::AntiFillRect(localDevRect, clip, blitter);
873                 } else {
874                     SkScan::FillRect(localDevRect, clip, blitter);
875                 }
876                 break;
877             case kStroke_RectType:
878                 if (paint.isAntiAlias()) {
879                     SkScan::AntiFrameRect(localDevRect, strokeSize, clip, blitter);
880                 } else {
881                     SkScan::FrameRect(localDevRect, strokeSize, clip, blitter);
882                 }
883                 break;
884             case kHair_RectType:
885                 if (paint.isAntiAlias()) {
886                     SkScan::AntiHairRect(localDevRect, clip, blitter);
887                 } else {
888                     SkScan::HairRect(localDevRect, clip, blitter);
889                 }
890                 break;
891             default:
892                 SkDEBUGFAIL("bad rtype");
893         }
894     }
895 }
896
897 void SkDraw::drawDevMask(const SkMask& srcM, const SkPaint& paint) const {
898     if (srcM.fBounds.isEmpty()) {
899         return;
900     }
901
902     const SkMask* mask = &srcM;
903
904     SkMask dstM;
905     if (paint.getMaskFilter() &&
906         paint.getMaskFilter()->filterMask(&dstM, srcM, *fMatrix, nullptr)) {
907         mask = &dstM;
908     }
909     SkAutoMaskFreeImage ami(dstM.fImage);
910
911     SkAutoBlitterChoose blitterChooser(fDst, *fMatrix, paint);
912     SkBlitter* blitter = blitterChooser.get();
913
914     SkAAClipBlitterWrapper wrapper;
915     const SkRegion* clipRgn;
916
917     if (fRC->isBW()) {
918         clipRgn = &fRC->bwRgn();
919     } else {
920         wrapper.init(*fRC, blitter);
921         clipRgn = &wrapper.getRgn();
922         blitter = wrapper.getBlitter();
923     }
924     blitter->blitMaskRegion(*mask, *clipRgn);
925 }
926
927 static SkScalar fast_len(const SkVector& vec) {
928     SkScalar x = SkScalarAbs(vec.fX);
929     SkScalar y = SkScalarAbs(vec.fY);
930     if (x < y) {
931         SkTSwap(x, y);
932     }
933     return x + SkScalarHalf(y);
934 }
935
936 bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
937                                    SkScalar* coverage) {
938     SkASSERT(strokeWidth > 0);
939     // We need to try to fake a thick-stroke with a modulated hairline.
940
941     if (matrix.hasPerspective()) {
942         return false;
943     }
944
945     SkVector src[2], dst[2];
946     src[0].set(strokeWidth, 0);
947     src[1].set(0, strokeWidth);
948     matrix.mapVectors(dst, src, 2);
949     SkScalar len0 = fast_len(dst[0]);
950     SkScalar len1 = fast_len(dst[1]);
951     if (len0 <= SK_Scalar1 && len1 <= SK_Scalar1) {
952         if (coverage) {
953             *coverage = SkScalarAve(len0, len1);
954         }
955         return true;
956     }
957     return false;
958 }
959
960 void SkDraw::drawRRect(const SkRRect& rrect, const SkPaint& paint) const {
961     SkDEBUGCODE(this->validate());
962
963     if (fRC->isEmpty()) {
964         return;
965     }
966
967     {
968         // TODO: Investigate optimizing these options. They are in the same
969         // order as SkDraw::drawPath, which handles each case. It may be
970         // that there is no way to optimize for these using the SkRRect path.
971         SkScalar coverage;
972         if (SkDrawTreatAsHairline(paint, *fMatrix, &coverage)) {
973             goto DRAW_PATH;
974         }
975
976         if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
977             goto DRAW_PATH;
978         }
979
980         if (paint.getRasterizer()) {
981             goto DRAW_PATH;
982         }
983     }
984
985     if (paint.getMaskFilter()) {
986         // Transform the rrect into device space.
987         SkRRect devRRect;
988         if (rrect.transform(*fMatrix, &devRRect)) {
989             SkAutoBlitterChoose blitter(fDst, *fMatrix, paint);
990             if (paint.getMaskFilter()->filterRRect(devRRect, *fMatrix, *fRC, blitter.get())) {
991                 return; // filterRRect() called the blitter, so we're done
992             }
993         }
994     }
995
996 DRAW_PATH:
997     // Now fall back to the default case of using a path.
998     SkPath path;
999     path.addRRect(rrect);
1000     this->drawPath(path, paint, nullptr, true);
1001 }
1002
1003 SkScalar SkDraw::ComputeResScaleForStroking(const SkMatrix& matrix) {
1004     if (!matrix.hasPerspective()) {
1005         SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
1006         SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX],  matrix[SkMatrix::kMScaleY]);
1007         if (SkScalarsAreFinite(sx, sy)) {
1008             SkScalar scale = SkTMax(sx, sy);
1009             if (scale > 0) {
1010                 return scale;
1011             }
1012         }
1013     }
1014     return 1;
1015 }
1016
1017 void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage,
1018                          SkBlitter* customBlitter, bool doFill) const {
1019     // Do a conservative quick-reject test, since a looper or other modifier may have moved us
1020     // out of range.
1021     if (!devPath.isInverseFillType()) {
1022         // If we're a H or V line, our bounds will be empty. So we bloat here just so we don't
1023         // appear empty to the intersects call. This also gives us slop in case we're antialiasing
1024         SkRect pathBounds = devPath.getBounds().makeOutset(1, 1);
1025
1026         if (paint.getMaskFilter()) {
1027             paint.getMaskFilter()->computeFastBounds(pathBounds, &pathBounds);
1028
1029             // Need to outset the path to work-around a bug in blurmaskfilter. When that is fixed
1030             // we can remove this hack. See skbug.com/5542
1031             pathBounds.outset(7, 7);
1032         }
1033
1034         // Now compare against the clip's bounds
1035         if (!SkRect::Make(fRC->getBounds()).intersects(pathBounds)) {
1036             return;
1037         }
1038     }
1039
1040     SkBlitter* blitter = nullptr;
1041     SkAutoBlitterChoose blitterStorage;
1042     if (nullptr == customBlitter) {
1043         blitterStorage.choose(fDst, *fMatrix, paint, drawCoverage);
1044         blitter = blitterStorage.get();
1045     } else {
1046         blitter = customBlitter;
1047     }
1048
1049     if (paint.getMaskFilter()) {
1050         SkStrokeRec::InitStyle style = doFill ? SkStrokeRec::kFill_InitStyle
1051         : SkStrokeRec::kHairline_InitStyle;
1052         if (paint.getMaskFilter()->filterPath(devPath, *fMatrix, *fRC, blitter, style)) {
1053             return; // filterPath() called the blitter, so we're done
1054         }
1055     }
1056
1057     void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
1058     if (doFill) {
1059         if (paint.isAntiAlias()) {
1060             proc = SkScan::AntiFillPath;
1061         } else {
1062             proc = SkScan::FillPath;
1063         }
1064     } else {    // hairline
1065         if (paint.isAntiAlias()) {
1066             switch (paint.getStrokeCap()) {
1067                 case SkPaint::kButt_Cap:
1068                     proc = SkScan::AntiHairPath;
1069                     break;
1070                 case SkPaint::kSquare_Cap:
1071                     proc = SkScan::AntiHairSquarePath;
1072                     break;
1073                 case SkPaint::kRound_Cap:
1074                     proc = SkScan::AntiHairRoundPath;
1075                     break;
1076                 default:
1077                     proc SK_INIT_TO_AVOID_WARNING;
1078                     SkDEBUGFAIL("unknown paint cap type");
1079             }
1080         } else {
1081             switch (paint.getStrokeCap()) {
1082                 case SkPaint::kButt_Cap:
1083                     proc = SkScan::HairPath;
1084                     break;
1085                 case SkPaint::kSquare_Cap:
1086                     proc = SkScan::HairSquarePath;
1087                     break;
1088                 case SkPaint::kRound_Cap:
1089                     proc = SkScan::HairRoundPath;
1090                     break;
1091                 default:
1092                     proc SK_INIT_TO_AVOID_WARNING;
1093                     SkDEBUGFAIL("unknown paint cap type");
1094             }
1095         }
1096     }
1097     proc(devPath, *fRC, blitter);
1098 }
1099
1100 void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
1101                       const SkMatrix* prePathMatrix, bool pathIsMutable,
1102                       bool drawCoverage, SkBlitter* customBlitter) const {
1103     SkDEBUGCODE(this->validate();)
1104
1105     // nothing to draw
1106     if (fRC->isEmpty()) {
1107         return;
1108     }
1109
1110     SkPath*         pathPtr = (SkPath*)&origSrcPath;
1111     bool            doFill = true;
1112     SkPath          tmpPath;
1113     SkMatrix        tmpMatrix;
1114     const SkMatrix* matrix = fMatrix;
1115     tmpPath.setIsVolatile(true);
1116
1117     if (prePathMatrix) {
1118         if (origPaint.getPathEffect() || origPaint.getStyle() != SkPaint::kFill_Style ||
1119                 origPaint.getRasterizer()) {
1120             SkPath* result = pathPtr;
1121
1122             if (!pathIsMutable) {
1123                 result = &tmpPath;
1124                 pathIsMutable = true;
1125             }
1126             pathPtr->transform(*prePathMatrix, result);
1127             pathPtr = result;
1128         } else {
1129             tmpMatrix.setConcat(*matrix, *prePathMatrix);
1130             matrix = &tmpMatrix;
1131         }
1132     }
1133     // at this point we're done with prePathMatrix
1134     SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;)
1135
1136     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
1137
1138     {
1139         SkScalar coverage;
1140         if (SkDrawTreatAsHairline(origPaint, *matrix, &coverage)) {
1141             if (SK_Scalar1 == coverage) {
1142                 paint.writable()->setStrokeWidth(0);
1143             } else if (SkBlendMode_SupportsCoverageAsAlpha(origPaint.getBlendMode())) {
1144                 U8CPU newAlpha;
1145 #if 0
1146                 newAlpha = SkToU8(SkScalarRoundToInt(coverage *
1147                                                      origPaint.getAlpha()));
1148 #else
1149                 // this is the old technique, which we preserve for now so
1150                 // we don't change previous results (testing)
1151                 // the new way seems fine, its just (a tiny bit) different
1152                 int scale = (int)SkScalarMul(coverage, 256);
1153                 newAlpha = origPaint.getAlpha() * scale >> 8;
1154 #endif
1155                 SkPaint* writablePaint = paint.writable();
1156                 writablePaint->setStrokeWidth(0);
1157                 writablePaint->setAlpha(newAlpha);
1158             }
1159         }
1160     }
1161
1162     if (paint->getPathEffect() || paint->getStyle() != SkPaint::kFill_Style) {
1163         SkRect cullRect;
1164         const SkRect* cullRectPtr = nullptr;
1165         if (this->computeConservativeLocalClipBounds(&cullRect)) {
1166             cullRectPtr = &cullRect;
1167         }
1168         doFill = paint->getFillPath(*pathPtr, &tmpPath, cullRectPtr,
1169                                     ComputeResScaleForStroking(*fMatrix));
1170         pathPtr = &tmpPath;
1171     }
1172
1173     if (paint->getRasterizer()) {
1174         SkMask  mask;
1175         if (paint->getRasterizer()->rasterize(*pathPtr, *matrix,
1176                             &fRC->getBounds(), paint->getMaskFilter(), &mask,
1177                             SkMask::kComputeBoundsAndRenderImage_CreateMode)) {
1178             this->drawDevMask(mask, *paint);
1179             SkMask::FreeImage(mask.fImage);
1180         }
1181         return;
1182     }
1183
1184     // avoid possibly allocating a new path in transform if we can
1185     SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
1186
1187     // transform the path into device space
1188     pathPtr->transform(*matrix, devPathPtr);
1189
1190     this->drawDevPath(*devPathPtr, *paint, drawCoverage, customBlitter, doFill);
1191 }
1192
1193 void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const {
1194     SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType);
1195
1196     if (SkTreatAsSprite(*fMatrix, bitmap.dimensions(), paint)) {
1197         int ix = SkScalarRoundToInt(fMatrix->getTranslateX());
1198         int iy = SkScalarRoundToInt(fMatrix->getTranslateY());
1199
1200         SkAutoPixmapUnlock result;
1201         if (!bitmap.requestLock(&result)) {
1202             return;
1203         }
1204         const SkPixmap& pmap = result.pixmap();
1205         SkMask  mask;
1206         mask.fBounds.set(ix, iy, ix + pmap.width(), iy + pmap.height());
1207         mask.fFormat = SkMask::kA8_Format;
1208         mask.fRowBytes = SkToU32(pmap.rowBytes());
1209         // fImage is typed as writable, but in this case it is used read-only
1210         mask.fImage = (uint8_t*)pmap.addr8(0, 0);
1211
1212         this->drawDevMask(mask, paint);
1213     } else {    // need to xform the bitmap first
1214         SkRect  r;
1215         SkMask  mask;
1216
1217         r.set(0, 0,
1218               SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height()));
1219         fMatrix->mapRect(&r);
1220         r.round(&mask.fBounds);
1221
1222         // set the mask's bounds to the transformed bitmap-bounds,
1223         // clipped to the actual device
1224         {
1225             SkIRect    devBounds;
1226             devBounds.set(0, 0, fDst.width(), fDst.height());
1227             // need intersect(l, t, r, b) on irect
1228             if (!mask.fBounds.intersect(devBounds)) {
1229                 return;
1230             }
1231         }
1232
1233         mask.fFormat = SkMask::kA8_Format;
1234         mask.fRowBytes = SkAlign4(mask.fBounds.width());
1235         size_t size = mask.computeImageSize();
1236         if (0 == size) {
1237             // the mask is too big to allocated, draw nothing
1238             return;
1239         }
1240
1241         // allocate (and clear) our temp buffer to hold the transformed bitmap
1242         SkAutoTMalloc<uint8_t> storage(size);
1243         mask.fImage = storage.get();
1244         memset(mask.fImage, 0, size);
1245
1246         // now draw our bitmap(src) into mask(dst), transformed by the matrix
1247         {
1248             SkBitmap    device;
1249             device.installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), mask.fBounds.height()),
1250                                  mask.fImage, mask.fRowBytes);
1251
1252             SkCanvas c(device);
1253             // need the unclipped top/left for the translate
1254             c.translate(-SkIntToScalar(mask.fBounds.fLeft),
1255                         -SkIntToScalar(mask.fBounds.fTop));
1256             c.concat(*fMatrix);
1257
1258             // We can't call drawBitmap, or we'll infinitely recurse. Instead
1259             // we manually build a shader and draw that into our new mask
1260             SkPaint tmpPaint;
1261             tmpPaint.setFlags(paint.getFlags());
1262             tmpPaint.setFilterQuality(paint.getFilterQuality());
1263             SkAutoBitmapShaderInstall install(bitmap, tmpPaint);
1264             SkRect rr;
1265             rr.set(0, 0, SkIntToScalar(bitmap.width()),
1266                    SkIntToScalar(bitmap.height()));
1267             c.drawRect(rr, install.paintWithShader());
1268         }
1269         this->drawDevMask(mask, paint);
1270     }
1271 }
1272
1273 static bool clipped_out(const SkMatrix& m, const SkRasterClip& c,
1274                         const SkRect& srcR) {
1275     SkRect  dstR;
1276     m.mapRect(&dstR, srcR);
1277     return c.quickReject(dstR.roundOut());
1278 }
1279
1280 static bool clipped_out(const SkMatrix& matrix, const SkRasterClip& clip,
1281                         int width, int height) {
1282     SkRect  r;
1283     r.set(0, 0, SkIntToScalar(width), SkIntToScalar(height));
1284     return clipped_out(matrix, clip, r);
1285 }
1286
1287 static bool clipHandlesSprite(const SkRasterClip& clip, int x, int y, const SkPixmap& pmap) {
1288     return clip.isBW() || clip.quickContains(x, y, x + pmap.width(), y + pmap.height());
1289 }
1290
1291 void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
1292                         const SkRect* dstBounds, const SkPaint& origPaint) const {
1293     SkDEBUGCODE(this->validate();)
1294
1295     // nothing to draw
1296     if (fRC->isEmpty() ||
1297             bitmap.width() == 0 || bitmap.height() == 0 ||
1298             bitmap.colorType() == kUnknown_SkColorType) {
1299         return;
1300     }
1301
1302     SkPaint paint(origPaint);
1303     paint.setStyle(SkPaint::kFill_Style);
1304
1305     SkMatrix matrix;
1306     matrix.setConcat(*fMatrix, prematrix);
1307
1308     if (clipped_out(matrix, *fRC, bitmap.width(), bitmap.height())) {
1309         return;
1310     }
1311
1312     if (bitmap.colorType() != kAlpha_8_SkColorType
1313         && SkTreatAsSprite(matrix, bitmap.dimensions(), paint)) {
1314         //
1315         // It is safe to call lock pixels now, since we know the matrix is
1316         // (more or less) identity.
1317         //
1318         SkAutoPixmapUnlock unlocker;
1319         if (!bitmap.requestLock(&unlocker)) {
1320             return;
1321         }
1322         const SkPixmap& pmap = unlocker.pixmap();
1323         int ix = SkScalarRoundToInt(matrix.getTranslateX());
1324         int iy = SkScalarRoundToInt(matrix.getTranslateY());
1325         if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
1326             SkTBlitterAllocator allocator;
1327             // blitter will be owned by the allocator.
1328             SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, ix, iy, &allocator);
1329             if (blitter) {
1330                 SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.height()),
1331                                   *fRC, blitter);
1332                 return;
1333             }
1334             // if !blitter, then we fall-through to the slower case
1335         }
1336     }
1337
1338     // now make a temp draw on the stack, and use it
1339     //
1340     SkDraw draw(*this);
1341     draw.fMatrix = &matrix;
1342
1343     if (bitmap.colorType() == kAlpha_8_SkColorType) {
1344         draw.drawBitmapAsMask(bitmap, paint);
1345     } else {
1346         SkAutoBitmapShaderInstall install(bitmap, paint);
1347         const SkPaint& paintWithShader = install.paintWithShader();
1348         const SkRect srcBounds = SkRect::MakeIWH(bitmap.width(), bitmap.height());
1349         if (dstBounds) {
1350             this->drawRect(srcBounds, paintWithShader, &prematrix, dstBounds);
1351         } else {
1352             draw.drawRect(srcBounds, paintWithShader);
1353         }
1354     }
1355 }
1356
1357 void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& origPaint) const {
1358     SkDEBUGCODE(this->validate();)
1359
1360     // nothing to draw
1361     if (fRC->isEmpty() ||
1362             bitmap.width() == 0 || bitmap.height() == 0 ||
1363             bitmap.colorType() == kUnknown_SkColorType) {
1364         return;
1365     }
1366
1367     const SkIRect bounds = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height());
1368
1369     if (fRC->quickReject(bounds)) {
1370         return; // nothing to draw
1371     }
1372
1373     SkPaint paint(origPaint);
1374     paint.setStyle(SkPaint::kFill_Style);
1375
1376     SkAutoPixmapUnlock unlocker;
1377     if (!bitmap.requestLock(&unlocker)) {
1378         return;
1379     }
1380     const SkPixmap& pmap = unlocker.pixmap();
1381
1382     if (nullptr == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) {
1383         SkTBlitterAllocator allocator;
1384         // blitter will be owned by the allocator.
1385         SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &allocator);
1386         if (blitter) {
1387             SkScan::FillIRect(bounds, *fRC, blitter);
1388             return;
1389         }
1390     }
1391
1392     SkMatrix        matrix;
1393     SkRect          r;
1394
1395     // get a scalar version of our rect
1396     r.set(bounds);
1397
1398     // create shader with offset
1399     matrix.setTranslate(r.fLeft, r.fTop);
1400     SkAutoBitmapShaderInstall install(bitmap, paint, &matrix);
1401     const SkPaint& shaderPaint = install.paintWithShader();
1402
1403     SkDraw draw(*this);
1404     matrix.reset();
1405     draw.fMatrix = &matrix;
1406     // call ourself with a rect
1407     // is this OK if paint has a rasterizer?
1408     draw.drawRect(r, shaderPaint);
1409 }
1410
1411 ///////////////////////////////////////////////////////////////////////////////
1412
1413 #include "SkScalerContext.h"
1414 #include "SkGlyphCache.h"
1415 #include "SkTextToPathIter.h"
1416 #include "SkUtils.h"
1417
1418 bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) {
1419     // hairline glyphs are fast enough so we don't need to cache them
1420     if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) {
1421         return true;
1422     }
1423
1424     // we don't cache perspective
1425     if (ctm.hasPerspective()) {
1426         return true;
1427     }
1428
1429     SkMatrix textM;
1430     return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM));
1431 }
1432
1433 void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
1434                               SkScalar x, SkScalar y,
1435                               const SkPaint& paint) const {
1436     SkDEBUGCODE(this->validate();)
1437
1438     SkTextToPathIter iter(text, byteLength, paint, true);
1439
1440     SkMatrix    matrix;
1441     matrix.setScale(iter.getPathScale(), iter.getPathScale());
1442     matrix.postTranslate(x, y);
1443
1444     const SkPath* iterPath;
1445     SkScalar xpos, prevXPos = 0;
1446
1447     while (iter.next(&iterPath, &xpos)) {
1448         matrix.postTranslate(xpos - prevXPos, 0);
1449         if (iterPath) {
1450             const SkPaint& pnt = iter.getPaint();
1451             if (fDevice) {
1452                 fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
1453             } else {
1454                 this->drawPath(*iterPath, pnt, &matrix, false);
1455             }
1456         }
1457         prevXPos = xpos;
1458     }
1459 }
1460
1461 // disable warning : local variable used without having been initialized
1462 #if defined _WIN32
1463 #pragma warning ( push )
1464 #pragma warning ( disable : 4701 )
1465 #endif
1466
1467 ////////////////////////////////////////////////////////////////////////////////////////////////////
1468
1469 class DrawOneGlyph {
1470 public:
1471     DrawOneGlyph(const SkDraw& draw, const SkPaint& paint, SkGlyphCache* cache, SkBlitter* blitter)
1472         : fUseRegionToDraw(UsingRegionToDraw(draw.fRC))
1473         , fGlyphCache(cache)
1474         , fBlitter(blitter)
1475         , fClip(fUseRegionToDraw ? &draw.fRC->bwRgn() : nullptr)
1476         , fDraw(draw)
1477         , fPaint(paint)
1478         , fClipBounds(PickClipBounds(draw)) { }
1479
1480     void operator()(const SkGlyph& glyph, SkPoint position, SkPoint rounding) {
1481         position += rounding;
1482         // Prevent glyphs from being drawn outside of or straddling the edge of device space.
1483         // Comparisons written a little weirdly so that NaN coordinates are treated safely.
1484         auto gt = [](float a, int b) { return !(a <= (float)b); };
1485         auto lt = [](float a, int b) { return !(a >= (float)b); };
1486         if (gt(position.fX, INT_MAX - (INT16_MAX + UINT16_MAX)) ||
1487             lt(position.fX, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/)) ||
1488             gt(position.fY, INT_MAX - (INT16_MAX + UINT16_MAX)) ||
1489             lt(position.fY, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/))) {
1490             return;
1491         }
1492
1493         int left = SkScalarFloorToInt(position.fX);
1494         int top  = SkScalarFloorToInt(position.fY);
1495         SkASSERT(glyph.fWidth > 0 && glyph.fHeight > 0);
1496
1497         left += glyph.fLeft;
1498         top  += glyph.fTop;
1499
1500         int right   = left + glyph.fWidth;
1501         int bottom  = top  + glyph.fHeight;
1502
1503         SkMask mask;
1504         mask.fBounds.set(left, top, right, bottom);
1505         SkASSERT(!mask.fBounds.isEmpty());
1506
1507         if (fUseRegionToDraw) {
1508             SkRegion::Cliperator clipper(*fClip, mask.fBounds);
1509
1510             if (!clipper.done() && this->getImageData(glyph, &mask)) {
1511                 const SkIRect& cr = clipper.rect();
1512                 do {
1513                     this->blitMask(mask, cr);
1514                     clipper.next();
1515                 } while (!clipper.done());
1516             }
1517         } else {
1518             SkIRect  storage;
1519             SkIRect* bounds = &mask.fBounds;
1520
1521             // this extra test is worth it, assuming that most of the time it succeeds
1522             // since we can avoid writing to storage
1523             if (!fClipBounds.containsNoEmptyCheck(mask.fBounds)) {
1524                 if (!storage.intersectNoEmptyCheck(mask.fBounds, fClipBounds))
1525                     return;
1526                 bounds = &storage;
1527             }
1528
1529             if (this->getImageData(glyph, &mask)) {
1530                 this->blitMask(mask, *bounds);
1531             }
1532         }
1533     }
1534
1535 private:
1536     static bool UsingRegionToDraw(const SkRasterClip* rClip) {
1537         return rClip->isBW() && !rClip->isRect();
1538     }
1539
1540     static SkIRect PickClipBounds(const SkDraw& draw) {
1541         const SkRasterClip& rasterClip = *draw.fRC;
1542
1543         if (rasterClip.isBW()) {
1544             return rasterClip.bwRgn().getBounds();
1545         } else {
1546             return rasterClip.aaRgn().getBounds();
1547         }
1548     }
1549
1550     bool getImageData(const SkGlyph& glyph, SkMask* mask) {
1551         uint8_t* bits = (uint8_t*)(fGlyphCache->findImage(glyph));
1552         if (nullptr == bits) {
1553             return false;  // can't rasterize glyph
1554         }
1555         mask->fImage    = bits;
1556         mask->fRowBytes = glyph.rowBytes();
1557         mask->fFormat   = static_cast<SkMask::Format>(glyph.fMaskFormat);
1558         return true;
1559     }
1560
1561     void blitMask(const SkMask& mask, const SkIRect& clip) const {
1562         if (SkMask::kARGB32_Format == mask.fFormat) {
1563             SkBitmap bm;
1564             bm.installPixels(
1565                 SkImageInfo::MakeN32Premul(mask.fBounds.width(), mask.fBounds.height()),
1566                 (SkPMColor*)mask.fImage, mask.fRowBytes);
1567
1568             fDraw.drawSprite(bm, mask.fBounds.x(), mask.fBounds.y(), fPaint);
1569         } else {
1570             fBlitter->blitMask(mask, clip);
1571         }
1572     }
1573
1574     const bool            fUseRegionToDraw;
1575     SkGlyphCache  * const fGlyphCache;
1576     SkBlitter     * const fBlitter;
1577     const SkRegion* const fClip;
1578     const SkDraw&         fDraw;
1579     const SkPaint&        fPaint;
1580     const SkIRect         fClipBounds;
1581 };
1582
1583 ////////////////////////////////////////////////////////////////////////////////////////////////////
1584
1585 uint32_t SkDraw::scalerContextFlags() const {
1586     uint32_t flags = SkPaint::kBoostContrast_ScalerContextFlag;
1587     if (!SkImageInfoIsGammaCorrect(fDevice->imageInfo())) {
1588         flags |= SkPaint::kFakeGamma_ScalerContextFlag;
1589     }
1590     return flags;
1591 }
1592
1593 void SkDraw::drawText(const char text[], size_t byteLength,
1594                       SkScalar x, SkScalar y, const SkPaint& paint) const {
1595     SkASSERT(byteLength == 0 || text != nullptr);
1596
1597     SkDEBUGCODE(this->validate();)
1598
1599     // nothing to draw
1600     if (text == nullptr || byteLength == 0 || fRC->isEmpty()) {
1601         return;
1602     }
1603
1604     // SkScalarRec doesn't currently have a way of representing hairline stroke and
1605     // will fill if its frame-width is 0.
1606     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1607         this->drawText_asPaths(text, byteLength, x, y, paint);
1608         return;
1609     }
1610
1611     SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->scalerContextFlags(), fMatrix);
1612
1613     // The Blitter Choose needs to be live while using the blitter below.
1614     SkAutoBlitterChoose    blitterChooser(fDst, *fMatrix, paint);
1615     SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
1616     DrawOneGlyph           drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
1617
1618     SkFindAndPlaceGlyph::ProcessText(
1619         paint.getTextEncoding(), text, byteLength,
1620         {x, y}, *fMatrix, paint.getTextAlign(), cache.get(), drawOneGlyph);
1621 }
1622
1623 //////////////////////////////////////////////////////////////////////////////
1624
1625 void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
1626                                  const SkScalar pos[], int scalarsPerPosition,
1627                                  const SkPoint& offset, const SkPaint& origPaint) const {
1628     // setup our std paint, in hopes of getting hits in the cache
1629     SkPaint paint(origPaint);
1630     SkScalar matrixScale = paint.setupForAsPaths();
1631
1632     SkMatrix matrix;
1633     matrix.setScale(matrixScale, matrixScale);
1634
1635     // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
1636     paint.setStyle(SkPaint::kFill_Style);
1637     paint.setPathEffect(nullptr);
1638
1639     SkPaint::GlyphCacheProc glyphCacheProc = SkPaint::GetGlyphCacheProc(paint.getTextEncoding(),
1640                                                                         paint.isDevKernText(),
1641                                                                         true);
1642     SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->scalerContextFlags(), nullptr);
1643
1644     const char*        stop = text + byteLength;
1645     SkTextAlignProc    alignProc(paint.getTextAlign());
1646     SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
1647
1648     // Now restore the original settings, so we "draw" with whatever style/stroking.
1649     paint.setStyle(origPaint.getStyle());
1650     paint.setPathEffect(sk_ref_sp(origPaint.getPathEffect()));
1651
1652     while (text < stop) {
1653         const SkGlyph& glyph = glyphCacheProc(cache.get(), &text);
1654         if (glyph.fWidth) {
1655             const SkPath* path = cache->findPath(glyph);
1656             if (path) {
1657                 SkPoint tmsLoc;
1658                 tmsProc(pos, &tmsLoc);
1659                 SkPoint loc;
1660                 alignProc(tmsLoc, glyph, &loc);
1661
1662                 matrix[SkMatrix::kMTransX] = loc.fX;
1663                 matrix[SkMatrix::kMTransY] = loc.fY;
1664                 if (fDevice) {
1665                     fDevice->drawPath(*this, *path, paint, &matrix, false);
1666                 } else {
1667                     this->drawPath(*path, paint, &matrix, false);
1668                 }
1669             }
1670         }
1671         pos += scalarsPerPosition;
1672     }
1673 }
1674
1675 void SkDraw::drawPosText(const char text[], size_t byteLength,
1676                          const SkScalar pos[], int scalarsPerPosition,
1677                          const SkPoint& offset, const SkPaint& paint) const {
1678     SkASSERT(byteLength == 0 || text != nullptr);
1679     SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
1680
1681     SkDEBUGCODE(this->validate();)
1682
1683     // nothing to draw
1684     if (text == nullptr || byteLength == 0 || fRC->isEmpty()) {
1685         return;
1686     }
1687
1688     if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
1689         this->drawPosText_asPaths(text, byteLength, pos, scalarsPerPosition, offset, paint);
1690         return;
1691     }
1692
1693     SkAutoGlyphCache cache(paint, &fDevice->surfaceProps(), this->scalerContextFlags(), fMatrix);
1694
1695     // The Blitter Choose needs to be live while using the blitter below.
1696     SkAutoBlitterChoose    blitterChooser(fDst, *fMatrix, paint);
1697     SkAAClipBlitterWrapper wrapper(*fRC, blitterChooser.get());
1698     DrawOneGlyph           drawOneGlyph(*this, paint, cache.get(), wrapper.getBlitter());
1699     SkPaint::Align         textAlignment = paint.getTextAlign();
1700
1701     SkFindAndPlaceGlyph::ProcessPosText(
1702         paint.getTextEncoding(), text, byteLength,
1703         offset, *fMatrix, pos, scalarsPerPosition, textAlignment, cache.get(), drawOneGlyph);
1704 }
1705
1706 #if defined _WIN32
1707 #pragma warning ( pop )
1708 #endif
1709
1710 ///////////////////////////////////////////////////////////////////////////////
1711
1712 static SkScan::HairRCProc ChooseHairProc(bool doAntiAlias) {
1713     return doAntiAlias ? SkScan::AntiHairLine : SkScan::HairLine;
1714 }
1715
1716 static bool texture_to_matrix(const VertState& state, const SkPoint verts[],
1717                               const SkPoint texs[], SkMatrix* matrix) {
1718     SkPoint src[3], dst[3];
1719
1720     src[0] = texs[state.f0];
1721     src[1] = texs[state.f1];
1722     src[2] = texs[state.f2];
1723     dst[0] = verts[state.f0];
1724     dst[1] = verts[state.f1];
1725     dst[2] = verts[state.f2];
1726     return matrix->setPolyToPoly(src, dst, 3);
1727 }
1728
1729 class SkTriColorShader : public SkShader {
1730 public:
1731     SkTriColorShader();
1732
1733     class TriColorShaderContext : public SkShader::Context {
1734     public:
1735         TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&);
1736         virtual ~TriColorShaderContext();
1737         void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
1738
1739     private:
1740         bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
1741
1742         SkMatrix    fDstToUnit;
1743         SkPMColor   fColors[3];
1744         bool fSetup;
1745
1746         typedef SkShader::Context INHERITED;
1747     };
1748
1749     struct TriColorShaderData {
1750         const SkPoint* pts;
1751         const SkColor* colors;
1752         const VertState *state;
1753     };
1754
1755     SK_TO_STRING_OVERRIDE()
1756
1757     // For serialization.  This will never be called.
1758     Factory getFactory() const override { sk_throw(); return nullptr; }
1759
1760     // Supply setup data to context from drawing setup
1761     void bindSetupData(TriColorShaderData* setupData) { fSetupData = setupData; }
1762
1763     // Take the setup data from context when needed.
1764     TriColorShaderData* takeSetupData() {
1765         TriColorShaderData *data = fSetupData;
1766         fSetupData = NULL;
1767         return data;
1768     }
1769
1770 protected:
1771     size_t onContextSize(const ContextRec&) const override;
1772     Context* onCreateContext(const ContextRec& rec, void* storage) const override {
1773         return new (storage) TriColorShaderContext(*this, rec);
1774     }
1775
1776 private:
1777     TriColorShaderData *fSetupData;
1778
1779     typedef SkShader INHERITED;
1780 };
1781
1782 bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const SkColor colors[],
1783                                                     int index0, int index1, int index2) {
1784
1785     fColors[0] = SkPreMultiplyColor(colors[index0]);
1786     fColors[1] = SkPreMultiplyColor(colors[index1]);
1787     fColors[2] = SkPreMultiplyColor(colors[index2]);
1788
1789     SkMatrix m, im;
1790     m.reset();
1791     m.set(0, pts[index1].fX - pts[index0].fX);
1792     m.set(1, pts[index2].fX - pts[index0].fX);
1793     m.set(2, pts[index0].fX);
1794     m.set(3, pts[index1].fY - pts[index0].fY);
1795     m.set(4, pts[index2].fY - pts[index0].fY);
1796     m.set(5, pts[index0].fY);
1797     if (!m.invert(&im)) {
1798         return false;
1799     }
1800     // We can't call getTotalInverse(), because we explicitly don't want to look at the localmatrix
1801     // as our interators are intrinsically tied to the vertices, and nothing else.
1802     SkMatrix ctmInv;
1803     if (!this->getCTM().invert(&ctmInv)) {
1804         return false;
1805     }
1806     // TODO replace INV(m) * INV(ctm) with INV(ctm * m)
1807     fDstToUnit.setConcat(im, ctmInv);
1808     return true;
1809 }
1810
1811 #include "SkColorPriv.h"
1812 #include "SkComposeShader.h"
1813
1814 static int ScalarTo256(SkScalar v) {
1815     return static_cast<int>(SkScalarPin(v, 0, 1) * 256 + 0.5);
1816 }
1817
1818 SkTriColorShader::SkTriColorShader()
1819     : INHERITED(NULL)
1820     , fSetupData(NULL) {}
1821
1822 SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader,
1823                                                                const ContextRec& rec)
1824     : INHERITED(shader, rec)
1825     , fSetup(false) {}
1826
1827 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
1828
1829 size_t SkTriColorShader::onContextSize(const ContextRec&) const {
1830     return sizeof(TriColorShaderContext);
1831 }
1832
1833 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
1834     SkTriColorShader* parent = static_cast<SkTriColorShader*>(const_cast<SkShader*>(&fShader));
1835     TriColorShaderData* set = parent->takeSetupData();
1836     if (set) {
1837         fSetup = setup(set->pts, set->colors, set->state->f0, set->state->f1, set->state->f2);
1838     }
1839
1840     if (!fSetup) {
1841         // Invalid matrices. Not checked before so no need to assert.
1842         return;
1843     }
1844
1845     const int alphaScale = Sk255To256(this->getPaintAlpha());
1846
1847     SkPoint src;
1848
1849     for (int i = 0; i < count; i++) {
1850         fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
1851         x += 1;
1852
1853         int scale1 = ScalarTo256(src.fX);
1854         int scale2 = ScalarTo256(src.fY);
1855         int scale0 = 256 - scale1 - scale2;
1856         if (scale0 < 0) {
1857             if (scale1 > scale2) {
1858                 scale2 = 256 - scale1;
1859             } else {
1860                 scale1 = 256 - scale2;
1861             }
1862             scale0 = 0;
1863         }
1864
1865         if (256 != alphaScale) {
1866             scale0 = SkAlphaMul(scale0, alphaScale);
1867             scale1 = SkAlphaMul(scale1, alphaScale);
1868             scale2 = SkAlphaMul(scale2, alphaScale);
1869         }
1870
1871         dstC[i] = SkAlphaMulQ(fColors[0], scale0) +
1872                   SkAlphaMulQ(fColors[1], scale1) +
1873                   SkAlphaMulQ(fColors[2], scale2);
1874     }
1875 }
1876
1877 #ifndef SK_IGNORE_TO_STRING
1878 void SkTriColorShader::toString(SkString* str) const {
1879     str->append("SkTriColorShader: (");
1880
1881     this->INHERITED::toString(str);
1882
1883     str->append(")");
1884 }
1885 #endif
1886
1887 void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
1888                           const SkPoint vertices[], const SkPoint textures[],
1889                           const SkColor colors[], SkXfermode* xmode,
1890                           const uint16_t indices[], int indexCount,
1891                           const SkPaint& paint) const {
1892     SkASSERT(0 == count || vertices);
1893
1894     // abort early if there is nothing to draw
1895     if (count < 3 || (indices && indexCount < 3) || fRC->isEmpty()) {
1896         return;
1897     }
1898
1899     // transform out vertices into device coordinates
1900     SkAutoSTMalloc<16, SkPoint> storage(count);
1901     SkPoint* devVerts = storage.get();
1902     fMatrix->mapPoints(devVerts, vertices, count);
1903
1904     /*
1905         We can draw the vertices in 1 of 4 ways:
1906
1907         - solid color (no shader/texture[], no colors[])
1908         - just colors (no shader/texture[], has colors[])
1909         - just texture (has shader/texture[], no colors[])
1910         - colors * texture (has shader/texture[], has colors[])
1911
1912         Thus for texture drawing, we need both texture[] and a shader.
1913     */
1914
1915     auto triShader = sk_make_sp<SkTriColorShader>();
1916     SkPaint p(paint);
1917
1918     SkShader* shader = p.getShader();
1919     if (nullptr == shader) {
1920         // if we have no shader, we ignore the texture coordinates
1921         textures = nullptr;
1922     } else if (nullptr == textures) {
1923         // if we don't have texture coordinates, ignore the shader
1924         p.setShader(nullptr);
1925         shader = nullptr;
1926     }
1927
1928     // setup the custom shader (if needed)
1929     if (colors) {
1930         if (nullptr == textures) {
1931             // just colors (no texture)
1932             p.setShader(triShader);
1933         } else {
1934             // colors * texture
1935             SkASSERT(shader);
1936             sk_sp<SkXfermode> xfer = xmode ? sk_ref_sp(xmode)
1937                                            : SkXfermode::Make(SkXfermode::kModulate_Mode);
1938             p.setShader(SkShader::MakeComposeShader(triShader, sk_ref_sp(shader), std::move(xfer)));
1939         }
1940     }
1941
1942     SkAutoBlitterChoose blitter(fDst, *fMatrix, p);
1943     // Abort early if we failed to create a shader context.
1944     if (blitter->isNullBlitter()) {
1945         return;
1946     }
1947
1948     // setup our state and function pointer for iterating triangles
1949     VertState       state(count, indices, indexCount);
1950     VertState::Proc vertProc = state.chooseProc(vmode);
1951
1952     if (textures || colors) {
1953         SkTriColorShader::TriColorShaderData verticesSetup = { vertices, colors, &state };
1954
1955         while (vertProc(&state)) {
1956             if (textures) {
1957                 SkMatrix tempM;
1958                 if (texture_to_matrix(state, vertices, textures, &tempM)) {
1959                     SkShader::ContextRec rec(p, *fMatrix, &tempM,
1960                                              SkBlitter::PreferredShaderDest(fDst.info()));
1961                     if (!blitter->resetShaderContext(rec)) {
1962                         continue;
1963                     }
1964                 }
1965             }
1966             if (colors) {
1967                 triShader->bindSetupData(&verticesSetup);
1968             }
1969
1970             SkPoint tmp[] = {
1971                 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2]
1972             };
1973             SkScan::FillTriangle(tmp, *fRC, blitter.get());
1974             triShader->bindSetupData(NULL);
1975         }
1976     } else {
1977         // no colors[] and no texture, stroke hairlines with paint's color.
1978         SkScan::HairRCProc hairProc = ChooseHairProc(paint.isAntiAlias());
1979         const SkRasterClip& clip = *fRC;
1980         while (vertProc(&state)) {
1981             SkPoint array[] = {
1982                 devVerts[state.f0], devVerts[state.f1], devVerts[state.f2], devVerts[state.f0]
1983             };
1984             hairProc(array, 4, clip, blitter.get());
1985         }
1986     }
1987 }
1988
1989 ///////////////////////////////////////////////////////////////////////////////
1990 ///////////////////////////////////////////////////////////////////////////////
1991
1992 #ifdef SK_DEBUG
1993
1994 void SkDraw::validate() const {
1995     SkASSERT(fMatrix != nullptr);
1996     SkASSERT(fRC != nullptr);
1997
1998     const SkIRect&  cr = fRC->getBounds();
1999     SkIRect         br;
2000
2001     br.set(0, 0, fDst.width(), fDst.height());
2002     SkASSERT(cr.isEmpty() || br.contains(cr));
2003 }
2004
2005 #endif
2006
2007 ////////////////////////////////////////////////////////////////////////////////////////////////
2008
2009 #include "SkPath.h"
2010 #include "SkDraw.h"
2011 #include "SkRegion.h"
2012 #include "SkBlitter.h"
2013
2014 static bool compute_bounds(const SkPath& devPath, const SkIRect* clipBounds,
2015                            const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2016                            SkIRect* bounds) {
2017     if (devPath.isEmpty()) {
2018         return false;
2019     }
2020
2021     //  init our bounds from the path
2022     *bounds = devPath.getBounds().makeOutset(SK_ScalarHalf, SK_ScalarHalf).roundOut();
2023
2024     SkIPoint margin = SkIPoint::Make(0, 0);
2025     if (filter) {
2026         SkASSERT(filterMatrix);
2027
2028         SkMask srcM, dstM;
2029
2030         srcM.fBounds = *bounds;
2031         srcM.fFormat = SkMask::kA8_Format;
2032         if (!filter->filterMask(&dstM, srcM, *filterMatrix, &margin)) {
2033             return false;
2034         }
2035     }
2036
2037     // (possibly) trim the bounds to reflect the clip
2038     // (plus whatever slop the filter needs)
2039     if (clipBounds) {
2040         // Ugh. Guard against gigantic margins from wacky filters. Without this
2041         // check we can request arbitrary amounts of slop beyond our visible
2042         // clip, and bring down the renderer (at least on finite RAM machines
2043         // like handsets, etc.). Need to balance this invented value between
2044         // quality of large filters like blurs, and the corresponding memory
2045         // requests.
2046         static const int MAX_MARGIN = 128;
2047         if (!bounds->intersect(clipBounds->makeOutset(SkMin32(margin.fX, MAX_MARGIN),
2048                                                       SkMin32(margin.fY, MAX_MARGIN)))) {
2049             return false;
2050         }
2051     }
2052
2053     return true;
2054 }
2055
2056 static void draw_into_mask(const SkMask& mask, const SkPath& devPath,
2057                            SkStrokeRec::InitStyle style) {
2058     SkDraw draw;
2059     if (!draw.fDst.reset(mask)) {
2060         return;
2061     }
2062
2063     SkRasterClip    clip;
2064     SkMatrix        matrix;
2065     SkPaint         paint;
2066
2067     clip.setRect(SkIRect::MakeWH(mask.fBounds.width(), mask.fBounds.height()));
2068     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
2069                         -SkIntToScalar(mask.fBounds.fTop));
2070
2071     draw.fRC        = &clip;
2072     draw.fMatrix    = &matrix;
2073     paint.setAntiAlias(true);
2074     switch (style) {
2075         case SkStrokeRec::kHairline_InitStyle:
2076             SkASSERT(!paint.getStrokeWidth());
2077             paint.setStyle(SkPaint::kStroke_Style);
2078             break;
2079         case SkStrokeRec::kFill_InitStyle:
2080             SkASSERT(paint.getStyle() == SkPaint::kFill_Style);
2081             break;
2082
2083     }
2084     draw.drawPath(devPath, paint);
2085 }
2086
2087 bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
2088                         const SkMaskFilter* filter, const SkMatrix* filterMatrix,
2089                         SkMask* mask, SkMask::CreateMode mode,
2090                         SkStrokeRec::InitStyle style) {
2091     if (SkMask::kJustRenderImage_CreateMode != mode) {
2092         if (!compute_bounds(devPath, clipBounds, filter, filterMatrix, &mask->fBounds))
2093             return false;
2094     }
2095
2096     if (SkMask::kComputeBoundsAndRenderImage_CreateMode == mode) {
2097         mask->fFormat = SkMask::kA8_Format;
2098         mask->fRowBytes = mask->fBounds.width();
2099         size_t size = mask->computeImageSize();
2100         if (0 == size) {
2101             // we're too big to allocate the mask, abort
2102             return false;
2103         }
2104         mask->fImage = SkMask::AllocImage(size);
2105         memset(mask->fImage, 0, mask->computeImageSize());
2106     }
2107
2108     if (SkMask::kJustComputeBounds_CreateMode != mode) {
2109         draw_into_mask(*mask, devPath, style);
2110     }
2111
2112     return true;
2113 }