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