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