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