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