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     if (paint.isFakeBoldText()) {
   1609 #ifdef SK_USE_FREETYPE_EMBOLDEN
   1610         flags |= SkScalerContext::kEmbolden_Flag;
   1611 #else
   1612         SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(),
   1613                                                     kStdFakeBoldInterpKeys,
   1614                                                     kStdFakeBoldInterpValues,
   1615                                                     kStdFakeBoldInterpLength);
   1616         SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
   1617 
   1618         if (style == SkPaint::kFill_Style) {
   1619             style = SkPaint::kStrokeAndFill_Style;
   1620             strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
   1621         } else {
   1622             strokeWidth += extra;
   1623         }
   1624 #endif
   1625     }
   1626 
   1627     if (paint.isDevKernText()) {
   1628         flags |= SkScalerContext::kDevKernText_Flag;
   1629     }
   1630 
   1631     if (style != SkPaint::kFill_Style && strokeWidth > 0) {
   1632         rec->fFrameWidth = strokeWidth;
   1633         rec->fMiterLimit = paint.getStrokeMiter();
   1634         rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
   1635 
   1636         if (style == SkPaint::kStrokeAndFill_Style) {
   1637             flags |= SkScalerContext::kFrameAndFill_Flag;
   1638         }
   1639     } else {
   1640         rec->fFrameWidth = 0;
   1641         rec->fMiterLimit = 0;
   1642         rec->fStrokeJoin = 0;
   1643     }
   1644 
   1645     rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
   1646 
   1647     SkDeviceProperties::Geometry geometry = deviceProperties
   1648                                           ? deviceProperties->fGeometry
   1649                                           : SkDeviceProperties::Geometry::MakeDefault();
   1650     if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) {
   1651         if (!geometry.isOrientationKnown() || !geometry.isLayoutKnown() || tooBigForLCD(*rec)) {
   1652             // eeek, can't support LCD
   1653             rec->fMaskFormat = SkMask::kA8_Format;
   1654         } else {
   1655             if (SkDeviceProperties::Geometry::kVertical_Orientation == geometry.getOrientation()) {
   1656                 flags |= SkScalerContext::kLCD_Vertical_Flag;
   1657             }
   1658             if (SkDeviceProperties::Geometry::kBGR_Layout == geometry.getLayout()) {
   1659                 flags |= SkScalerContext::kLCD_BGROrder_Flag;
   1660             }
   1661         }
   1662     }
   1663 
   1664     if (paint.isEmbeddedBitmapText()) {
   1665         flags |= SkScalerContext::kEmbeddedBitmapText_Flag;
   1666     }
   1667     if (paint.isSubpixelText()) {
   1668         flags |= SkScalerContext::kSubpixelPositioning_Flag;
   1669     }
   1670     if (paint.isAutohinted()) {
   1671         flags |= SkScalerContext::kForceAutohinting_Flag;
   1672     }
   1673     if (paint.isVerticalText()) {
   1674         flags |= SkScalerContext::kVertical_Flag;
   1675     }
   1676     if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
   1677         flags |= SkScalerContext::kGenA8FromLCD_Flag;
   1678     }
   1679     rec->fFlags = SkToU16(flags);
   1680 
   1681     // these modify fFlags, so do them after assigning fFlags
   1682     rec->setHinting(computeHinting(paint));
   1683 
   1684     rec->setLuminanceColor(computeLuminanceColor(paint));
   1685 
   1686     if (NULL == deviceProperties) {
   1687         rec->setDeviceGamma(SK_GAMMA_EXPONENT);
   1688         rec->setPaintGamma(SK_GAMMA_EXPONENT);
   1689     } else {
   1690         rec->setDeviceGamma(deviceProperties->fGamma);
   1691 
   1692         //For now always set the paint gamma equal to the device gamma.
   1693         //The math in SkMaskGamma can handle them being different,
   1694         //but it requires superluminous masks when
   1695         //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large.
   1696         rec->setPaintGamma(deviceProperties->fGamma);
   1697     }
   1698 
   1699 #ifdef SK_GAMMA_CONTRAST
   1700     rec->setContrast(SK_GAMMA_CONTRAST);
   1701 #else
   1702     /**
   1703      * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise.
   1704      * With lower values small text appears washed out (though correctly so).
   1705      * With higher values lcd fringing is worse and the smoothing effect of
   1706      * partial coverage is diminished.
   1707      */
   1708     rec->setContrast(0.5f);
   1709 #endif
   1710 
   1711     rec->fReservedAlign = 0;
   1712 
   1713     /*  Allow the fonthost to modify our rec before we use it as a key into the
   1714         cache. This way if we're asking for something that they will ignore,
   1715         they can modify our rec up front, so we don't create duplicate cache
   1716         entries.
   1717      */
   1718     typeface->onFilterRec(rec);
   1719 
   1720     // be sure to call PostMakeRec(rec) before you actually use it!
   1721 }
   1722 
   1723 /**
   1724  * In order to call cachedDeviceLuminance, cachedPaintLuminance, or
   1725  * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue
   1726  * to hold it until the returned pointer is refed or forgotten.
   1727  */
   1728 SK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex);
   1729 
   1730 static SkMaskGamma* gLinearMaskGamma = NULL;
   1731 static SkMaskGamma* gMaskGamma = NULL;
   1732 static SkScalar gContrast = SK_ScalarMin;
   1733 static SkScalar gPaintGamma = SK_ScalarMin;
   1734 static SkScalar gDeviceGamma = SK_ScalarMin;
   1735 /**
   1736  * The caller must hold the gMaskGammaCacheMutex and continue to hold it until
   1737  * the returned SkMaskGamma pointer is refed or forgotten.
   1738  */
   1739 static const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) {
   1740     gMaskGammaCacheMutex.assertHeld();
   1741     if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) {
   1742         if (NULL == gLinearMaskGamma) {
   1743             gLinearMaskGamma = SkNEW(SkMaskGamma);
   1744         }
   1745         return *gLinearMaskGamma;
   1746     }
   1747     if (gContrast != contrast || gPaintGamma != paintGamma || gDeviceGamma != deviceGamma) {
   1748         SkSafeUnref(gMaskGamma);
   1749         gMaskGamma = SkNEW_ARGS(SkMaskGamma, (contrast, paintGamma, deviceGamma));
   1750         gContrast = contrast;
   1751         gPaintGamma = paintGamma;
   1752         gDeviceGamma = deviceGamma;
   1753     }
   1754     return *gMaskGamma;
   1755 }
   1756 
   1757 /*static*/ void SkPaint::Term() {
   1758     SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
   1759 
   1760     SkSafeUnref(gLinearMaskGamma);
   1761     gLinearMaskGamma = NULL;
   1762     SkSafeUnref(gMaskGamma);
   1763     gMaskGamma = NULL;
   1764     SkDEBUGCODE(gContrast = SK_ScalarMin;)
   1765     SkDEBUGCODE(gPaintGamma = SK_ScalarMin;)
   1766     SkDEBUGCODE(gDeviceGamma = SK_ScalarMin;)
   1767 }
   1768 
   1769 /**
   1770  *  We ensure that the rec is self-consistent and efficient (where possible)
   1771  */
   1772 void SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) {
   1773     /**
   1774      *  If we're asking for A8, we force the colorlum to be gray, since that
   1775      *  limits the number of unique entries, and the scaler will only look at
   1776      *  the lum of one of them.
   1777      */
   1778     switch (rec->fMaskFormat) {
   1779         case SkMask::kLCD16_Format:
   1780         case SkMask::kLCD32_Format: {
   1781             // filter down the luminance color to a finite number of bits
   1782             SkColor color = rec->getLuminanceColor();
   1783             rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
   1784             break;
   1785         }
   1786         case SkMask::kA8_Format: {
   1787             // filter down the luminance to a single component, since A8 can't
   1788             // use per-component information
   1789 
   1790             SkColor color = rec->getLuminanceColor();
   1791             U8CPU lum = SkColorSpaceLuminance::computeLuminance(rec->getPaintGamma(), color);
   1792             //If we are asked to look like LCD, look like LCD.
   1793             if (!(rec->fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
   1794                 // HACK: Prevents green from being pre-blended as white.
   1795                 lum -= ((255 - lum) * lum) / 255;
   1796             }
   1797 
   1798             // reduce to our finite number of bits
   1799             color = SkColorSetRGB(lum, lum, lum);
   1800             rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color));
   1801             break;
   1802         }
   1803         case SkMask::kBW_Format:
   1804             // No need to differentiate gamma if we're BW
   1805             rec->ignorePreBlend();
   1806             break;
   1807     }
   1808 }
   1809 
   1810 #define MIN_SIZE_FOR_EFFECT_BUFFER  1024
   1811 
   1812 #ifdef SK_DEBUG
   1813     #define TEST_DESC
   1814 #endif
   1815 
   1816 /*
   1817  *  ignoreGamma tells us that the caller just wants metrics that are unaffected
   1818  *  by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1,
   1819  *  contrast = 0, luminanceColor = transparent black.
   1820  */
   1821 void SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties,
   1822                              const SkMatrix* deviceMatrix,
   1823                              void (*proc)(SkTypeface*, const SkDescriptor*, void*),
   1824                              void* context, bool ignoreGamma) const {
   1825     SkScalerContext::Rec    rec;
   1826 
   1827     SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec);
   1828     if (ignoreGamma) {
   1829         rec.ignorePreBlend();
   1830     }
   1831 
   1832     size_t          descSize = sizeof(rec);
   1833     int             entryCount = 1;
   1834     SkPathEffect*   pe = this->getPathEffect();
   1835     SkMaskFilter*   mf = this->getMaskFilter();
   1836     SkRasterizer*   ra = this->getRasterizer();
   1837 
   1838     SkWriteBuffer    peBuffer, mfBuffer, raBuffer;
   1839 
   1840     if (pe) {
   1841         peBuffer.writeFlattenable(pe);
   1842         descSize += peBuffer.bytesWritten();
   1843         entryCount += 1;
   1844         rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
   1845         // seems like we could support kLCD as well at this point...
   1846     }
   1847     if (mf) {
   1848         mfBuffer.writeFlattenable(mf);
   1849         descSize += mfBuffer.bytesWritten();
   1850         entryCount += 1;
   1851         rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
   1852         /* Pre-blend is not currently applied to filtered text.
   1853            The primary filter is blur, for which contrast makes no sense,
   1854            and for which the destination guess error is more visible.
   1855            Also, all existing users of blur have calibrated for linear. */
   1856         rec.ignorePreBlend();
   1857     }
   1858     if (ra) {
   1859         raBuffer.writeFlattenable(ra);
   1860         descSize += raBuffer.bytesWritten();
   1861         entryCount += 1;
   1862         rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
   1863     }
   1864 
   1865 #ifdef SK_BUILD_FOR_ANDROID
   1866     SkWriteBuffer androidBuffer;
   1867     fPaintOptionsAndroid.flatten(androidBuffer);
   1868     descSize += androidBuffer.bytesWritten();
   1869     entryCount += 1;
   1870 #endif
   1871 
   1872     ///////////////////////////////////////////////////////////////////////////
   1873     // Now that we're done tweaking the rec, call the PostMakeRec cleanup
   1874     SkScalerContext::PostMakeRec(*this, &rec);
   1875 
   1876     descSize += SkDescriptor::ComputeOverhead(entryCount);
   1877 
   1878     SkAutoDescriptor    ad(descSize);
   1879     SkDescriptor*       desc = ad.getDesc();
   1880 
   1881     desc->init();
   1882     desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
   1883 
   1884 #ifdef SK_BUILD_FOR_ANDROID
   1885     add_flattenable(desc, kAndroidOpts_SkDescriptorTag, &androidBuffer);
   1886 #endif
   1887 
   1888     if (pe) {
   1889         add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
   1890     }
   1891     if (mf) {
   1892         add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
   1893     }
   1894     if (ra) {
   1895         add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
   1896     }
   1897 
   1898     SkASSERT(descSize == desc->getLength());
   1899     desc->computeChecksum();
   1900 
   1901 #ifdef TEST_DESC
   1902     {
   1903         // Check that we completely write the bytes in desc (our key), and that
   1904         // there are no uninitialized bytes. If there were, then we would get
   1905         // false-misses (or worse, false-hits) in our fontcache.
   1906         //
   1907         // We do this buy filling 2 others, one with 0s and the other with 1s
   1908         // and create those, and then check that all 3 are identical.
   1909         SkAutoDescriptor    ad1(descSize);
   1910         SkAutoDescriptor    ad2(descSize);
   1911         SkDescriptor*       desc1 = ad1.getDesc();
   1912         SkDescriptor*       desc2 = ad2.getDesc();
   1913 
   1914         memset(desc1, 0x00, descSize);
   1915         memset(desc2, 0xFF, descSize);
   1916 
   1917         desc1->init();
   1918         desc2->init();
   1919         desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
   1920         desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
   1921 
   1922 #ifdef SK_BUILD_FOR_ANDROID
   1923         add_flattenable(desc1, kAndroidOpts_SkDescriptorTag, &androidBuffer);
   1924         add_flattenable(desc2, kAndroidOpts_SkDescriptorTag, &androidBuffer);
   1925 #endif
   1926 
   1927         if (pe) {
   1928             add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer);
   1929             add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer);
   1930         }
   1931         if (mf) {
   1932             add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer);
   1933             add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer);
   1934         }
   1935         if (ra) {
   1936             add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer);
   1937             add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer);
   1938         }
   1939 
   1940         SkASSERT(descSize == desc1->getLength());
   1941         SkASSERT(descSize == desc2->getLength());
   1942         desc1->computeChecksum();
   1943         desc2->computeChecksum();
   1944         SkASSERT(!memcmp(desc, desc1, descSize));
   1945         SkASSERT(!memcmp(desc, desc2, descSize));
   1946     }
   1947 #endif
   1948 
   1949     proc(fTypeface, desc, context);
   1950 }
   1951 
   1952 SkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties,
   1953                                    const SkMatrix* deviceMatrix,
   1954                                    bool ignoreGamma) const {
   1955     SkGlyphCache* cache;
   1956     this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma);
   1957     return cache;
   1958 }
   1959 
   1960 /**
   1961  * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend.
   1962  */
   1963 //static
   1964 SkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Rec& rec) {
   1965     SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
   1966     const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(),
   1967                                                    rec.getPaintGamma(),
   1968                                                    rec.getDeviceGamma());
   1969     return maskGamma.preBlend(rec.getLuminanceColor());
   1970 }
   1971 
   1972 size_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma,
   1973                                         SkScalar deviceGamma, int* width, int* height) {
   1974     SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
   1975     const SkMaskGamma& maskGamma = cachedMaskGamma(contrast,
   1976                                                    paintGamma,
   1977                                                    deviceGamma);
   1978 
   1979     maskGamma.getGammaTableDimensions(width, height);
   1980     size_t size = (*width)*(*height)*sizeof(uint8_t);
   1981 
   1982     return size;
   1983 }
   1984 
   1985 void SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma,
   1986                                       void* data) {
   1987     SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
   1988     const SkMaskGamma& maskGamma = cachedMaskGamma(contrast,
   1989                                                    paintGamma,
   1990                                                    deviceGamma);
   1991     int width, height;
   1992     maskGamma.getGammaTableDimensions(&width, &height);
   1993     size_t size = width*height*sizeof(uint8_t);
   1994     const uint8_t* gammaTables = maskGamma.getGammaTables();
   1995     memcpy(data, gammaTables, size);
   1996 }
   1997 
   1998 
   1999 ///////////////////////////////////////////////////////////////////////////////
   2000 
   2001 #include "SkStream.h"
   2002 
   2003 static uintptr_t asint(const void* p) {
   2004     return reinterpret_cast<uintptr_t>(p);
   2005 }
   2006 
   2007 union Scalar32 {
   2008     SkScalar    fScalar;
   2009     uint32_t    f32;
   2010 };
   2011 
   2012 static uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
   2013     SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
   2014     Scalar32 tmp;
   2015     tmp.fScalar = value;
   2016     *ptr = tmp.f32;
   2017     return ptr + 1;
   2018 }
   2019 
   2020 static SkScalar read_scalar(const uint32_t*& ptr) {
   2021     SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
   2022     Scalar32 tmp;
   2023     tmp.f32 = *ptr++;
   2024     return tmp.fScalar;
   2025 }
   2026 
   2027 static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
   2028     SkASSERT(a == (uint8_t)a);
   2029     SkASSERT(b == (uint8_t)b);
   2030     SkASSERT(c == (uint8_t)c);
   2031     SkASSERT(d == (uint8_t)d);
   2032     return (a << 24) | (b << 16) | (c << 8) | d;
   2033 }
   2034 
   2035 #ifdef SK_DEBUG
   2036     static void ASSERT_FITS_IN(uint32_t value, int bitCount) {
   2037         SkASSERT(bitCount > 0 && bitCount <= 32);
   2038         uint32_t mask = ~0U;
   2039         mask >>= (32 - bitCount);
   2040         SkASSERT(0 == (value & ~mask));
   2041     }
   2042 #else
   2043     #define ASSERT_FITS_IN(value, bitcount)
   2044 #endif
   2045 
   2046 enum FlatFlags {
   2047     kHasTypeface_FlatFlag                      = 0x01,
   2048     kHasEffects_FlatFlag                       = 0x02,
   2049     kHasNonDefaultPaintOptionsAndroid_FlatFlag = 0x04,
   2050 
   2051     kFlatFlagMask = 0x7,
   2052 };
   2053 
   2054 enum BitsPerField {
   2055     kFlags_BPF  = 16,
   2056     kHint_BPF   = 2,
   2057     kAlign_BPF  = 2,
   2058     kFilter_BPF = 2,
   2059     kFlatFlags_BPF  = 3,
   2060 };
   2061 
   2062 static inline int BPF_Mask(int bits) {
   2063     return (1 << bits) - 1;
   2064 }
   2065 
   2066 static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align,
   2067                                  unsigned filter, unsigned flatFlags) {
   2068     ASSERT_FITS_IN(flags, kFlags_BPF);
   2069     ASSERT_FITS_IN(hint, kHint_BPF);
   2070     ASSERT_FITS_IN(align, kAlign_BPF);
   2071     ASSERT_FITS_IN(filter, kFilter_BPF);
   2072     ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF);
   2073 
   2074     // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly
   2075     // add more bits in the future.
   2076     return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags;
   2077 }
   2078 
   2079 static FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) {
   2080     paint->setFlags(packed >> 16);
   2081     paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF)));
   2082     paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF)));
   2083     paint->setFilterLevel((SkPaint::FilterLevel)((packed >> 10) & BPF_Mask(kFilter_BPF)));
   2084     return (FlatFlags)(packed & kFlatFlagMask);
   2085 }
   2086 
   2087 // V22_COMPATIBILITY_CODE
   2088 static FlatFlags unpack_paint_flags_v22(SkPaint* paint, uint32_t packed) {
   2089     enum {
   2090         kFilterBitmap_Flag    = 0x02,
   2091         kHighQualityFilterBitmap_Flag = 0x4000,
   2092 
   2093         kAll_Flags = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag
   2094     };
   2095 
   2096     // previously flags:16, textAlign:8, flatFlags:8
   2097     // now flags:16, hinting:4, textAlign:4, flatFlags:8
   2098     unsigned flags = packed >> 16;
   2099     int filter = 0;
   2100     if (flags & kFilterBitmap_Flag) {
   2101         filter |= 1;
   2102     }
   2103     if (flags & kHighQualityFilterBitmap_Flag) {
   2104         filter |= 2;
   2105     }
   2106     paint->setFilterLevel((SkPaint::FilterLevel)filter);
   2107     flags &= ~kAll_Flags;   // remove these (now dead) bit flags
   2108 
   2109     paint->setFlags(flags);
   2110 
   2111     // hinting added later. 0 in this nibble means use the default.
   2112     uint32_t hinting = (packed >> 12) & 0xF;
   2113     paint->setHinting(0 == hinting ? SkPaint::kNormal_Hinting : static_cast<SkPaint::Hinting>(hinting-1));
   2114     paint->setTextAlign(static_cast<SkPaint::Align>((packed >> 8) & 0xF));
   2115     return (FlatFlags)(packed & kFlatFlagMask);
   2116 }
   2117 
   2118 // The size of a flat paint's POD fields
   2119 static const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
   2120                                         1 * sizeof(SkColor) +
   2121                                         1 * sizeof(uint16_t) +
   2122                                         6 * sizeof(uint8_t);
   2123 
   2124 /*  To save space/time, we analyze the paint, and write a truncated version of
   2125     it if there are not tricky elements like shaders, etc.
   2126  */
   2127 void SkPaint::flatten(SkWriteBuffer& buffer) const {
   2128     uint8_t flatFlags = 0;
   2129     if (this->getTypeface()) {
   2130         flatFlags |= kHasTypeface_FlatFlag;
   2131     }
   2132     if (asint(this->getPathEffect()) |
   2133         asint(this->getShader()) |
   2134         asint(this->getXfermode()) |
   2135         asint(this->getMaskFilter()) |
   2136         asint(this->getColorFilter()) |
   2137         asint(this->getRasterizer()) |
   2138         asint(this->getLooper()) |
   2139         asint(this->getAnnotation()) |
   2140         asint(this->getImageFilter())) {
   2141         flatFlags |= kHasEffects_FlatFlag;
   2142     }
   2143 #ifdef SK_BUILD_FOR_ANDROID
   2144     if (this->getPaintOptionsAndroid() != SkPaintOptionsAndroid()) {
   2145         flatFlags |= kHasNonDefaultPaintOptionsAndroid_FlatFlag;
   2146     }
   2147 #endif
   2148 
   2149     SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
   2150     uint32_t* ptr = buffer.reserve(kPODPaintSize);
   2151 
   2152     ptr = write_scalar(ptr, this->getTextSize());
   2153     ptr = write_scalar(ptr, this->getTextScaleX());
   2154     ptr = write_scalar(ptr, this->getTextSkewX());
   2155     ptr = write_scalar(ptr, this->getStrokeWidth());
   2156     ptr = write_scalar(ptr, this->getStrokeMiter());
   2157     *ptr++ = this->getColor();
   2158 
   2159     *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(),
   2160                               this->getFilterLevel(), flatFlags);
   2161     *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
   2162                     this->getStyle(), this->getTextEncoding());
   2163 
   2164     // now we're done with ptr and the (pre)reserved space. If we need to write
   2165     // additional fields, use the buffer directly
   2166     if (flatFlags & kHasTypeface_FlatFlag) {
   2167         buffer.writeTypeface(this->getTypeface());
   2168     }
   2169     if (flatFlags & kHasEffects_FlatFlag) {
   2170         buffer.writeFlattenable(this->getPathEffect());
   2171         buffer.writeFlattenable(this->getShader());
   2172         buffer.writeFlattenable(this->getXfermode());
   2173         buffer.writeFlattenable(this->getMaskFilter());
   2174         buffer.writeFlattenable(this->getColorFilter());
   2175         buffer.writeFlattenable(this->getRasterizer());
   2176         buffer.writeFlattenable(this->getLooper());
   2177         buffer.writeFlattenable(this->getImageFilter());
   2178 
   2179         if (fAnnotation) {
   2180             buffer.writeBool(true);
   2181             fAnnotation->writeToBuffer(buffer);
   2182         } else {
   2183             buffer.writeBool(false);
   2184         }
   2185     }
   2186 #ifdef SK_BUILD_FOR_ANDROID
   2187     if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
   2188         this->getPaintOptionsAndroid().flatten(buffer);
   2189     }
   2190 #endif
   2191 }
   2192 
   2193 void SkPaint::unflatten(SkReadBuffer& buffer) {
   2194     SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
   2195     const void* podData = buffer.skip(kPODPaintSize);
   2196     const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
   2197 
   2198     // the order we read must match the order we wrote in flatten()
   2199     this->setTextSize(read_scalar(pod));
   2200     this->setTextScaleX(read_scalar(pod));
   2201     this->setTextSkewX(read_scalar(pod));
   2202     this->setStrokeWidth(read_scalar(pod));
   2203     this->setStrokeMiter(read_scalar(pod));
   2204     this->setColor(*pod++);
   2205 
   2206     unsigned flatFlags = 0;
   2207     if (buffer.isVersionLT(SkReadBuffer::kFilterLevelIsEnum_Version)) {
   2208         flatFlags = unpack_paint_flags_v22(this, *pod++);
   2209     } else {
   2210         flatFlags = unpack_paint_flags(this, *pod++);
   2211     }
   2212 
   2213     uint32_t tmp = *pod++;
   2214     this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
   2215     this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
   2216     this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
   2217     this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
   2218 
   2219     if (flatFlags & kHasTypeface_FlatFlag) {
   2220         this->setTypeface(buffer.readTypeface());
   2221     } else {
   2222         this->setTypeface(NULL);
   2223     }
   2224 
   2225     if (flatFlags & kHasEffects_FlatFlag) {
   2226         SkSafeUnref(this->setPathEffect(buffer.readPathEffect()));
   2227         SkSafeUnref(this->setShader(buffer.readShader()));
   2228         SkSafeUnref(this->setXfermode(buffer.readXfermode()));
   2229         SkSafeUnref(this->setMaskFilter(buffer.readMaskFilter()));
   2230         SkSafeUnref(this->setColorFilter(buffer.readColorFilter()));
   2231         SkSafeUnref(this->setRasterizer(buffer.readRasterizer()));
   2232         SkSafeUnref(this->setLooper(buffer.readDrawLooper()));
   2233         SkSafeUnref(this->setImageFilter(buffer.readImageFilter()));
   2234 
   2235         if (buffer.readBool()) {
   2236             this->setAnnotation(SkAnnotation::Create(buffer))->unref();
   2237         }
   2238     } else {
   2239         this->setPathEffect(NULL);
   2240         this->setShader(NULL);
   2241         this->setXfermode(NULL);
   2242         this->setMaskFilter(NULL);
   2243         this->setColorFilter(NULL);
   2244         this->setRasterizer(NULL);
   2245         this->setLooper(NULL);
   2246         this->setImageFilter(NULL);
   2247     }
   2248 
   2249 #ifdef SK_BUILD_FOR_ANDROID
   2250     this->setPaintOptionsAndroid(SkPaintOptionsAndroid());
   2251 #endif
   2252     if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) {
   2253         SkPaintOptionsAndroid options;
   2254         options.unflatten(buffer);
   2255 #ifdef SK_BUILD_FOR_ANDROID
   2256         this->setPaintOptionsAndroid(options);
   2257 #endif
   2258     }
   2259 }
   2260 
   2261 ///////////////////////////////////////////////////////////////////////////////
   2262 
   2263 SkShader* SkPaint::setShader(SkShader* shader) {
   2264     GEN_ID_INC_EVAL(shader != fShader);
   2265     SkRefCnt_SafeAssign(fShader, shader);
   2266     fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL);
   2267     return shader;
   2268 }
   2269 
   2270 SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
   2271     GEN_ID_INC_EVAL(filter != fColorFilter);
   2272     SkRefCnt_SafeAssign(fColorFilter, filter);
   2273     fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL);
   2274     return filter;
   2275 }
   2276 
   2277 SkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
   2278     GEN_ID_INC_EVAL(mode != fXfermode);
   2279     SkRefCnt_SafeAssign(fXfermode, mode);
   2280     fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL);
   2281     return mode;
   2282 }
   2283 
   2284 SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
   2285     SkSafeUnref(fXfermode);
   2286     fXfermode = SkXfermode::Create(mode);
   2287     GEN_ID_INC;
   2288     fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL);
   2289     return fXfermode;
   2290 }
   2291 
   2292 SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
   2293     GEN_ID_INC_EVAL(effect != fPathEffect);
   2294     SkRefCnt_SafeAssign(fPathEffect, effect);
   2295     fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL);
   2296     return effect;
   2297 }
   2298 
   2299 SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
   2300     GEN_ID_INC_EVAL(filter != fMaskFilter);
   2301     SkRefCnt_SafeAssign(fMaskFilter, filter);
   2302     fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL);
   2303     return filter;
   2304 }
   2305 
   2306 ///////////////////////////////////////////////////////////////////////////////
   2307 
   2308 bool SkPaint::getFillPath(const SkPath& src, SkPath* dst,
   2309                           const SkRect* cullRect) const {
   2310     SkStrokeRec rec(*this);
   2311 
   2312     const SkPath* srcPtr = &src;
   2313     SkPath tmpPath;
   2314 
   2315     if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) {
   2316         srcPtr = &tmpPath;
   2317     }
   2318 
   2319     if (!rec.applyToPath(dst, *srcPtr)) {
   2320         if (srcPtr == &tmpPath) {
   2321             // If path's were copy-on-write, this trick would not be needed.
   2322             // As it is, we want to save making a deep-copy from tmpPath -> dst
   2323             // since we know we're just going to delete tmpPath when we return,
   2324             // so the swap saves that copy.
   2325             dst->swap(tmpPath);
   2326         } else {
   2327             *dst = *srcPtr;
   2328         }
   2329     }
   2330     return !rec.isHairlineStyle();
   2331 }
   2332 
   2333 const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc,
   2334                                            SkRect* storage,
   2335                                            Style style) const {
   2336     SkASSERT(storage);
   2337 
   2338     const SkRect* src = &origSrc;
   2339 
   2340     if (this->getLooper()) {
   2341         SkASSERT(this->getLooper()->canComputeFastBounds(*this));
   2342         this->getLooper()->computeFastBounds(*this, *src, storage);
   2343         return *storage;
   2344     }
   2345 
   2346     SkRect tmpSrc;
   2347     if (this->getPathEffect()) {
   2348         this->getPathEffect()->computeFastBounds(&tmpSrc, origSrc);
   2349         src = &tmpSrc;
   2350     }
   2351 
   2352     if (kFill_Style != style) {
   2353         // since we're stroked, outset the rect by the radius (and join type)
   2354         SkScalar radius = SkScalarHalf(this->getStrokeWidth());
   2355         if (0 == radius) {  // hairline
   2356             radius = SK_Scalar1;
   2357         } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
   2358             SkScalar scale = this->getStrokeMiter();
   2359             if (scale > SK_Scalar1) {
   2360                 radius = SkScalarMul(radius, scale);
   2361             }
   2362         }
   2363         storage->set(src->fLeft - radius, src->fTop - radius,
   2364                      src->fRight + radius, src->fBottom + radius);
   2365     } else {
   2366         *storage = *src;
   2367     }
   2368 
   2369     if (this->getMaskFilter()) {
   2370         this->getMaskFilter()->computeFastBounds(*storage, storage);
   2371     }
   2372 
   2373     if (this->getImageFilter()) {
   2374         this->getImageFilter()->computeFastBounds(*storage, storage);
   2375     }
   2376 
   2377     return *storage;
   2378 }
   2379 
   2380 #ifndef SK_IGNORE_TO_STRING
   2381 void SkPaint::toString(SkString* str) const {
   2382     str->append("<dl><dt>SkPaint:</dt><dd><dl>");
   2383 
   2384     SkTypeface* typeface = this->getTypeface();
   2385     if (NULL != typeface) {
   2386         SkDynamicMemoryWStream ostream;
   2387         typeface->serialize(&ostream);
   2388         SkAutoTUnref<SkData> data(ostream.copyToData());
   2389 
   2390         SkMemoryStream stream(data);
   2391         SkFontDescriptor descriptor(&stream);
   2392 
   2393         str->append("<dt>Font Family Name:</dt><dd>");
   2394         str->append(descriptor.getFamilyName());
   2395         str->append("</dd><dt>Font Full Name:</dt><dd>");
   2396         str->append(descriptor.getFullName());
   2397         str->append("</dd><dt>Font PS Name:</dt><dd>");
   2398         str->append(descriptor.getPostscriptName());
   2399         str->append("</dd><dt>Font File Name:</dt><dd>");
   2400         str->append(descriptor.getFontFileName());
   2401         str->append("</dd>");
   2402     }
   2403 
   2404     str->append("<dt>TextSize:</dt><dd>");
   2405     str->appendScalar(this->getTextSize());
   2406     str->append("</dd>");
   2407 
   2408     str->append("<dt>TextScaleX:</dt><dd>");
   2409     str->appendScalar(this->getTextScaleX());
   2410     str->append("</dd>");
   2411 
   2412     str->append("<dt>TextSkewX:</dt><dd>");
   2413     str->appendScalar(this->getTextSkewX());
   2414     str->append("</dd>");
   2415 
   2416     SkPathEffect* pathEffect = this->getPathEffect();
   2417     if (NULL != pathEffect) {
   2418         str->append("<dt>PathEffect:</dt><dd>");
   2419         str->append("</dd>");
   2420     }
   2421 
   2422     SkShader* shader = this->getShader();
   2423     if (NULL != shader) {
   2424         str->append("<dt>Shader:</dt><dd>");
   2425         shader->toString(str);
   2426         str->append("</dd>");
   2427     }
   2428 
   2429     SkXfermode* xfer = this->getXfermode();
   2430     if (NULL != xfer) {
   2431         str->append("<dt>Xfermode:</dt><dd>");
   2432         xfer->toString(str);
   2433         str->append("</dd>");
   2434     }
   2435 
   2436     SkMaskFilter* maskFilter = this->getMaskFilter();
   2437     if (NULL != maskFilter) {
   2438         str->append("<dt>MaskFilter:</dt><dd>");
   2439         maskFilter->toString(str);
   2440         str->append("</dd>");
   2441     }
   2442 
   2443     SkColorFilter* colorFilter = this->getColorFilter();
   2444     if (NULL != colorFilter) {
   2445         str->append("<dt>ColorFilter:</dt><dd>");
   2446         colorFilter->toString(str);
   2447         str->append("</dd>");
   2448     }
   2449 
   2450     SkRasterizer* rasterizer = this->getRasterizer();
   2451     if (NULL != rasterizer) {
   2452         str->append("<dt>Rasterizer:</dt><dd>");
   2453         str->append("</dd>");
   2454     }
   2455 
   2456     SkDrawLooper* looper = this->getLooper();
   2457     if (NULL != looper) {
   2458         str->append("<dt>DrawLooper:</dt><dd>");
   2459         looper->toString(str);
   2460         str->append("</dd>");
   2461     }
   2462 
   2463     SkImageFilter* imageFilter = this->getImageFilter();
   2464     if (NULL != imageFilter) {
   2465         str->append("<dt>ImageFilter:</dt><dd>");
   2466         str->append("</dd>");
   2467     }
   2468 
   2469     SkAnnotation* annotation = this->getAnnotation();
   2470     if (NULL != annotation) {
   2471         str->append("<dt>Annotation:</dt><dd>");
   2472         str->append("</dd>");
   2473     }
   2474 
   2475     str->append("<dt>Color:</dt><dd>0x");
   2476     SkColor color = this->getColor();
   2477     str->appendHex(color);
   2478     str->append("</dd>");
   2479 
   2480     str->append("<dt>Stroke Width:</dt><dd>");
   2481     str->appendScalar(this->getStrokeWidth());
   2482     str->append("</dd>");
   2483 
   2484     str->append("<dt>Stroke Miter:</dt><dd>");
   2485     str->appendScalar(this->getStrokeMiter());
   2486     str->append("</dd>");
   2487 
   2488     str->append("<dt>Flags:</dt><dd>(");
   2489     if (this->getFlags()) {
   2490         bool needSeparator = false;
   2491         SkAddFlagToString(str, this->isAntiAlias(), "AntiAlias", &needSeparator);
   2492         SkAddFlagToString(str, this->isDither(), "Dither", &needSeparator);
   2493         SkAddFlagToString(str, this->isUnderlineText(), "UnderlineText", &needSeparator);
   2494         SkAddFlagToString(str, this->isStrikeThruText(), "StrikeThruText", &needSeparator);
   2495         SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator);
   2496         SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator);
   2497         SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator);
   2498         SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator);
   2499         SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator);
   2500         SkAddFlagToString(str, this->isEmbeddedBitmapText(),
   2501                           "EmbeddedBitmapText", &needSeparator);
   2502         SkAddFlagToString(str, this->isAutohinted(), "Autohinted", &needSeparator);
   2503         SkAddFlagToString(str, this->isVerticalText(), "VerticalText", &needSeparator);
   2504         SkAddFlagToString(str, SkToBool(this->getFlags() & SkPaint::kGenA8FromLCD_Flag),
   2505                           "GenA8FromLCD", &needSeparator);
   2506     } else {
   2507         str->append("None");
   2508     }
   2509     str->append(")</dd>");
   2510 
   2511     str->append("<dt>FilterLevel:</dt><dd>");
   2512     static const char* gFilterLevelStrings[] = { "None", "Low", "Medium", "High" };
   2513     str->append(gFilterLevelStrings[this->getFilterLevel()]);
   2514     str->append("</dd>");
   2515 
   2516     str->append("<dt>TextAlign:</dt><dd>");
   2517     static const char* gTextAlignStrings[SkPaint::kAlignCount] = { "Left", "Center", "Right" };
   2518     str->append(gTextAlignStrings[this->getTextAlign()]);
   2519     str->append("</dd>");
   2520 
   2521     str->append("<dt>CapType:</dt><dd>");
   2522     static const char* gStrokeCapStrings[SkPaint::kCapCount] = { "Butt", "Round", "Square" };
   2523     str->append(gStrokeCapStrings[this->getStrokeCap()]);
   2524     str->append("</dd>");
   2525 
   2526     str->append("<dt>JoinType:</dt><dd>");
   2527     static const char* gJoinStrings[SkPaint::kJoinCount] = { "Miter", "Round", "Bevel" };
   2528     str->append(gJoinStrings[this->getStrokeJoin()]);
   2529     str->append("</dd>");
   2530 
   2531     str->append("<dt>Style:</dt><dd>");
   2532     static const char* gStyleStrings[SkPaint::kStyleCount] = { "Fill", "Stroke", "StrokeAndFill" };
   2533     str->append(gStyleStrings[this->getStyle()]);
   2534     str->append("</dd>");
   2535 
   2536     str->append("<dt>TextEncoding:</dt><dd>");
   2537     static const char* gTextEncodingStrings[] = { "UTF8", "UTF16", "UTF32", "GlyphID" };
   2538     str->append(gTextEncodingStrings[this->getTextEncoding()]);
   2539     str->append("</dd>");
   2540 
   2541     str->append("<dt>Hinting:</dt><dd>");
   2542     static const char* gHintingStrings[] = { "None", "Slight", "Normal", "Full" };
   2543     str->append(gHintingStrings[this->getHinting()]);
   2544     str->append("</dd>");
   2545 
   2546     str->append("</dd></dl></dl>");
   2547 }
   2548 #endif
   2549 
   2550 ///////////////////////////////////////////////////////////////////////////////
   2551 
   2552 static bool has_thick_frame(const SkPaint& paint) {
   2553     return  paint.getStrokeWidth() > 0 &&
   2554             paint.getStyle() != SkPaint::kFill_Style;
   2555 }
   2556 
   2557 SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
   2558                                     const SkPaint& paint,
   2559                                     bool applyStrokeAndPathEffects)
   2560                                     : fPaint(paint) {
   2561     fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
   2562                                                 true);
   2563 
   2564     fPaint.setLinearText(true);
   2565     fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
   2566 
   2567     if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
   2568         applyStrokeAndPathEffects = false;
   2569     }
   2570 
   2571     // can't use our canonical size if we need to apply patheffects
   2572     if (fPaint.getPathEffect() == NULL) {
   2573         fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
   2574         fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
   2575         if (has_thick_frame(fPaint)) {
   2576             fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
   2577         }
   2578     } else {
   2579         fScale = SK_Scalar1;
   2580     }
   2581 
   2582     if (!applyStrokeAndPathEffects) {
   2583         fPaint.setStyle(SkPaint::kFill_Style);
   2584         fPaint.setPathEffect(NULL);
   2585     }
   2586 
   2587     fCache = fPaint.detachCache(NULL, NULL, false);
   2588 
   2589     SkPaint::Style  style = SkPaint::kFill_Style;
   2590     SkPathEffect*   pe = NULL;
   2591 
   2592     if (!applyStrokeAndPathEffects) {
   2593         style = paint.getStyle();   // restore
   2594         pe = paint.getPathEffect();     // restore
   2595     }
   2596     fPaint.setStyle(style);
   2597     fPaint.setPathEffect(pe);
   2598     fPaint.setMaskFilter(paint.getMaskFilter());    // restore
   2599 
   2600     // now compute fXOffset if needed
   2601 
   2602     SkScalar xOffset = 0;
   2603     if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first
   2604         int      count;
   2605         SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length,
   2606                                                          &count, NULL), fScale);
   2607         if (paint.getTextAlign() == SkPaint::kCenter_Align) {
   2608             width = SkScalarHalf(width);
   2609         }
   2610         xOffset = -width;
   2611     }
   2612     fXPos = xOffset;
   2613     fPrevAdvance = 0;
   2614 
   2615     fText = text;
   2616     fStop = text + length;
   2617 
   2618     fXYIndex = paint.isVerticalText() ? 1 : 0;
   2619 }
   2620 
   2621 SkTextToPathIter::~SkTextToPathIter() {
   2622     SkGlyphCache::AttachCache(fCache);
   2623 }
   2624 
   2625 bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
   2626     if (fText < fStop) {
   2627         const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
   2628 
   2629         fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
   2630         fPrevAdvance = advance(glyph, fXYIndex);   // + fPaint.getTextTracking();
   2631 
   2632         if (glyph.fWidth) {
   2633             if (path) {
   2634                 *path = fCache->findPath(glyph);
   2635             }
   2636         } else {
   2637             if (path) {
   2638                 *path = NULL;
   2639             }
   2640         }
   2641         if (xpos) {
   2642             *xpos = fXPos;
   2643         }
   2644         return true;
   2645     }
   2646     return false;
   2647 }
   2648 
   2649 ///////////////////////////////////////////////////////////////////////////////
   2650 
   2651 bool SkPaint::nothingToDraw() const {
   2652     if (fLooper) {
   2653         return false;
   2654     }
   2655     SkXfermode::Mode mode;
   2656     if (SkXfermode::AsMode(fXfermode, &mode)) {
   2657         switch (mode) {
   2658             case SkXfermode::kSrcOver_Mode:
   2659             case SkXfermode::kSrcATop_Mode:
   2660             case SkXfermode::kDstOut_Mode:
   2661             case SkXfermode::kDstOver_Mode:
   2662             case SkXfermode::kPlus_Mode:
   2663                 return 0 == this->getAlpha();
   2664             case SkXfermode::kDst_Mode:
   2665                 return true;
   2666             default:
   2667                 break;
   2668         }
   2669     }
   2670     return false;
   2671 }
   2672 
   2673 void SkPaint::setBitfields(uint32_t bitfields) {
   2674     fBitfields = bitfields;
   2675 }
   2676 
   2677 inline static unsigned popcount(uint8_t x) {
   2678     // As in Hacker's delight, adapted for just 8 bits.
   2679     x = (x & 0x55) + ((x >> 1) & 0x55);  // a b c d w x y z -> a+b c+d w+x y+z
   2680     x = (x & 0x33) + ((x >> 2) & 0x33);  // a+b c+d w+x y+z -> a+b+c+d w+x+y+z
   2681     x = (x & 0x0F) + ((x >> 4) & 0x0F);  // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z
   2682     return x;
   2683 }
   2684 
   2685 void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& paint) {
   2686     const uint32_t dirty = paint.fDirtyBits;
   2687 
   2688     // Each of the low 7 dirty bits corresponds to a 4-byte flat value,
   2689     // plus one for the dirty bits and one for the bitfields
   2690     const size_t flatBytes = 4 * (popcount(dirty & kPOD_DirtyBitMask) + 2);
   2691     SkASSERT(flatBytes <= 32);
   2692     uint32_t* u32 = buffer.reserve(flatBytes);
   2693     *u32++ = dirty;
   2694     *u32++ = paint.getBitfields();
   2695     if (0 == dirty) {
   2696         return;
   2697     }
   2698 
   2699 #define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field()
   2700     F(u32, Color);
   2701     SkScalar* f32 = reinterpret_cast<SkScalar*>(u32);
   2702     F(f32, TextSize);
   2703     F(f32, TextScaleX);
   2704     F(f32, TextSkewX);
   2705     F(f32, StrokeWidth);
   2706     F(f32, StrokeMiter);
   2707 #undef F
   2708 #define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.get##field())
   2709     F(PathEffect);
   2710     F(Shader);
   2711     F(Xfermode);
   2712     F(MaskFilter);
   2713     F(ColorFilter);
   2714     F(Rasterizer);
   2715     F(Looper);
   2716     F(ImageFilter);
   2717 #undef F
   2718     if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface());
   2719     if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffer);
   2720 #ifdef SK_BUILD_FOR_ANDROID
   2721     if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().flatten(buffer);
   2722 #endif
   2723 }
   2724 
   2725 void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) {
   2726     const uint32_t dirty = buffer.readUInt();
   2727     paint->setBitfields(buffer.readUInt());
   2728     if (dirty == 0) {
   2729         return;
   2730     }
   2731 #define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buffer.reader())
   2732 // Same function, except it unrefs the object newly set on the paint:
   2733 #define F_UNREF(field, reader)                      \
   2734     if (dirty & k##field##_DirtyBit)                \
   2735         paint->set##field(buffer.reader())->unref()
   2736 
   2737     F(Color,       readUInt);
   2738     F(TextSize,    readScalar);
   2739     F(TextScaleX,  readScalar);
   2740     F(TextSkewX,   readScalar);
   2741     F(StrokeWidth, readScalar);
   2742     F(StrokeMiter, readScalar);
   2743     F_UNREF(PathEffect,  readPathEffect);
   2744     F_UNREF(Shader,      readShader);
   2745     F_UNREF(Xfermode,    readXfermode);
   2746     F_UNREF(MaskFilter,  readMaskFilter);
   2747     F_UNREF(ColorFilter, readColorFilter);
   2748     F_UNREF(Rasterizer,  readRasterizer);
   2749     F_UNREF(Looper,      readDrawLooper);
   2750     F_UNREF(ImageFilter, readImageFilter);
   2751     F(Typeface,    readTypeface);
   2752 #undef F
   2753 #undef F_UNREF
   2754     if (dirty & kAnnotation_DirtyBit) {
   2755         paint->setAnnotation(SkAnnotation::Create(buffer))->unref();
   2756     }
   2757 #ifdef SK_BUILD_FOR_ANDROID
   2758     if (dirty & kPaintOptionsAndroid_DirtyBit) {
   2759         SkPaintOptionsAndroid options;
   2760         options.unflatten(buffer);
   2761         paint->setPaintOptionsAndroid(options);
   2762     }
   2763 #endif
   2764     SkASSERT(dirty == paint->fDirtyBits);
   2765 }
   2766