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