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