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