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