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