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