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