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