SkPaint.cpp revision f539b8cdee0204985edca028eec826ee94a0c472
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
8#include "SkPaint.h"
9#include "SkAnnotation.h"
10#include "SkAutoKern.h"
11#include "SkChecksum.h"
12#include "SkColorFilter.h"
13#include "SkData.h"
14#include "SkDeviceProperties.h"
15#include "SkDraw.h"
16#include "SkFontDescriptor.h"
17#include "SkFontHost.h"
18#include "SkGlyphCache.h"
19#include "SkImageFilter.h"
20#include "SkMaskFilter.h"
21#include "SkMaskGamma.h"
22#include "SkReadBuffer.h"
23#include "SkWriteBuffer.h"
24#include "SkPaintDefaults.h"
25#include "SkPathEffect.h"
26#include "SkRasterizer.h"
27#include "SkScalar.h"
28#include "SkScalerContext.h"
29#include "SkShader.h"
30#include "SkStringUtils.h"
31#include "SkStroke.h"
32#include "SkTextFormatParams.h"
33#include "SkTextToPathIter.h"
34#include "SkTLazy.h"
35#include "SkTypeface.h"
36#include "SkXfermode.h"
37
38// define this to get a printf for out-of-range parameter in setters
39// e.g. setTextSize(-1)
40//#define SK_REPORT_API_RANGE_CHECK
41
42SkPaint::SkPaint() {
43    fTypeface    = NULL;
44    fPathEffect  = NULL;
45    fShader      = NULL;
46    fXfermode    = NULL;
47    fMaskFilter  = NULL;
48    fColorFilter = NULL;
49    fRasterizer  = NULL;
50    fLooper      = NULL;
51    fImageFilter = NULL;
52    fAnnotation  = NULL;
53
54    fTextSize   = SkPaintDefaults_TextSize;
55    fTextScaleX = SK_Scalar1;
56    fTextSkewX  = 0;
57    fColor      = SK_ColorBLACK;
58    fWidth      = 0;
59    fMiterLimit = SkPaintDefaults_MiterLimit;
60
61    // Zero all bitfields, then set some non-zero defaults.
62    fBitfieldsUInt           = 0;
63    fBitfields.fFlags        = SkPaintDefaults_Flags;
64    fBitfields.fCapType      = kDefault_Cap;
65    fBitfields.fJoinType     = kDefault_Join;
66    fBitfields.fTextAlign    = kLeft_Align;
67    fBitfields.fStyle        = kFill_Style;
68    fBitfields.fTextEncoding = kUTF8_TextEncoding;
69    fBitfields.fHinting      = SkPaintDefaults_Hinting;
70}
71
72SkPaint::SkPaint(const SkPaint& src) {
73#define COPY(field) field = src.field
74#define REF_COPY(field) field = SkSafeRef(src.field)
75
76    REF_COPY(fTypeface);
77    REF_COPY(fPathEffect);
78    REF_COPY(fShader);
79    REF_COPY(fXfermode);
80    REF_COPY(fMaskFilter);
81    REF_COPY(fColorFilter);
82    REF_COPY(fRasterizer);
83    REF_COPY(fLooper);
84    REF_COPY(fImageFilter);
85    REF_COPY(fAnnotation);
86
87    COPY(fTextSize);
88    COPY(fTextScaleX);
89    COPY(fTextSkewX);
90    COPY(fColor);
91    COPY(fWidth);
92    COPY(fMiterLimit);
93    COPY(fBitfields);
94
95#undef COPY
96#undef REF_COPY
97}
98
99SkPaint::~SkPaint() {
100    SkSafeUnref(fTypeface);
101    SkSafeUnref(fPathEffect);
102    SkSafeUnref(fShader);
103    SkSafeUnref(fXfermode);
104    SkSafeUnref(fMaskFilter);
105    SkSafeUnref(fColorFilter);
106    SkSafeUnref(fRasterizer);
107    SkSafeUnref(fLooper);
108    SkSafeUnref(fImageFilter);
109    SkSafeUnref(fAnnotation);
110}
111
112SkPaint& SkPaint::operator=(const SkPaint& src) {
113    if (this == &src) {
114        return *this;
115    }
116
117#define COPY(field) field = src.field
118#define REF_COPY(field) SkSafeUnref(field); field = SkSafeRef(src.field)
119
120    SkASSERT(&src);
121
122    REF_COPY(fTypeface);
123    REF_COPY(fPathEffect);
124    REF_COPY(fShader);
125    REF_COPY(fXfermode);
126    REF_COPY(fMaskFilter);
127    REF_COPY(fColorFilter);
128    REF_COPY(fRasterizer);
129    REF_COPY(fLooper);
130    REF_COPY(fImageFilter);
131    REF_COPY(fAnnotation);
132
133    COPY(fTextSize);
134    COPY(fTextScaleX);
135    COPY(fTextSkewX);
136    COPY(fColor);
137    COPY(fWidth);
138    COPY(fMiterLimit);
139    COPY(fBitfields);
140
141    return *this;
142
143#undef COPY
144#undef REF_COPY
145}
146
147bool operator==(const SkPaint& a, const SkPaint& b) {
148#define EQUAL(field) (a.field == b.field)
149    return EQUAL(fTypeface)
150        && EQUAL(fPathEffect)
151        && EQUAL(fShader)
152        && EQUAL(fXfermode)
153        && EQUAL(fMaskFilter)
154        && EQUAL(fColorFilter)
155        && EQUAL(fRasterizer)
156        && EQUAL(fLooper)
157        && EQUAL(fImageFilter)
158        && EQUAL(fAnnotation)
159        && EQUAL(fTextSize)
160        && EQUAL(fTextScaleX)
161        && EQUAL(fTextSkewX)
162        && EQUAL(fColor)
163        && EQUAL(fWidth)
164        && EQUAL(fMiterLimit)
165        && EQUAL(fBitfieldsUInt)
166        ;
167#undef EQUAL
168}
169
170void SkPaint::reset() {
171    SkPaint init;
172    *this = init;
173}
174
175void SkPaint::setFilterLevel(FilterLevel level) {
176    fBitfields.fFilterLevel = level;
177}
178
179void SkPaint::setHinting(Hinting hintingLevel) {
180    fBitfields.fHinting = hintingLevel;
181}
182
183void SkPaint::setFlags(uint32_t flags) {
184    fBitfields.fFlags = flags;
185}
186
187void SkPaint::setAntiAlias(bool doAA) {
188    this->setFlags(SkSetClearMask(fBitfields.fFlags, doAA, kAntiAlias_Flag));
189}
190
191void SkPaint::setDither(bool doDither) {
192    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDither, kDither_Flag));
193}
194
195void SkPaint::setSubpixelText(bool doSubpixel) {
196    this->setFlags(SkSetClearMask(fBitfields.fFlags, doSubpixel, kSubpixelText_Flag));
197}
198
199void SkPaint::setLCDRenderText(bool doLCDRender) {
200    this->setFlags(SkSetClearMask(fBitfields.fFlags, doLCDRender, kLCDRenderText_Flag));
201}
202
203void SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) {
204    this->setFlags(SkSetClearMask(fBitfields.fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
205}
206
207void SkPaint::setAutohinted(bool useAutohinter) {
208    this->setFlags(SkSetClearMask(fBitfields.fFlags, useAutohinter, kAutoHinting_Flag));
209}
210
211void SkPaint::setLinearText(bool doLinearText) {
212    this->setFlags(SkSetClearMask(fBitfields.fFlags, doLinearText, kLinearText_Flag));
213}
214
215void SkPaint::setVerticalText(bool doVertical) {
216    this->setFlags(SkSetClearMask(fBitfields.fFlags, doVertical, kVerticalText_Flag));
217}
218
219void SkPaint::setUnderlineText(bool doUnderline) {
220    this->setFlags(SkSetClearMask(fBitfields.fFlags, doUnderline, kUnderlineText_Flag));
221}
222
223void SkPaint::setStrikeThruText(bool doStrikeThru) {
224    this->setFlags(SkSetClearMask(fBitfields.fFlags, doStrikeThru, kStrikeThruText_Flag));
225}
226
227void SkPaint::setFakeBoldText(bool doFakeBold) {
228    this->setFlags(SkSetClearMask(fBitfields.fFlags, doFakeBold, kFakeBoldText_Flag));
229}
230
231void SkPaint::setDevKernText(bool doDevKern) {
232    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDevKern, kDevKernText_Flag));
233}
234
235void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) {
236    this->setFlags(SkSetClearMask(fBitfields.fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag));
237}
238
239void SkPaint::setStyle(Style style) {
240    if ((unsigned)style < kStyleCount) {
241        fBitfields.fStyle = style;
242    } else {
243#ifdef SK_REPORT_API_RANGE_CHECK
244        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
245#endif
246    }
247}
248
249void SkPaint::setColor(SkColor color) {
250    fColor = color;
251}
252
253void SkPaint::setAlpha(U8CPU a) {
254    this->setColor(SkColorSetARGB(a, SkColorGetR(fColor),
255                                  SkColorGetG(fColor), SkColorGetB(fColor)));
256}
257
258void SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
259    this->setColor(SkColorSetARGB(a, r, g, b));
260}
261
262void SkPaint::setStrokeWidth(SkScalar width) {
263    if (width >= 0) {
264        fWidth = width;
265    } else {
266#ifdef SK_REPORT_API_RANGE_CHECK
267        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
268#endif
269    }
270}
271
272void SkPaint::setStrokeMiter(SkScalar limit) {
273    if (limit >= 0) {
274        fMiterLimit = limit;
275    } else {
276#ifdef SK_REPORT_API_RANGE_CHECK
277        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
278#endif
279    }
280}
281
282void SkPaint::setStrokeCap(Cap ct) {
283    if ((unsigned)ct < kCapCount) {
284        fBitfields.fCapType = SkToU8(ct);
285    } else {
286#ifdef SK_REPORT_API_RANGE_CHECK
287        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
288#endif
289    }
290}
291
292void SkPaint::setStrokeJoin(Join jt) {
293    if ((unsigned)jt < kJoinCount) {
294        fBitfields.fJoinType = SkToU8(jt);
295    } else {
296#ifdef SK_REPORT_API_RANGE_CHECK
297        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
298#endif
299    }
300}
301
302///////////////////////////////////////////////////////////////////////////////
303
304void SkPaint::setTextAlign(Align align) {
305    if ((unsigned)align < kAlignCount) {
306        fBitfields.fTextAlign = SkToU8(align);
307    } else {
308#ifdef SK_REPORT_API_RANGE_CHECK
309        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
310#endif
311    }
312}
313
314void SkPaint::setTextSize(SkScalar ts) {
315    if (ts >= 0) {
316        fTextSize = ts;
317    } else {
318#ifdef SK_REPORT_API_RANGE_CHECK
319        SkDebugf("SkPaint::setTextSize() called with negative value\n");
320#endif
321    }
322}
323
324void SkPaint::setTextScaleX(SkScalar scaleX) {
325    fTextScaleX = scaleX;
326}
327
328void SkPaint::setTextSkewX(SkScalar skewX) {
329    fTextSkewX = skewX;
330}
331
332void SkPaint::setTextEncoding(TextEncoding encoding) {
333    if ((unsigned)encoding <= kGlyphID_TextEncoding) {
334        fBitfields.fTextEncoding = encoding;
335    } else {
336#ifdef SK_REPORT_API_RANGE_CHECK
337        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
338#endif
339    }
340}
341
342///////////////////////////////////////////////////////////////////////////////
343
344SkTypeface* SkPaint::setTypeface(SkTypeface* font) {
345    SkRefCnt_SafeAssign(fTypeface, font);
346    return font;
347}
348
349SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) {
350    SkRefCnt_SafeAssign(fRasterizer, r);
351    return r;
352}
353
354SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) {
355    SkRefCnt_SafeAssign(fLooper, looper);
356    return looper;
357}
358
359SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
360    SkRefCnt_SafeAssign(fImageFilter, imageFilter);
361    return imageFilter;
362}
363
364SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) {
365    SkRefCnt_SafeAssign(fAnnotation, annotation);
366    return annotation;
367}
368
369///////////////////////////////////////////////////////////////////////////////
370
371static SkScalar mag2(SkScalar x, SkScalar y) {
372    return x * x + y * y;
373}
374
375static bool tooBig(const SkMatrix& m, SkScalar ma2max) {
376    return  mag2(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewY]) > ma2max
377            ||
378            mag2(m[SkMatrix::kMSkewX], m[SkMatrix::kMScaleY]) > ma2max;
379}
380
381bool SkPaint::TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM) {
382    SkASSERT(!ctm.hasPerspective());
383    SkASSERT(!textM.hasPerspective());
384
385    SkMatrix matrix;
386    matrix.setConcat(ctm, textM);
387    return tooBig(matrix, MaxCacheSize2());
388}
389
390
391///////////////////////////////////////////////////////////////////////////////
392
393#include "SkGlyphCache.h"
394#include "SkUtils.h"
395
396static void DetachDescProc(SkTypeface* typeface, const SkDescriptor* desc,
397                           void* context) {
398    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, desc);
399}
400
401int SkPaint::textToGlyphs(const void* textData, size_t byteLength,
402                          uint16_t glyphs[]) const {
403    if (byteLength == 0) {
404        return 0;
405    }
406
407    SkASSERT(textData != NULL);
408
409    if (NULL == glyphs) {
410        switch (this->getTextEncoding()) {
411        case kUTF8_TextEncoding:
412            return SkUTF8_CountUnichars((const char*)textData, byteLength);
413        case kUTF16_TextEncoding:
414            return SkUTF16_CountUnichars((const uint16_t*)textData, SkToInt(byteLength >> 1));
415        case kUTF32_TextEncoding:
416            return SkToInt(byteLength >> 2);
417        case kGlyphID_TextEncoding:
418            return SkToInt(byteLength >> 1);
419        default:
420            SkDEBUGFAIL("unknown text encoding");
421        }
422        return 0;
423    }
424
425    // if we get here, we have a valid glyphs[] array, so time to fill it in
426
427    // handle this encoding before the setup for the glyphcache
428    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
429        // we want to ignore the low bit of byteLength
430        memcpy(glyphs, textData, byteLength >> 1 << 1);
431        return SkToInt(byteLength >> 1);
432    }
433
434    SkAutoGlyphCache autoCache(*this, NULL, NULL);
435    SkGlyphCache*    cache = autoCache.getCache();
436
437    const char* text = (const char*)textData;
438    const char* stop = text + byteLength;
439    uint16_t*   gptr = glyphs;
440
441    switch (this->getTextEncoding()) {
442        case SkPaint::kUTF8_TextEncoding:
443            while (text < stop) {
444                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
445            }
446            break;
447        case SkPaint::kUTF16_TextEncoding: {
448            const uint16_t* text16 = (const uint16_t*)text;
449            const uint16_t* stop16 = (const uint16_t*)stop;
450            while (text16 < stop16) {
451                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
452            }
453            break;
454        }
455        case kUTF32_TextEncoding: {
456            const int32_t* text32 = (const int32_t*)text;
457            const int32_t* stop32 = (const int32_t*)stop;
458            while (text32 < stop32) {
459                *gptr++ = cache->unicharToGlyph(*text32++);
460            }
461            break;
462        }
463        default:
464            SkDEBUGFAIL("unknown text encoding");
465    }
466    return SkToInt(gptr - glyphs);
467}
468
469bool SkPaint::containsText(const void* textData, size_t byteLength) const {
470    if (0 == byteLength) {
471        return true;
472    }
473
474    SkASSERT(textData != NULL);
475
476    // handle this encoding before the setup for the glyphcache
477    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
478        const uint16_t* glyphID = static_cast<const uint16_t*>(textData);
479        size_t count = byteLength >> 1;
480        for (size_t i = 0; i < count; i++) {
481            if (0 == glyphID[i]) {
482                return false;
483            }
484        }
485        return true;
486    }
487
488    SkAutoGlyphCache autoCache(*this, NULL, NULL);
489    SkGlyphCache*    cache = autoCache.getCache();
490
491    switch (this->getTextEncoding()) {
492        case SkPaint::kUTF8_TextEncoding: {
493            const char* text = static_cast<const char*>(textData);
494            const char* stop = text + byteLength;
495            while (text < stop) {
496                if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) {
497                    return false;
498                }
499            }
500            break;
501        }
502        case SkPaint::kUTF16_TextEncoding: {
503            const uint16_t* text = static_cast<const uint16_t*>(textData);
504            const uint16_t* stop = text + (byteLength >> 1);
505            while (text < stop) {
506                if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) {
507                    return false;
508                }
509            }
510            break;
511        }
512        case SkPaint::kUTF32_TextEncoding: {
513            const int32_t* text = static_cast<const int32_t*>(textData);
514            const int32_t* stop = text + (byteLength >> 2);
515            while (text < stop) {
516                if (0 == cache->unicharToGlyph(*text++)) {
517                    return false;
518                }
519            }
520            break;
521        }
522        default:
523            SkDEBUGFAIL("unknown text encoding");
524            return false;
525    }
526    return true;
527}
528
529void SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count,
530                               SkUnichar textData[]) const {
531    if (count <= 0) {
532        return;
533    }
534
535    SkASSERT(glyphs != NULL);
536    SkASSERT(textData != NULL);
537
538    SkAutoGlyphCache autoCache(*this, NULL, NULL);
539    SkGlyphCache*    cache = autoCache.getCache();
540
541    for (int index = 0; index < count; index++) {
542        textData[index] = cache->glyphToUnichar(glyphs[index]);
543    }
544}
545
546///////////////////////////////////////////////////////////////////////////////
547
548static const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache,
549                                              const char** text) {
550    SkASSERT(cache != NULL);
551    SkASSERT(text != NULL);
552
553    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
554}
555
556static const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache,
557                                               const char** text) {
558    SkASSERT(cache != NULL);
559    SkASSERT(text != NULL);
560
561    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
562}
563
564static const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache,
565                                               const char** text) {
566    SkASSERT(cache != NULL);
567    SkASSERT(text != NULL);
568
569    const int32_t* ptr = *(const int32_t**)text;
570    SkUnichar uni = *ptr++;
571    *text = (const char*)ptr;
572    return cache->getUnicharMetrics(uni);
573}
574
575static const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache,
576                                               const char** text) {
577    SkASSERT(cache != NULL);
578    SkASSERT(text != NULL);
579
580    const uint16_t* ptr = *(const uint16_t**)text;
581    unsigned glyphID = *ptr;
582    ptr += 1;
583    *text = (const char*)ptr;
584    return cache->getGlyphIDMetrics(glyphID);
585}
586
587static const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache,
588                                              const char** text) {
589    SkASSERT(cache != NULL);
590    SkASSERT(text != NULL);
591
592    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
593}
594
595static const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache,
596                                               const char** text) {
597    SkASSERT(cache != NULL);
598    SkASSERT(text != NULL);
599
600    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
601}
602
603static const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache,
604                                               const char** text) {
605    SkASSERT(cache != NULL);
606    SkASSERT(text != NULL);
607
608    const int32_t* ptr = *(const int32_t**)text;
609    SkUnichar uni = *ptr++;
610    *text = (const char*)ptr;
611    return cache->getUnicharAdvance(uni);
612}
613
614static const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache,
615                                               const char** text) {
616    SkASSERT(cache != NULL);
617    SkASSERT(text != NULL);
618
619    const uint16_t* ptr = *(const uint16_t**)text;
620    unsigned glyphID = *ptr;
621    ptr += 1;
622    *text = (const char*)ptr;
623    return cache->getGlyphIDAdvance(glyphID);
624}
625
626SkMeasureCacheProc SkPaint::getMeasureCacheProc(bool needFullMetrics) const {
627    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
628        sk_getMetrics_utf8_next,
629        sk_getMetrics_utf16_next,
630        sk_getMetrics_utf32_next,
631        sk_getMetrics_glyph_next,
632
633        sk_getAdvance_utf8_next,
634        sk_getAdvance_utf16_next,
635        sk_getAdvance_utf32_next,
636        sk_getAdvance_glyph_next,
637    };
638
639    unsigned index = this->getTextEncoding();
640
641    if (!needFullMetrics && !this->isDevKernText()) {
642        index += 4;
643    }
644
645    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
646    return gMeasureCacheProcs[index];
647}
648
649///////////////////////////////////////////////////////////////////////////////
650
651static const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
652                                        const char** text, SkFixed, SkFixed) {
653    SkASSERT(cache != NULL);
654    SkASSERT(text != NULL);
655
656    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
657}
658
659static const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
660                                    const char** text, SkFixed x, SkFixed y) {
661    SkASSERT(cache != NULL);
662    SkASSERT(text != NULL);
663
664    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
665}
666
667static const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache,
668                                        const char** text, SkFixed, SkFixed) {
669    SkASSERT(cache != NULL);
670    SkASSERT(text != NULL);
671
672    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
673}
674
675static const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
676                                     const char** text, SkFixed x, SkFixed y) {
677    SkASSERT(cache != NULL);
678    SkASSERT(text != NULL);
679
680    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
681                                    x, y);
682}
683
684static const SkGlyph& sk_getMetrics_utf32_00(SkGlyphCache* cache,
685                                    const char** text, SkFixed, SkFixed) {
686    SkASSERT(cache != NULL);
687    SkASSERT(text != NULL);
688
689    const int32_t* ptr = *(const int32_t**)text;
690    SkUnichar uni = *ptr++;
691    *text = (const char*)ptr;
692    return cache->getUnicharMetrics(uni);
693}
694
695static const SkGlyph& sk_getMetrics_utf32_xy(SkGlyphCache* cache,
696                                    const char** text, SkFixed x, SkFixed y) {
697    SkASSERT(cache != NULL);
698    SkASSERT(text != NULL);
699
700    const int32_t* ptr = *(const int32_t**)text;
701    SkUnichar uni = *ptr++;
702    *text = (const char*)ptr;
703    return cache->getUnicharMetrics(uni, x, y);
704}
705
706static const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache,
707                                         const char** text, SkFixed, SkFixed) {
708    SkASSERT(cache != NULL);
709    SkASSERT(text != NULL);
710
711    const uint16_t* ptr = *(const uint16_t**)text;
712    unsigned glyphID = *ptr;
713    ptr += 1;
714    *text = (const char*)ptr;
715    return cache->getGlyphIDMetrics(glyphID);
716}
717
718static const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
719                                     const char** text, SkFixed x, SkFixed y) {
720    SkASSERT(cache != NULL);
721    SkASSERT(text != NULL);
722
723    const uint16_t* ptr = *(const uint16_t**)text;
724    unsigned glyphID = *ptr;
725    ptr += 1;
726    *text = (const char*)ptr;
727    return cache->getGlyphIDMetrics(glyphID, x, y);
728}
729
730SkDrawCacheProc SkPaint::getDrawCacheProc() const {
731    static const SkDrawCacheProc gDrawCacheProcs[] = {
732        sk_getMetrics_utf8_00,
733        sk_getMetrics_utf16_00,
734        sk_getMetrics_utf32_00,
735        sk_getMetrics_glyph_00,
736
737        sk_getMetrics_utf8_xy,
738        sk_getMetrics_utf16_xy,
739        sk_getMetrics_utf32_xy,
740        sk_getMetrics_glyph_xy
741    };
742
743    unsigned index = this->getTextEncoding();
744    if (fBitfields.fFlags & kSubpixelText_Flag) {
745        index += 4;
746    }
747
748    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
749    return gDrawCacheProcs[index];
750}
751
752///////////////////////////////////////////////////////////////////////////////
753
754#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE (   \
755SkPaint::kDevKernText_Flag          |       \
756SkPaint::kLinearText_Flag           |       \
757SkPaint::kLCDRenderText_Flag        |       \
758SkPaint::kEmbeddedBitmapText_Flag   |       \
759SkPaint::kAutoHinting_Flag          |       \
760SkPaint::kGenA8FromLCD_Flag )
761
762SkScalar SkPaint::setupForAsPaths() {
763    uint32_t flags = this->getFlags();
764    // clear the flags we don't care about
765    flags &= ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE;
766    // set the flags we do care about
767    flags |= SkPaint::kSubpixelText_Flag;
768
769    this->setFlags(flags);
770    this->setHinting(SkPaint::kNo_Hinting);
771
772    SkScalar textSize = fTextSize;
773    this->setTextSize(kCanonicalTextSizeForPaths);
774    return textSize / kCanonicalTextSizeForPaths;
775}
776
777class SkCanonicalizePaint {
778public:
779    SkCanonicalizePaint(const SkPaint& paint) : fPaint(&paint), fScale(0) {
780        if (paint.isLinearText() || SkDraw::ShouldDrawTextAsPaths(paint, SkMatrix::I())) {
781            SkPaint* p = fLazy.set(paint);
782            fScale = p->setupForAsPaths();
783            fPaint = p;
784        }
785    }
786
787    const SkPaint& getPaint() const { return *fPaint; }
788
789    /**
790     *  Returns 0 if the paint was unmodified, or the scale factor need to
791     *  the original textSize
792     */
793    SkScalar getScale() const { return fScale; }
794
795private:
796    const SkPaint*   fPaint;
797    SkScalar         fScale;
798    SkTLazy<SkPaint> fLazy;
799};
800
801static void set_bounds(const SkGlyph& g, SkRect* bounds) {
802    bounds->set(SkIntToScalar(g.fLeft),
803                SkIntToScalar(g.fTop),
804                SkIntToScalar(g.fLeft + g.fWidth),
805                SkIntToScalar(g.fTop + g.fHeight));
806}
807
808// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so
809// we don't overflow along the way
810typedef int64_t Sk48Dot16;
811
812static inline float Sk48Dot16ToScalar(Sk48Dot16 x) {
813    return (float) (x * 1.5258789e-5);   // x * (1 / 65536.0f)
814}
815
816static void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) {
817    SkScalar sx = Sk48Dot16ToScalar(dx);
818    bounds->join(SkIntToScalar(g.fLeft) + sx,
819                 SkIntToScalar(g.fTop),
820                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
821                 SkIntToScalar(g.fTop + g.fHeight));
822}
823
824static void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) {
825    SkScalar sy = Sk48Dot16ToScalar(dy);
826    bounds->join(SkIntToScalar(g.fLeft),
827                 SkIntToScalar(g.fTop) + sy,
828                 SkIntToScalar(g.fLeft + g.fWidth),
829                 SkIntToScalar(g.fTop + g.fHeight) + sy);
830}
831
832typedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16);
833
834// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY
835static SkFixed advance(const SkGlyph& glyph, int xyIndex) {
836    SkASSERT(0 == xyIndex || 1 == xyIndex);
837    return (&glyph.fAdvanceX)[xyIndex];
838}
839
840SkScalar SkPaint::measure_text(SkGlyphCache* cache,
841                               const char* text, size_t byteLength,
842                               int* count, SkRect* bounds) const {
843    SkASSERT(count);
844    if (byteLength == 0) {
845        *count = 0;
846        if (bounds) {
847            bounds->setEmpty();
848        }
849        return 0;
850    }
851
852    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(NULL != bounds);
853
854    int xyIndex;
855    JoinBoundsProc joinBoundsProc;
856    if (this->isVerticalText()) {
857        xyIndex = 1;
858        joinBoundsProc = join_bounds_y;
859    } else {
860        xyIndex = 0;
861        joinBoundsProc = join_bounds_x;
862    }
863
864    int         n = 1;
865    const char* stop = (const char*)text + byteLength;
866    const SkGlyph* g = &glyphCacheProc(cache, &text);
867    // our accumulated fixed-point advances might overflow 16.16, so we use
868    // a 48.16 (64bit) accumulator, and then convert that to scalar at the
869    // very end.
870    Sk48Dot16 x = advance(*g, xyIndex);
871
872    SkAutoKern  autokern;
873
874    if (NULL == bounds) {
875        if (this->isDevKernText()) {
876            int rsb;
877            for (; text < stop; n++) {
878                rsb = g->fRsbDelta;
879                g = &glyphCacheProc(cache, &text);
880                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex);
881            }
882        } else {
883            for (; text < stop; n++) {
884                x += advance(glyphCacheProc(cache, &text), xyIndex);
885            }
886        }
887    } else {
888        set_bounds(*g, bounds);
889        if (this->isDevKernText()) {
890            int rsb;
891            for (; text < stop; n++) {
892                rsb = g->fRsbDelta;
893                g = &glyphCacheProc(cache, &text);
894                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
895                joinBoundsProc(*g, bounds, x);
896                x += advance(*g, xyIndex);
897            }
898        } else {
899            for (; text < stop; n++) {
900                g = &glyphCacheProc(cache, &text);
901                joinBoundsProc(*g, bounds, x);
902                x += advance(*g, xyIndex);
903            }
904        }
905    }
906    SkASSERT(text == stop);
907
908    *count = n;
909    return Sk48Dot16ToScalar(x);
910}
911
912SkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bounds) const {
913    const char* text = (const char*)textData;
914    SkASSERT(text != NULL || length == 0);
915
916    SkCanonicalizePaint canon(*this);
917    const SkPaint& paint = canon.getPaint();
918    SkScalar scale = canon.getScale();
919
920    SkAutoGlyphCache    autoCache(paint, NULL, NULL);
921    SkGlyphCache*       cache = autoCache.getCache();
922
923    SkScalar width = 0;
924
925    if (length > 0) {
926        int tempCount;
927
928        width = paint.measure_text(cache, text, length, &tempCount, bounds);
929        if (scale) {
930            width = SkScalarMul(width, scale);
931            if (bounds) {
932                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
933                bounds->fTop = SkScalarMul(bounds->fTop, scale);
934                bounds->fRight = SkScalarMul(bounds->fRight, scale);
935                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
936            }
937        }
938    } else if (bounds) {
939        // ensure that even if we don't measure_text we still update the bounds
940        bounds->setEmpty();
941    }
942    return width;
943}
944
945size_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
946                          SkScalar* measuredWidth) const {
947    if (0 == length || 0 >= maxWidth) {
948        if (measuredWidth) {
949            *measuredWidth = 0;
950        }
951        return 0;
952    }
953
954    if (0 == fTextSize) {
955        if (measuredWidth) {
956            *measuredWidth = 0;
957        }
958        return length;
959    }
960
961    SkASSERT(textD != NULL);
962    const char* text = (const char*)textD;
963    const char* stop = text + length;
964
965    SkCanonicalizePaint canon(*this);
966    const SkPaint& paint = canon.getPaint();
967    SkScalar scale = canon.getScale();
968
969    // adjust max in case we changed the textSize in paint
970    if (scale) {
971        maxWidth /= scale;
972    }
973
974    SkAutoGlyphCache    autoCache(paint, NULL, NULL);
975    SkGlyphCache*       cache = autoCache.getCache();
976
977    SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(false);
978    const int        xyIndex = paint.isVerticalText() ? 1 : 0;
979    // use 64bits for our accumulator, to avoid overflowing 16.16
980    Sk48Dot16        max = SkScalarToFixed(maxWidth);
981    Sk48Dot16        width = 0;
982
983    SkAutoKern  autokern;
984
985    if (this->isDevKernText()) {
986        int rsb = 0;
987        while (text < stop) {
988            const char* curr = text;
989            const SkGlyph& g = glyphCacheProc(cache, &text);
990            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex);
991            if ((width += x) > max) {
992                width -= x;
993                text = curr;
994                break;
995            }
996            rsb = g.fRsbDelta;
997        }
998    } else {
999        while (text < stop) {
1000            const char* curr = text;
1001            SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex);
1002            if ((width += x) > max) {
1003                width -= x;
1004                text = curr;
1005                break;
1006            }
1007        }
1008    }
1009
1010    if (measuredWidth) {
1011        SkScalar scalarWidth = Sk48Dot16ToScalar(width);
1012        if (scale) {
1013            scalarWidth = SkScalarMul(scalarWidth, scale);
1014        }
1015        *measuredWidth = scalarWidth;
1016    }
1017
1018    // return the number of bytes measured
1019    return text - stop + length;
1020}
1021
1022///////////////////////////////////////////////////////////////////////////////
1023
1024static bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) {
1025    *(SkPaint::FontMetrics*)context = cache->getFontMetrics();
1026    return false;   // don't detach the cache
1027}
1028
1029static void FontMetricsDescProc(SkTypeface* typeface, const SkDescriptor* desc,
1030                                void* context) {
1031    SkGlyphCache::VisitCache(typeface, desc, FontMetricsCacheProc, context);
1032}
1033
1034SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
1035    SkCanonicalizePaint canon(*this);
1036    const SkPaint& paint = canon.getPaint();
1037    SkScalar scale = canon.getScale();
1038
1039    SkMatrix zoomMatrix, *zoomPtr = NULL;
1040    if (zoom) {
1041        zoomMatrix.setScale(zoom, zoom);
1042        zoomPtr = &zoomMatrix;
1043    }
1044
1045    FontMetrics storage;
1046    if (NULL == metrics) {
1047        metrics = &storage;
1048    }
1049
1050    paint.descriptorProc(NULL, zoomPtr, FontMetricsDescProc, metrics, true);
1051
1052    if (scale) {
1053        metrics->fTop = SkScalarMul(metrics->fTop, scale);
1054        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
1055        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
1056        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
1057        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
1058        metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale);
1059        metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
1060        metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
1061        metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
1062        metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale);
1063        metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale);
1064    }
1065    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
1066}
1067
1068///////////////////////////////////////////////////////////////////////////////
1069
1070static void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) {
1071    bounds->set(g.fLeft * scale,
1072                g.fTop * scale,
1073                (g.fLeft + g.fWidth) * scale,
1074                (g.fTop + g.fHeight) * scale);
1075}
1076
1077int SkPaint::getTextWidths(const void* textData, size_t byteLength,
1078                           SkScalar widths[], SkRect bounds[]) const {
1079    if (0 == byteLength) {
1080        return 0;
1081    }
1082
1083    SkASSERT(textData);
1084
1085    if (NULL == widths && NULL == bounds) {
1086        return this->countText(textData, byteLength);
1087    }
1088
1089    SkCanonicalizePaint canon(*this);
1090    const SkPaint& paint = canon.getPaint();
1091    SkScalar scale = canon.getScale();
1092
1093    SkAutoGlyphCache    autoCache(paint, NULL, NULL);
1094    SkGlyphCache*       cache = autoCache.getCache();
1095    SkMeasureCacheProc  glyphCacheProc;
1096    glyphCacheProc = paint.getMeasureCacheProc(NULL != bounds);
1097
1098    const char* text = (const char*)textData;
1099    const char* stop = text + byteLength;
1100    int         count = 0;
1101    const int   xyIndex = paint.isVerticalText() ? 1 : 0;
1102
1103    if (this->isDevKernText()) {
1104        // we adjust the widths returned here through auto-kerning
1105        SkAutoKern  autokern;
1106        SkFixed     prevWidth = 0;
1107
1108        if (scale) {
1109            while (text < stop) {
1110                const SkGlyph& g = glyphCacheProc(cache, &text);
1111                if (widths) {
1112                    SkFixed  adjust = autokern.adjust(g);
1113
1114                    if (count > 0) {
1115                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
1116                        *widths++ = SkScalarMul(w, scale);
1117                    }
1118                    prevWidth = advance(g, xyIndex);
1119                }
1120                if (bounds) {
1121                    set_bounds(g, bounds++, scale);
1122                }
1123                ++count;
1124            }
1125            if (count > 0 && widths) {
1126                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
1127            }
1128        } else {
1129            while (text < stop) {
1130                const SkGlyph& g = glyphCacheProc(cache, &text);
1131                if (widths) {
1132                    SkFixed  adjust = autokern.adjust(g);
1133
1134                    if (count > 0) {
1135                        *widths++ = SkFixedToScalar(prevWidth + adjust);
1136                    }
1137                    prevWidth = advance(g, xyIndex);
1138                }
1139                if (bounds) {
1140                    set_bounds(g, bounds++);
1141                }
1142                ++count;
1143            }
1144            if (count > 0 && widths) {
1145                *widths = SkFixedToScalar(prevWidth);
1146            }
1147        }
1148    } else {    // no devkern
1149        if (scale) {
1150            while (text < stop) {
1151                const SkGlyph& g = glyphCacheProc(cache, &text);
1152                if (widths) {
1153                    *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)),
1154                                            scale);
1155                }
1156                if (bounds) {
1157                    set_bounds(g, bounds++, scale);
1158                }
1159                ++count;
1160            }
1161        } else {
1162            while (text < stop) {
1163                const SkGlyph& g = glyphCacheProc(cache, &text);
1164                if (widths) {
1165                    *widths++ = SkFixedToScalar(advance(g, xyIndex));
1166                }
1167                if (bounds) {
1168                    set_bounds(g, bounds++);
1169                }
1170                ++count;
1171            }
1172        }
1173    }
1174
1175    SkASSERT(text == stop);
1176    return count;
1177}
1178
1179///////////////////////////////////////////////////////////////////////////////
1180
1181#include "SkDraw.h"
1182
1183void SkPaint::getTextPath(const void* textData, size_t length,
1184                          SkScalar x, SkScalar y, SkPath* path) const {
1185    SkASSERT(length == 0 || textData != NULL);
1186
1187    const char* text = (const char*)textData;
1188    if (text == NULL || length == 0 || path == NULL) {
1189        return;
1190    }
1191
1192    SkTextToPathIter    iter(text, length, *this, false);
1193    SkMatrix            matrix;
1194    SkScalar            prevXPos = 0;
1195
1196    matrix.setScale(iter.getPathScale(), iter.getPathScale());
1197    matrix.postTranslate(x, y);
1198    path->reset();
1199
1200    SkScalar        xpos;
1201    const SkPath*   iterPath;
1202    while (iter.next(&iterPath, &xpos)) {
1203        matrix.postTranslate(xpos - prevXPos, 0);
1204        if (iterPath) {
1205            path->addPath(*iterPath, matrix);
1206        }
1207        prevXPos = xpos;
1208    }
1209}
1210
1211void SkPaint::getPosTextPath(const void* textData, size_t length,
1212                             const SkPoint pos[], SkPath* path) const {
1213    SkASSERT(length == 0 || textData != NULL);
1214
1215    const char* text = (const char*)textData;
1216    if (text == NULL || length == 0 || path == NULL) {
1217        return;
1218    }
1219
1220    SkTextToPathIter    iter(text, length, *this, false);
1221    SkMatrix            matrix;
1222    SkPoint             prevPos;
1223    prevPos.set(0, 0);
1224
1225    matrix.setScale(iter.getPathScale(), iter.getPathScale());
1226    path->reset();
1227
1228    unsigned int    i = 0;
1229    const SkPath*   iterPath;
1230    while (iter.next(&iterPath, NULL)) {
1231        matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
1232        if (iterPath) {
1233            path->addPath(*iterPath, matrix);
1234        }
1235        prevPos = pos[i];
1236        i++;
1237    }
1238}
1239
1240static void add_flattenable(SkDescriptor* desc, uint32_t tag,
1241                            SkWriteBuffer* buffer) {
1242    buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), NULL));
1243}
1244
1245// SkFontHost can override this choice in FilterRec()
1246static SkMask::Format computeMaskFormat(const SkPaint& paint) {
1247    uint32_t flags = paint.getFlags();
1248
1249    // Antialiasing being disabled trumps all other settings.
1250    if (!(flags & SkPaint::kAntiAlias_Flag)) {
1251        return SkMask::kBW_Format;
1252    }
1253
1254    if (flags & SkPaint::kLCDRenderText_Flag) {
1255        return SkMask::kLCD16_Format;
1256    }
1257
1258    return SkMask::kA8_Format;
1259}
1260
1261// if linear-text is on, then we force hinting to be off (since that's sort of
1262// the point of linear-text.
1263static SkPaint::Hinting computeHinting(const SkPaint& paint) {
1264    SkPaint::Hinting h = paint.getHinting();
1265    if (paint.isLinearText()) {
1266        h = SkPaint::kNo_Hinting;
1267    }
1268    return h;
1269}
1270
1271// return true if the paint is just a single color (i.e. not a shader). If its
1272// a shader, then we can't compute a const luminance for it :(
1273static bool justAColor(const SkPaint& paint, SkColor* color) {
1274    SkColor c = paint.getColor();
1275
1276    SkShader* shader = paint.getShader();
1277    if (shader && !shader->asLuminanceColor(&c)) {
1278        return false;
1279    }
1280    if (paint.getColorFilter()) {
1281        c = paint.getColorFilter()->filterColor(c);
1282    }
1283    if (color) {
1284        *color = c;
1285    }
1286    return true;
1287}
1288
1289static SkColor computeLuminanceColor(const SkPaint& paint) {
1290    SkColor c;
1291    if (!justAColor(paint, &c)) {
1292        c = SkColorSetRGB(0x7F, 0x80, 0x7F);
1293    }
1294    return c;
1295}
1296
1297#define assert_byte(x)  SkASSERT(0 == ((x) >> 8))
1298
1299// Beyond this size, LCD doesn't appreciably improve quality, but it always
1300// cost more RAM and draws slower, so we set a cap.
1301#ifndef SK_MAX_SIZE_FOR_LCDTEXT
1302    #define SK_MAX_SIZE_FOR_LCDTEXT    48
1303#endif
1304
1305const SkScalar gMaxSize2ForLCDText = SK_MAX_SIZE_FOR_LCDTEXT * SK_MAX_SIZE_FOR_LCDTEXT;
1306
1307static bool too_big_for_lcd(const SkScalerContext::Rec& rec, bool checkPost2x2) {
1308    if (checkPost2x2) {
1309        SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] -
1310                        rec.fPost2x2[1][0] * rec.fPost2x2[0][1];
1311        area *= rec.fTextSize * rec.fTextSize;
1312        return area > gMaxSize2ForLCDText;
1313    } else {
1314        return rec.fTextSize > SK_MAX_SIZE_FOR_LCDTEXT;
1315    }
1316}
1317
1318/*
1319 *  Return the scalar with only limited fractional precision. Used to consolidate matrices
1320 *  that vary only slightly when we create our key into the font cache, since the font scaler
1321 *  typically returns the same looking resuts for tiny changes in the matrix.
1322 */
1323static SkScalar sk_relax(SkScalar x) {
1324    int n = sk_float_round2int(x * 1024);
1325    return n / 1024.0f;
1326}
1327
1328void SkScalerContext::MakeRec(const SkPaint& paint,
1329                              const SkDeviceProperties* deviceProperties,
1330                              const SkMatrix* deviceMatrix,
1331                              Rec* rec) {
1332    SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective());
1333
1334    SkTypeface* typeface = paint.getTypeface();
1335    if (NULL == typeface) {
1336        typeface = SkTypeface::GetDefaultTypeface();
1337    }
1338    rec->fFontID = typeface->uniqueID();
1339    rec->fTextSize = paint.getTextSize();
1340    rec->fPreScaleX = paint.getTextScaleX();
1341    rec->fPreSkewX  = paint.getTextSkewX();
1342
1343    bool checkPost2x2 = false;
1344
1345    if (deviceMatrix) {
1346        const SkMatrix::TypeMask mask = deviceMatrix->getType();
1347        if (mask & SkMatrix::kScale_Mask) {
1348            rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX());
1349            rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY());
1350            checkPost2x2 = true;
1351        } else {
1352            rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
1353        }
1354        if (mask & SkMatrix::kAffine_Mask) {
1355            rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX());
1356            rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY());
1357            checkPost2x2 = true;
1358        } else {
1359            rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
1360        }
1361    } else {
1362        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
1363        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
1364    }
1365
1366    SkPaint::Style  style = paint.getStyle();
1367    SkScalar        strokeWidth = paint.getStrokeWidth();
1368
1369    unsigned flags = 0;
1370
1371    if (paint.isFakeBoldText()) {
1372#ifdef SK_USE_FREETYPE_EMBOLDEN
1373        flags |= SkScalerContext::kEmbolden_Flag;
1374#else
1375        SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(),
1376                                                    kStdFakeBoldInterpKeys,
1377                                                    kStdFakeBoldInterpValues,
1378                                                    kStdFakeBoldInterpLength);
1379        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
1380
1381        if (style == SkPaint::kFill_Style) {
1382            style = SkPaint::kStrokeAndFill_Style;
1383            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
1384        } else {
1385            strokeWidth += extra;
1386        }
1387#endif
1388    }
1389
1390    if (paint.isDevKernText()) {
1391        flags |= SkScalerContext::kDevKernText_Flag;
1392    }
1393
1394    if (style != SkPaint::kFill_Style && strokeWidth > 0) {
1395        rec->fFrameWidth = strokeWidth;
1396        rec->fMiterLimit = paint.getStrokeMiter();
1397        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
1398
1399        if (style == SkPaint::kStrokeAndFill_Style) {
1400            flags |= SkScalerContext::kFrameAndFill_Flag;
1401        }
1402    } else {
1403        rec->fFrameWidth = 0;
1404        rec->fMiterLimit = 0;
1405        rec->fStrokeJoin = 0;
1406    }
1407
1408    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
1409
1410    if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) {
1411        if (too_big_for_lcd(*rec, checkPost2x2)) {
1412            rec->fMaskFormat = SkMask::kA8_Format;
1413            flags |= SkScalerContext::kGenA8FromLCD_Flag;
1414        } else {
1415            SkPixelGeometry geometry = deviceProperties
1416                                     ? deviceProperties->pixelGeometry()
1417                                     : SkSurfacePropsDefaultPixelGeometry();
1418            switch (geometry) {
1419                case kUnknown_SkPixelGeometry:
1420                    // eeek, can't support LCD
1421                    rec->fMaskFormat = SkMask::kA8_Format;
1422                    flags |= SkScalerContext::kGenA8FromLCD_Flag;
1423                    break;
1424                case kRGB_H_SkPixelGeometry:
1425                    // our default, do nothing.
1426                    break;
1427                case kBGR_H_SkPixelGeometry:
1428                    flags |= SkScalerContext::kLCD_BGROrder_Flag;
1429                    break;
1430                case kRGB_V_SkPixelGeometry:
1431                    flags |= SkScalerContext::kLCD_Vertical_Flag;
1432                    break;
1433                case kBGR_V_SkPixelGeometry:
1434                    flags |= SkScalerContext::kLCD_Vertical_Flag;
1435                    flags |= SkScalerContext::kLCD_BGROrder_Flag;
1436                    break;
1437            }
1438        }
1439    }
1440
1441    if (paint.isEmbeddedBitmapText()) {
1442        flags |= SkScalerContext::kEmbeddedBitmapText_Flag;
1443    }
1444    if (paint.isSubpixelText()) {
1445        flags |= SkScalerContext::kSubpixelPositioning_Flag;
1446    }
1447    if (paint.isAutohinted()) {
1448        flags |= SkScalerContext::kForceAutohinting_Flag;
1449    }
1450    if (paint.isVerticalText()) {
1451        flags |= SkScalerContext::kVertical_Flag;
1452    }
1453    if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
1454        flags |= SkScalerContext::kGenA8FromLCD_Flag;
1455    }
1456    rec->fFlags = SkToU16(flags);
1457
1458    // these modify fFlags, so do them after assigning fFlags
1459    rec->setHinting(computeHinting(paint));
1460
1461    rec->setLuminanceColor(computeLuminanceColor(paint));
1462
1463    if (NULL == deviceProperties) {
1464        rec->setDeviceGamma(SK_GAMMA_EXPONENT);
1465        rec->setPaintGamma(SK_GAMMA_EXPONENT);
1466    } else {
1467        rec->setDeviceGamma(deviceProperties->gamma());
1468
1469        //For now always set the paint gamma equal to the device gamma.
1470        //The math in SkMaskGamma can handle them being different,
1471        //but it requires superluminous masks when
1472        //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
1473        rec->setPaintGamma(deviceProperties->gamma());
1474    }
1475
1476#ifdef SK_GAMMA_CONTRAST
1477    rec->setContrast(SK_GAMMA_CONTRAST);
1478#else
1479    /**
1480     * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
1481     * With lower values small text appears washed out (though correctly so).
1482     * With higher values lcd fringing is worse and the smoothing effect of
1483     * partial coverage is diminished.
1484     */
1485    rec->setContrast(0.5f);
1486#endif
1487
1488    rec->fReservedAlign = 0;
1489
1490    /*  Allow the fonthost to modify our rec before we use it as a key into the
1491        cache. This way if we're asking for something that they will ignore,
1492        they can modify our rec up front, so we don't create duplicate cache
1493        entries.
1494     */
1495    typeface->onFilterRec(rec);
1496
1497    // be sure to call PostMakeRec(rec) before you actually use it!
1498}
1499
1500/**
1501 * In order to call cachedDeviceLuminance, cachedPaintLuminance, or
1502 * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue
1503 * to hold it until the returned pointer is refed or forgotten.
1504 */
1505SK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex);
1506
1507static SkMaskGamma* gLinearMaskGamma = NULL;
1508static SkMaskGamma* gMaskGamma = NULL;
1509static SkScalar gContrast = SK_ScalarMin;
1510static SkScalar gPaintGamma = SK_ScalarMin;
1511static SkScalar gDeviceGamma = SK_ScalarMin;
1512/**
1513 * The caller must hold the gMaskGammaCacheMutex and continue to hold it until
1514 * the returned SkMaskGamma pointer is refed or forgotten.
1515 */
1516static const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) {
1517    gMaskGammaCacheMutex.assertHeld();
1518    if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) {
1519        if (NULL == gLinearMaskGamma) {
1520            gLinearMaskGamma = SkNEW(SkMaskGamma);
1521        }
1522        return *gLinearMaskGamma;
1523    }
1524    if (gContrast != contrast || gPaintGamma != paintGamma || gDeviceGamma != deviceGamma) {
1525        SkSafeUnref(gMaskGamma);
1526        gMaskGamma = SkNEW_ARGS(SkMaskGamma, (contrast, paintGamma, deviceGamma));
1527        gContrast = contrast;
1528        gPaintGamma = paintGamma;
1529        gDeviceGamma = deviceGamma;
1530    }
1531    return *gMaskGamma;
1532}
1533
1534/*static*/ void SkPaint::Term() {
1535    SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
1536
1537    SkSafeUnref(gLinearMaskGamma);
1538    gLinearMaskGamma = NULL;
1539    SkSafeUnref(gMaskGamma);
1540    gMaskGamma = NULL;
1541    SkDEBUGCODE(gContrast = SK_ScalarMin;)
1542    SkDEBUGCODE(gPaintGamma = SK_ScalarMin;)
1543    SkDEBUGCODE(gDeviceGamma = SK_ScalarMin;)
1544}
1545
1546/**
1547 *  We ensure that the rec is self-consistent and efficient (where possible)
1548 */
1549void SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) {
1550    /**
1551     *  If we're asking for A8, we force the colorlum to be gray, since that
1552     *  limits the number of unique entries, and the scaler will only look at
1553     *  the lum of one of them.
1554     */
1555    switch (rec->fMaskFormat) {
1556        case SkMask::kLCD16_Format:
1557        case SkMask::kLCD32_Format: {
1558            // filter down the luminance color to a finite number of bits
1559            SkColor color = rec->getLuminanceColor();
1560            rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
1561            break;
1562        }
1563        case SkMask::kA8_Format: {
1564            // filter down the luminance to a single component, since A8 can't
1565            // use per-component information
1566            SkColor color = rec->getLuminanceColor();
1567            U8CPU lum = SkComputeLuminance(SkColorGetR(color),
1568                                           SkColorGetG(color),
1569                                           SkColorGetB(color));
1570            // reduce to our finite number of bits
1571            color = SkColorSetRGB(lum, lum, lum);
1572            rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
1573            break;
1574        }
1575        case SkMask::kBW_Format:
1576            // No need to differentiate gamma if we're BW
1577            rec->ignorePreBlend();
1578            break;
1579    }
1580}
1581
1582#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
1583
1584#ifdef SK_DEBUG
1585    #define TEST_DESC
1586#endif
1587
1588/*
1589 *  ignoreGamma tells us that the caller just wants metrics that are unaffected
1590 *  by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1,
1591 *  contrast = 0, luminanceColor = transparent black.
1592 */
1593void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
1594                             const SkMatrix* deviceMatrix,
1595                             void (*proc)(SkTypeface*, const SkDescriptor*, void*),
1596                             void* context, bool ignoreGamma) const {
1597    SkScalerContext::Rec    rec;
1598
1599    SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec);
1600    if (ignoreGamma) {
1601        rec.ignorePreBlend();
1602    }
1603
1604    size_t          descSize = sizeof(rec);
1605    int             entryCount = 1;
1606    SkPathEffect*   pe = this->getPathEffect();
1607    SkMaskFilter*   mf = this->getMaskFilter();
1608    SkRasterizer*   ra = this->getRasterizer();
1609
1610    SkWriteBuffer    peBuffer, mfBuffer, raBuffer;
1611
1612    if (pe) {
1613        peBuffer.writeFlattenable(pe);
1614        descSize += peBuffer.bytesWritten();
1615        entryCount += 1;
1616        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
1617        // seems like we could support kLCD as well at this point...
1618    }
1619    if (mf) {
1620        mfBuffer.writeFlattenable(mf);
1621        descSize += mfBuffer.bytesWritten();
1622        entryCount += 1;
1623        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
1624        /* Pre-blend is not currently applied to filtered text.
1625           The primary filter is blur, for which contrast makes no sense,
1626           and for which the destination guess error is more visible.
1627           Also, all existing users of blur have calibrated for linear. */
1628        rec.ignorePreBlend();
1629    }
1630    if (ra) {
1631        raBuffer.writeFlattenable(ra);
1632        descSize += raBuffer.bytesWritten();
1633        entryCount += 1;
1634        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
1635    }
1636
1637    ///////////////////////////////////////////////////////////////////////////
1638    // Now that we're done tweaking the rec, call the PostMakeRec cleanup
1639    SkScalerContext::PostMakeRec(*this, &rec);
1640
1641    descSize += SkDescriptor::ComputeOverhead(entryCount);
1642
1643    SkAutoDescriptor    ad(descSize);
1644    SkDescriptor*       desc = ad.getDesc();
1645
1646    desc->init();
1647    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
1648
1649    if (pe) {
1650        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
1651    }
1652    if (mf) {
1653        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
1654    }
1655    if (ra) {
1656        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
1657    }
1658
1659    SkASSERT(descSize == desc->getLength());
1660    desc->computeChecksum();
1661
1662#ifdef TEST_DESC
1663    {
1664        // Check that we completely write the bytes in desc (our key), and that
1665        // there are no uninitialized bytes. If there were, then we would get
1666        // false-misses (or worse, false-hits) in our fontcache.
1667        //
1668        // We do this buy filling 2 others, one with 0s and the other with 1s
1669        // and create those, and then check that all 3 are identical.
1670        SkAutoDescriptor    ad1(descSize);
1671        SkAutoDescriptor    ad2(descSize);
1672        SkDescriptor*       desc1 = ad1.getDesc();
1673        SkDescriptor*       desc2 = ad2.getDesc();
1674
1675        memset(desc1, 0x00, descSize);
1676        memset(desc2, 0xFF, descSize);
1677
1678        desc1->init();
1679        desc2->init();
1680        desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
1681        desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
1682
1683        if (pe) {
1684            add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer);
1685            add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer);
1686        }
1687        if (mf) {
1688            add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer);
1689            add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer);
1690        }
1691        if (ra) {
1692            add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer);
1693            add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer);
1694        }
1695
1696        SkASSERT(descSize == desc1->getLength());
1697        SkASSERT(descSize == desc2->getLength());
1698        desc1->computeChecksum();
1699        desc2->computeChecksum();
1700        SkASSERT(!memcmp(desc, desc1, descSize));
1701        SkASSERT(!memcmp(desc, desc2, descSize));
1702    }
1703#endif
1704
1705    proc(fTypeface, desc, context);
1706}
1707
1708SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties,
1709                                   const SkMatrix* deviceMatrix,
1710                                   bool ignoreGamma) const {
1711    SkGlyphCache* cache;
1712    this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma);
1713    return cache;
1714}
1715
1716/**
1717 * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend.
1718 */
1719//static
1720SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Rec& rec) {
1721    SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
1722    const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(),
1723                                                   rec.getPaintGamma(),
1724                                                   rec.getDeviceGamma());
1725    return maskGamma.preBlend(rec.getLuminanceColor());
1726}
1727
1728size_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma,
1729                                        SkScalar deviceGamma, int* width, int* height) {
1730    SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
1731    const SkMaskGamma& maskGamma = cachedMaskGamma(contrast,
1732                                                   paintGamma,
1733                                                   deviceGamma);
1734
1735    maskGamma.getGammaTableDimensions(width, height);
1736    size_t size = (*width)*(*height)*sizeof(uint8_t);
1737
1738    return size;
1739}
1740
1741void SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
1742                                      void* data) {
1743    SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
1744    const SkMaskGamma& maskGamma = cachedMaskGamma(contrast,
1745                                                   paintGamma,
1746                                                   deviceGamma);
1747    int width, height;
1748    maskGamma.getGammaTableDimensions(&width, &height);
1749    size_t size = width*height*sizeof(uint8_t);
1750    const uint8_t* gammaTables = maskGamma.getGammaTables();
1751    memcpy(data, gammaTables, size);
1752}
1753
1754
1755///////////////////////////////////////////////////////////////////////////////
1756
1757#include "SkStream.h"
1758
1759static uintptr_t asint(const void* p) {
1760    return reinterpret_cast<uintptr_t>(p);
1761}
1762
1763union Scalar32 {
1764    SkScalar    fScalar;
1765    uint32_t    f32;
1766};
1767
1768static uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
1769    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
1770    Scalar32 tmp;
1771    tmp.fScalar = value;
1772    *ptr = tmp.f32;
1773    return ptr + 1;
1774}
1775
1776static SkScalar read_scalar(const uint32_t*& ptr) {
1777    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
1778    Scalar32 tmp;
1779    tmp.f32 = *ptr++;
1780    return tmp.fScalar;
1781}
1782
1783static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
1784    SkASSERT(a == (uint8_t)a);
1785    SkASSERT(b == (uint8_t)b);
1786    SkASSERT(c == (uint8_t)c);
1787    SkASSERT(d == (uint8_t)d);
1788    return (a << 24) | (b << 16) | (c << 8) | d;
1789}
1790
1791#ifdef SK_DEBUG
1792    static void ASSERT_FITS_IN(uint32_t value, int bitCount) {
1793        SkASSERT(bitCount > 0 && bitCount <= 32);
1794        uint32_t mask = ~0U;
1795        mask >>= (32 - bitCount);
1796        SkASSERT(0 == (value & ~mask));
1797    }
1798#else
1799    #define ASSERT_FITS_IN(value, bitcount)
1800#endif
1801
1802enum FlatFlags {
1803    kHasTypeface_FlatFlag                      = 0x01,
1804    kHasEffects_FlatFlag                       = 0x02,
1805    kHasNonDefaultPaintOptionsAndroid_FlatFlag = 0x04,
1806
1807    kFlatFlagMask = 0x7,
1808};
1809
1810enum BitsPerField {
1811    kFlags_BPF  = 16,
1812    kHint_BPF   = 2,
1813    kAlign_BPF  = 2,
1814    kFilter_BPF = 2,
1815    kFlatFlags_BPF  = 3,
1816};
1817
1818static inline int BPF_Mask(int bits) {
1819    return (1 << bits) - 1;
1820}
1821
1822static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align,
1823                                 unsigned filter, unsigned flatFlags) {
1824    ASSERT_FITS_IN(flags, kFlags_BPF);
1825    ASSERT_FITS_IN(hint, kHint_BPF);
1826    ASSERT_FITS_IN(align, kAlign_BPF);
1827    ASSERT_FITS_IN(filter, kFilter_BPF);
1828    ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF);
1829
1830    // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly
1831    // add more bits in the future.
1832    return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags;
1833}
1834
1835static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
1836    paint->setFlags(packed >> 16);
1837    paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF)));
1838    paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF)));
1839    paint->setFilterLevel((SkPaint::FilterLevel)((packed >> 10) & BPF_Mask(kFilter_BPF)));
1840    return (FlatFlags)(packed & kFlatFlagMask);
1841}
1842
1843// V22_COMPATIBILITY_CODE
1844static FlatFlags unpack_paint_flags_v22(SkPaint* paint, uint32_t packed) {
1845    enum {
1846        kFilterBitmap_Flag    = 0x02,
1847        kHighQualityFilterBitmap_Flag = 0x4000,
1848
1849        kAll_Flags = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag
1850    };
1851
1852    // previously flags:16, textAlign:8, flatFlags:8
1853    // now flags:16, hinting:4, textAlign:4, flatFlags:8
1854    unsigned flags = packed >> 16;
1855    int filter = 0;
1856    if (flags & kFilterBitmap_Flag) {
1857        filter |= 1;
1858    }
1859    if (flags & kHighQualityFilterBitmap_Flag) {
1860        filter |= 2;
1861    }
1862    paint->setFilterLevel((SkPaint::FilterLevel)filter);
1863    flags &= ~kAll_Flags;   // remove these (now dead) bit flags
1864
1865    paint->setFlags(flags);
1866
1867    // hinting added later. 0 in this nibble means use the default.
1868    uint32_t hinting = (packed >> 12) & 0xF;
1869    paint->setHinting(0 == hinting ? SkPaint::kNormal_Hinting : static_cast<SkPaint::Hinting>(hinting-1));
1870    paint->setTextAlign(static_cast<SkPaint::Align>((packed >> 8) & 0xF));
1871    return (FlatFlags)(packed & kFlatFlagMask);
1872}
1873
1874// The size of a flat paint's POD fields
1875static const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
1876                                        1 * sizeof(SkColor) +
1877                                        1 * sizeof(uint16_t) +
1878                                        6 * sizeof(uint8_t);
1879
1880/*  To save space/time, we analyze the paint, and write a truncated version of
1881    it if there are not tricky elements like shaders, etc.
1882 */
1883void SkPaint::flatten(SkWriteBuffer& buffer) const {
1884    uint8_t flatFlags = 0;
1885    if (this->getTypeface()) {
1886        flatFlags |= kHasTypeface_FlatFlag;
1887    }
1888    if (asint(this->getPathEffect()) |
1889        asint(this->getShader()) |
1890        asint(this->getXfermode()) |
1891        asint(this->getMaskFilter()) |
1892        asint(this->getColorFilter()) |
1893        asint(this->getRasterizer()) |
1894        asint(this->getLooper()) |
1895        asint(this->getAnnotation()) |
1896        asint(this->getImageFilter())) {
1897        flatFlags |= kHasEffects_FlatFlag;
1898    }
1899
1900    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
1901    uint32_t* ptr = buffer.reserve(kPODPaintSize);
1902
1903    ptr = write_scalar(ptr, this->getTextSize());
1904    ptr = write_scalar(ptr, this->getTextScaleX());
1905    ptr = write_scalar(ptr, this->getTextSkewX());
1906    ptr = write_scalar(ptr, this->getStrokeWidth());
1907    ptr = write_scalar(ptr, this->getStrokeMiter());
1908    *ptr++ = this->getColor();
1909
1910    *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(),
1911                              this->getFilterLevel(), flatFlags);
1912    *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
1913                    this->getStyle(), this->getTextEncoding());
1914
1915    // now we're done with ptr and the (pre)reserved space. If we need to write
1916    // additional fields, use the buffer directly
1917    if (flatFlags & kHasTypeface_FlatFlag) {
1918        buffer.writeTypeface(this->getTypeface());
1919    }
1920    if (flatFlags & kHasEffects_FlatFlag) {
1921        buffer.writeFlattenable(this->getPathEffect());
1922        buffer.writeFlattenable(this->getShader());
1923        buffer.writeFlattenable(this->getXfermode());
1924        buffer.writeFlattenable(this->getMaskFilter());
1925        buffer.writeFlattenable(this->getColorFilter());
1926        buffer.writeFlattenable(this->getRasterizer());
1927        buffer.writeFlattenable(this->getLooper());
1928        buffer.writeFlattenable(this->getImageFilter());
1929
1930        if (fAnnotation) {
1931            buffer.writeBool(true);
1932            fAnnotation->writeToBuffer(buffer);
1933        } else {
1934            buffer.writeBool(false);
1935        }
1936    }
1937}
1938
1939void SkPaint::unflatten(SkReadBuffer& buffer) {
1940    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
1941    const void* podData = buffer.skip(kPODPaintSize);
1942    const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
1943
1944    // the order we read must match the order we wrote in flatten()
1945    this->setTextSize(read_scalar(pod));
1946    this->setTextScaleX(read_scalar(pod));
1947    this->setTextSkewX(read_scalar(pod));
1948    this->setStrokeWidth(read_scalar(pod));
1949    this->setStrokeMiter(read_scalar(pod));
1950    this->setColor(*pod++);
1951
1952    unsigned flatFlags = 0;
1953    if (buffer.isVersionLT(SkReadBuffer::kFilterLevelIsEnum_Version)) {
1954        flatFlags = unpack_paint_flags_v22(this, *pod++);
1955    } else {
1956        flatFlags = unpack_paint_flags(this, *pod++);
1957    }
1958
1959    uint32_t tmp = *pod++;
1960    this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
1961    this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
1962    this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
1963    this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
1964
1965    if (flatFlags & kHasTypeface_FlatFlag) {
1966        this->setTypeface(buffer.readTypeface());
1967    } else {
1968        this->setTypeface(NULL);
1969    }
1970
1971    if (flatFlags & kHasEffects_FlatFlag) {
1972        SkSafeUnref(this->setPathEffect(buffer.readPathEffect()));
1973        SkSafeUnref(this->setShader(buffer.readShader()));
1974        SkSafeUnref(this->setXfermode(buffer.readXfermode()));
1975        SkSafeUnref(this->setMaskFilter(buffer.readMaskFilter()));
1976        SkSafeUnref(this->setColorFilter(buffer.readColorFilter()));
1977        SkSafeUnref(this->setRasterizer(buffer.readRasterizer()));
1978        SkSafeUnref(this->setLooper(buffer.readDrawLooper()));
1979        SkSafeUnref(this->setImageFilter(buffer.readImageFilter()));
1980
1981        if (buffer.readBool()) {
1982            this->setAnnotation(SkAnnotation::Create(buffer))->unref();
1983        }
1984    } else {
1985        this->setPathEffect(NULL);
1986        this->setShader(NULL);
1987        this->setXfermode(NULL);
1988        this->setMaskFilter(NULL);
1989        this->setColorFilter(NULL);
1990        this->setRasterizer(NULL);
1991        this->setLooper(NULL);
1992        this->setImageFilter(NULL);
1993    }
1994
1995    if (buffer.isVersionLT(SkReadBuffer::kRemoveAndroidPaintOpts_Version) &&
1996            flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
1997        SkString tag;
1998        buffer.readUInt();
1999        buffer.readString(&tag);
2000        buffer.readBool();
2001    }
2002}
2003
2004///////////////////////////////////////////////////////////////////////////////
2005
2006SkShader* SkPaint::setShader(SkShader* shader) {
2007    SkRefCnt_SafeAssign(fShader, shader);
2008    return shader;
2009}
2010
2011SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
2012    SkRefCnt_SafeAssign(fColorFilter, filter);
2013    return filter;
2014}
2015
2016SkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
2017    SkRefCnt_SafeAssign(fXfermode, mode);
2018    return mode;
2019}
2020
2021SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
2022    SkSafeUnref(fXfermode);
2023    fXfermode = SkXfermode::Create(mode);
2024    return fXfermode;
2025}
2026
2027SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
2028    SkRefCnt_SafeAssign(fPathEffect, effect);
2029    return effect;
2030}
2031
2032SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
2033    SkRefCnt_SafeAssign(fMaskFilter, filter);
2034    return filter;
2035}
2036
2037///////////////////////////////////////////////////////////////////////////////
2038
2039bool SkPaint::getFillPath(const SkPath& src, SkPath* dst,
2040                          const SkRect* cullRect) const {
2041    SkStrokeRec rec(*this);
2042
2043    const SkPath* srcPtr = &src;
2044    SkPath tmpPath;
2045
2046    if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) {
2047        srcPtr = &tmpPath;
2048    }
2049
2050    if (!rec.applyToPath(dst, *srcPtr)) {
2051        if (srcPtr == &tmpPath) {
2052            // If path's were copy-on-write, this trick would not be needed.
2053            // As it is, we want to save making a deep-copy from tmpPath -> dst
2054            // since we know we're just going to delete tmpPath when we return,
2055            // so the swap saves that copy.
2056            dst->swap(tmpPath);
2057        } else {
2058            *dst = *srcPtr;
2059        }
2060    }
2061    return !rec.isHairlineStyle();
2062}
2063
2064const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
2065                                           SkRect* storage,
2066                                           Style style) const {
2067    SkASSERT(storage);
2068
2069    const SkRect* src = &origSrc;
2070
2071    if (this->getLooper()) {
2072        SkASSERT(this->getLooper()->canComputeFastBounds(*this));
2073        this->getLooper()->computeFastBounds(*this, *src, storage);
2074        return *storage;
2075    }
2076
2077    SkRect tmpSrc;
2078    if (this->getPathEffect()) {
2079        this->getPathEffect()->computeFastBounds(&tmpSrc, origSrc);
2080        src = &tmpSrc;
2081    }
2082
2083    if (kFill_Style != style) {
2084        // since we're stroked, outset the rect by the radius (and join type)
2085        SkScalar radius = SkScalarHalf(this->getStrokeWidth());
2086        if (0 == radius) {  // hairline
2087            radius = SK_Scalar1;
2088        } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
2089            SkScalar scale = this->getStrokeMiter();
2090            if (scale > SK_Scalar1) {
2091                radius = SkScalarMul(radius, scale);
2092            }
2093        }
2094        storage->set(src->fLeft - radius, src->fTop - radius,
2095                     src->fRight + radius, src->fBottom + radius);
2096    } else {
2097        *storage = *src;
2098    }
2099
2100    if (this->getMaskFilter()) {
2101        this->getMaskFilter()->computeFastBounds(*storage, storage);
2102    }
2103
2104    if (this->getImageFilter()) {
2105        this->getImageFilter()->computeFastBounds(*storage, storage);
2106    }
2107
2108    return *storage;
2109}
2110
2111#ifndef SK_IGNORE_TO_STRING
2112
2113void SkPaint::toString(SkString* str) const {
2114    str->append("<dl><dt>SkPaint:</dt><dd><dl>");
2115
2116    SkTypeface* typeface = this->getTypeface();
2117    if (typeface) {
2118        SkDynamicMemoryWStream ostream;
2119        typeface->serialize(&ostream);
2120        SkAutoTUnref<SkStreamAsset> istream(ostream.detachAsStream());
2121        SkFontDescriptor descriptor(istream);
2122
2123        str->append("<dt>Font Family Name:</dt><dd>");
2124        str->append(descriptor.getFamilyName());
2125        str->append("</dd><dt>Font Full Name:</dt><dd>");
2126        str->append(descriptor.getFullName());
2127        str->append("</dd><dt>Font PS Name:</dt><dd>");
2128        str->append(descriptor.getPostscriptName());
2129        str->append("</dd><dt>Font File Name:</dt><dd>");
2130        str->append(descriptor.getFontFileName());
2131        str->append("</dd>");
2132    }
2133
2134    str->append("<dt>TextSize:</dt><dd>");
2135    str->appendScalar(this->getTextSize());
2136    str->append("</dd>");
2137
2138    str->append("<dt>TextScaleX:</dt><dd>");
2139    str->appendScalar(this->getTextScaleX());
2140    str->append("</dd>");
2141
2142    str->append("<dt>TextSkewX:</dt><dd>");
2143    str->appendScalar(this->getTextSkewX());
2144    str->append("</dd>");
2145
2146    SkPathEffect* pathEffect = this->getPathEffect();
2147    if (pathEffect) {
2148        str->append("<dt>PathEffect:</dt><dd>");
2149        str->append("</dd>");
2150    }
2151
2152    SkShader* shader = this->getShader();
2153    if (shader) {
2154        str->append("<dt>Shader:</dt><dd>");
2155        shader->toString(str);
2156        str->append("</dd>");
2157    }
2158
2159    SkXfermode* xfer = this->getXfermode();
2160    if (xfer) {
2161        str->append("<dt>Xfermode:</dt><dd>");
2162        xfer->toString(str);
2163        str->append("</dd>");
2164    }
2165
2166    SkMaskFilter* maskFilter = this->getMaskFilter();
2167    if (maskFilter) {
2168        str->append("<dt>MaskFilter:</dt><dd>");
2169        maskFilter->toString(str);
2170        str->append("</dd>");
2171    }
2172
2173    SkColorFilter* colorFilter = this->getColorFilter();
2174    if (colorFilter) {
2175        str->append("<dt>ColorFilter:</dt><dd>");
2176        colorFilter->toString(str);
2177        str->append("</dd>");
2178    }
2179
2180    SkRasterizer* rasterizer = this->getRasterizer();
2181    if (rasterizer) {
2182        str->append("<dt>Rasterizer:</dt><dd>");
2183        str->append("</dd>");
2184    }
2185
2186    SkDrawLooper* looper = this->getLooper();
2187    if (looper) {
2188        str->append("<dt>DrawLooper:</dt><dd>");
2189        looper->toString(str);
2190        str->append("</dd>");
2191    }
2192
2193    SkImageFilter* imageFilter = this->getImageFilter();
2194    if (imageFilter) {
2195        str->append("<dt>ImageFilter:</dt><dd>");
2196        str->append("</dd>");
2197    }
2198
2199    SkAnnotation* annotation = this->getAnnotation();
2200    if (annotation) {
2201        str->append("<dt>Annotation:</dt><dd>");
2202        str->append("</dd>");
2203    }
2204
2205    str->append("<dt>Color:</dt><dd>0x");
2206    SkColor color = this->getColor();
2207    str->appendHex(color);
2208    str->append("</dd>");
2209
2210    str->append("<dt>Stroke Width:</dt><dd>");
2211    str->appendScalar(this->getStrokeWidth());
2212    str->append("</dd>");
2213
2214    str->append("<dt>Stroke Miter:</dt><dd>");
2215    str->appendScalar(this->getStrokeMiter());
2216    str->append("</dd>");
2217
2218    str->append("<dt>Flags:</dt><dd>(");
2219    if (this->getFlags()) {
2220        bool needSeparator = false;
2221        SkAddFlagToString(str, this->isAntiAlias(), "AntiAlias", &needSeparator);
2222        SkAddFlagToString(str, this->isDither(), "Dither", &needSeparator);
2223        SkAddFlagToString(str, this->isUnderlineText(), "UnderlineText", &needSeparator);
2224        SkAddFlagToString(str, this->isStrikeThruText(), "StrikeThruText", &needSeparator);
2225        SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator);
2226        SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator);
2227        SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator);
2228        SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator);
2229        SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator);
2230        SkAddFlagToString(str, this->isEmbeddedBitmapText(),
2231                          "EmbeddedBitmapText", &needSeparator);
2232        SkAddFlagToString(str, this->isAutohinted(), "Autohinted", &needSeparator);
2233        SkAddFlagToString(str, this->isVerticalText(), "VerticalText", &needSeparator);
2234        SkAddFlagToString(str, SkToBool(this->getFlags() & SkPaint::kGenA8FromLCD_Flag),
2235                          "GenA8FromLCD", &needSeparator);
2236    } else {
2237        str->append("None");
2238    }
2239    str->append(")</dd>");
2240
2241    str->append("<dt>FilterLevel:</dt><dd>");
2242    static const char* gFilterLevelStrings[] = { "None", "Low", "Medium", "High" };
2243    str->append(gFilterLevelStrings[this->getFilterLevel()]);
2244    str->append("</dd>");
2245
2246    str->append("<dt>TextAlign:</dt><dd>");
2247    static const char* gTextAlignStrings[SkPaint::kAlignCount] = { "Left", "Center", "Right" };
2248    str->append(gTextAlignStrings[this->getTextAlign()]);
2249    str->append("</dd>");
2250
2251    str->append("<dt>CapType:</dt><dd>");
2252    static const char* gStrokeCapStrings[SkPaint::kCapCount] = { "Butt", "Round", "Square" };
2253    str->append(gStrokeCapStrings[this->getStrokeCap()]);
2254    str->append("</dd>");
2255
2256    str->append("<dt>JoinType:</dt><dd>");
2257    static const char* gJoinStrings[SkPaint::kJoinCount] = { "Miter", "Round", "Bevel" };
2258    str->append(gJoinStrings[this->getStrokeJoin()]);
2259    str->append("</dd>");
2260
2261    str->append("<dt>Style:</dt><dd>");
2262    static const char* gStyleStrings[SkPaint::kStyleCount] = { "Fill", "Stroke", "StrokeAndFill" };
2263    str->append(gStyleStrings[this->getStyle()]);
2264    str->append("</dd>");
2265
2266    str->append("<dt>TextEncoding:</dt><dd>");
2267    static const char* gTextEncodingStrings[] = { "UTF8", "UTF16", "UTF32", "GlyphID" };
2268    str->append(gTextEncodingStrings[this->getTextEncoding()]);
2269    str->append("</dd>");
2270
2271    str->append("<dt>Hinting:</dt><dd>");
2272    static const char* gHintingStrings[] = { "None", "Slight", "Normal", "Full" };
2273    str->append(gHintingStrings[this->getHinting()]);
2274    str->append("</dd>");
2275
2276    str->append("</dd></dl></dl>");
2277}
2278#endif
2279
2280///////////////////////////////////////////////////////////////////////////////
2281
2282static bool has_thick_frame(const SkPaint& paint) {
2283    return  paint.getStrokeWidth() > 0 &&
2284            paint.getStyle() != SkPaint::kFill_Style;
2285}
2286
2287SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
2288                                    const SkPaint& paint,
2289                                    bool applyStrokeAndPathEffects)
2290                                    : fPaint(paint) {
2291    fGlyphCacheProc = paint.getMeasureCacheProc(true);
2292
2293    fPaint.setLinearText(true);
2294    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
2295
2296    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
2297        applyStrokeAndPathEffects = false;
2298    }
2299
2300    // can't use our canonical size if we need to apply patheffects
2301    if (fPaint.getPathEffect() == NULL) {
2302        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
2303        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
2304        if (has_thick_frame(fPaint)) {
2305            fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
2306        }
2307    } else {
2308        fScale = SK_Scalar1;
2309    }
2310
2311    if (!applyStrokeAndPathEffects) {
2312        fPaint.setStyle(SkPaint::kFill_Style);
2313        fPaint.setPathEffect(NULL);
2314    }
2315
2316    fCache = fPaint.detachCache(NULL, NULL, false);
2317
2318    SkPaint::Style  style = SkPaint::kFill_Style;
2319    SkPathEffect*   pe = NULL;
2320
2321    if (!applyStrokeAndPathEffects) {
2322        style = paint.getStyle();   // restore
2323        pe = paint.getPathEffect();     // restore
2324    }
2325    fPaint.setStyle(style);
2326    fPaint.setPathEffect(pe);
2327    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
2328
2329    // now compute fXOffset if needed
2330
2331    SkScalar xOffset = 0;
2332    if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first
2333        int      count;
2334        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length,
2335                                                         &count, NULL), fScale);
2336        if (paint.getTextAlign() == SkPaint::kCenter_Align) {
2337            width = SkScalarHalf(width);
2338        }
2339        xOffset = -width;
2340    }
2341    fXPos = xOffset;
2342    fPrevAdvance = 0;
2343
2344    fText = text;
2345    fStop = text + length;
2346
2347    fXYIndex = paint.isVerticalText() ? 1 : 0;
2348}
2349
2350SkTextToPathIter::~SkTextToPathIter() {
2351    SkGlyphCache::AttachCache(fCache);
2352}
2353
2354bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
2355    if (fText < fStop) {
2356        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
2357
2358        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
2359        fPrevAdvance = advance(glyph, fXYIndex);   // + fPaint.getTextTracking();
2360
2361        if (glyph.fWidth) {
2362            if (path) {
2363                *path = fCache->findPath(glyph);
2364            }
2365        } else {
2366            if (path) {
2367                *path = NULL;
2368            }
2369        }
2370        if (xpos) {
2371            *xpos = fXPos;
2372        }
2373        return true;
2374    }
2375    return false;
2376}
2377
2378///////////////////////////////////////////////////////////////////////////////
2379
2380// return true if the filter exists, and may affect alpha
2381static bool affects_alpha(const SkColorFilter* cf) {
2382    return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
2383}
2384
2385// return true if the filter exists, and may affect alpha
2386static bool affects_alpha(const SkImageFilter* imf) {
2387    // TODO: check if we should allow imagefilters to broadcast that they don't affect alpha
2388    // ala colorfilters
2389    return imf != NULL;
2390}
2391
2392bool SkPaint::nothingToDraw() const {
2393    if (fLooper) {
2394        return false;
2395    }
2396    SkXfermode::Mode mode;
2397    if (SkXfermode::AsMode(fXfermode, &mode)) {
2398        switch (mode) {
2399            case SkXfermode::kSrcOver_Mode:
2400            case SkXfermode::kSrcATop_Mode:
2401            case SkXfermode::kDstOut_Mode:
2402            case SkXfermode::kDstOver_Mode:
2403            case SkXfermode::kPlus_Mode:
2404                if (0 == this->getAlpha()) {
2405                    return !affects_alpha(fColorFilter) && !affects_alpha(fImageFilter);
2406                }
2407                break;
2408            case SkXfermode::kDst_Mode:
2409                return true;
2410            default:
2411                break;
2412        }
2413    }
2414    return false;
2415}
2416
2417uint32_t SkPaint::getHash() const {
2418    // We're going to hash 10 pointers and 7 32-bit values, finishing up with fBitfields,
2419    // so fBitfields should be 10 pointers and 6 32-bit values from the start.
2420    SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * sizeof(uint32_t),
2421                      SkPaint_notPackedTightly);
2422    return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this),
2423                               offsetof(SkPaint, fBitfields) + sizeof(fBitfields));
2424}
2425