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