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