Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkScalerContext.h"
     11 #include "SkColorPriv.h"
     12 #include "SkDescriptor.h"
     13 #include "SkDraw.h"
     14 #include "SkFontHost.h"
     15 #include "SkGlyph.h"
     16 #include "SkMaskFilter.h"
     17 #include "SkMaskGamma.h"
     18 #include "SkOrderedReadBuffer.h"
     19 #include "SkOrderedWriteBuffer.h"
     20 #include "SkPathEffect.h"
     21 #include "SkRasterizer.h"
     22 #include "SkRasterClip.h"
     23 #include "SkStroke.h"
     24 #include "SkThread.h"
     25 
     26 #ifdef SK_BUILD_FOR_ANDROID
     27     #include "SkTypeface_android.h"
     28 #endif
     29 
     30 #define ComputeBWRowBytes(width)        (((unsigned)(width) + 7) >> 3)
     31 
     32 void SkGlyph::toMask(SkMask* mask) const {
     33     SkASSERT(mask);
     34 
     35     mask->fImage = (uint8_t*)fImage;
     36     mask->fBounds.set(fLeft, fTop, fLeft + fWidth, fTop + fHeight);
     37     mask->fRowBytes = this->rowBytes();
     38     mask->fFormat = static_cast<SkMask::Format>(fMaskFormat);
     39 }
     40 
     41 size_t SkGlyph::computeImageSize() const {
     42     const size_t size = this->rowBytes() * fHeight;
     43 
     44     switch (fMaskFormat) {
     45         case SkMask::k3D_Format:
     46             return 3 * size;
     47         default:
     48             return size;
     49     }
     50 }
     51 
     52 void SkGlyph::zeroMetrics() {
     53     fAdvanceX = 0;
     54     fAdvanceY = 0;
     55     fWidth    = 0;
     56     fHeight   = 0;
     57     fTop      = 0;
     58     fLeft     = 0;
     59     fRsbDelta = 0;
     60     fLsbDelta = 0;
     61 }
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 #ifdef SK_DEBUG
     66     #define DUMP_RECx
     67 #endif
     68 
     69 static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag,
     70                                        SkFlattenable::Type ft) {
     71     SkFlattenable*  obj = NULL;
     72     uint32_t        len;
     73     const void*     data = desc->findEntry(tag, &len);
     74 
     75     if (data) {
     76         SkOrderedReadBuffer   buffer(data, len);
     77         obj = buffer.readFlattenable(ft);
     78         SkASSERT(buffer.offset() == buffer.size());
     79     }
     80     return obj;
     81 }
     82 
     83 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc)
     84     : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL)))
     85 
     86     , fBaseGlyphCount(0)
     87     , fTypeface(SkRef(typeface))
     88     , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_SkDescriptorTag,
     89                                              SkFlattenable::kSkPathEffect_Type)))
     90     , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_SkDescriptorTag,
     91                                              SkFlattenable::kSkMaskFilter_Type)))
     92     , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_SkDescriptorTag,
     93                                              SkFlattenable::kSkRasterizer_Type)))
     94       // Initialize based on our settings. Subclasses can also force this.
     95     , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL)
     96 
     97     , fNextContext(NULL)
     98 
     99     , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMaskPreBlend(fRec))
    100     , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec)
    101                                      : SkMaskGamma::PreBlend())
    102 {
    103 #ifdef DUMP_REC
    104     desc->assertChecksum();
    105     SkDebugf("SkScalarContext checksum %x count %d length %d\n",
    106              desc->getChecksum(), desc->getCount(), desc->getLength());
    107     SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n",
    108         rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0],
    109         rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]);
    110     SkDebugf("  frame %g miter %g hints %d framefill %d format %d join %d\n",
    111         rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill,
    112         rec->fMaskFormat, rec->fStrokeJoin);
    113     SkDebugf("  pathEffect %x maskFilter %x\n",
    114              desc->findEntry(kPathEffect_SkDescriptorTag, NULL),
    115         desc->findEntry(kMaskFilter_SkDescriptorTag, NULL));
    116 #endif
    117 #ifdef SK_BUILD_FOR_ANDROID
    118     uint32_t len;
    119     const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len);
    120     if (data) {
    121         SkOrderedReadBuffer buffer(data, len);
    122         fPaintOptionsAndroid.unflatten(buffer);
    123         SkASSERT(buffer.offset() == buffer.size());
    124     }
    125 #endif
    126 }
    127 
    128 SkScalerContext::~SkScalerContext() {
    129     SkDELETE(fNextContext);
    130 
    131     SkSafeUnref(fPathEffect);
    132     SkSafeUnref(fMaskFilter);
    133     SkSafeUnref(fRasterizer);
    134 }
    135 
    136 // Return the context associated with the next logical typeface, or NULL if
    137 // there are no more entries in the fallback chain.
    138 SkScalerContext* SkScalerContext::allocNextContext() const {
    139 #ifdef SK_BUILD_FOR_ANDROID
    140     SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
    141                                                        fRec.fOrigFontID,
    142                                                        fPaintOptionsAndroid);
    143     if (0 == newFace) {
    144         return NULL;
    145     }
    146 
    147     SkAutoTUnref<SkTypeface> aur(newFace);
    148     uint32_t newFontID = newFace->uniqueID();
    149 
    150     SkOrderedWriteBuffer androidBuffer(128);
    151     fPaintOptionsAndroid.flatten(androidBuffer);
    152 
    153     SkAutoDescriptor    ad(sizeof(fRec) + androidBuffer.size() + SkDescriptor::ComputeOverhead(2));
    154     SkDescriptor*       desc = ad.getDesc();
    155 
    156     desc->init();
    157     SkScalerContext::Rec* newRec =
    158     (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
    159                                           sizeof(fRec), &fRec);
    160     androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
    161                                                androidBuffer.size(), NULL));
    162 
    163     newRec->fFontID = newFontID;
    164     desc->computeChecksum();
    165 
    166     return newFace->createScalerContext(desc);
    167 #else
    168     return NULL;
    169 #endif
    170 }
    171 
    172 /*  Return the next context, creating it if its not already created, but return
    173     NULL if the fonthost says there are no more fonts to fallback to.
    174  */
    175 SkScalerContext* SkScalerContext::getNextContext() {
    176     SkScalerContext* next = fNextContext;
    177     // if next is null, then either it isn't cached yet, or we're at the
    178     // end of our possible chain
    179     if (NULL == next) {
    180         next = this->allocNextContext();
    181         if (NULL == next) {
    182             return NULL;
    183         }
    184         // next's base is our base + our local count
    185         next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount());
    186         // cache the answer
    187         fNextContext = next;
    188     }
    189     return next;
    190 }
    191 
    192 SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
    193     unsigned glyphID = glyph.getGlyphID();
    194     SkScalerContext* ctx = this;
    195     for (;;) {
    196         unsigned count = ctx->getGlyphCount();
    197         if (glyphID < count) {
    198             break;
    199         }
    200         glyphID -= count;
    201         ctx = ctx->getNextContext();
    202         if (NULL == ctx) {
    203 //            SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID());
    204             // just return the original context (this)
    205             return this;
    206         }
    207     }
    208     return ctx;
    209 }
    210 
    211 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni,
    212                                                      uint16_t* glyphID) {
    213     SkScalerContext* ctx = this;
    214     for (;;) {
    215         const uint16_t glyph = ctx->generateCharToGlyph(uni);
    216         if (glyph) {
    217             if (NULL != glyphID) {
    218                 *glyphID = glyph;
    219             }
    220             break;  // found it
    221         }
    222         ctx = ctx->getNextContext();
    223         if (NULL == ctx) {
    224             return NULL;
    225         }
    226     }
    227     return ctx;
    228 }
    229 
    230 #ifdef SK_BUILD_FOR_ANDROID
    231 SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
    232     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
    233     if (NULL != ctx) {
    234         return ctx->fRec.fFontID;
    235     } else {
    236         return 0;
    237     }
    238 }
    239 
    240 /*  This loops through all available fallback contexts (if needed) until it
    241     finds some context that can handle the unichar and return it.
    242 
    243     As this is somewhat expensive operation, it should only be done on the first
    244     char of a run.
    245  */
    246 unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
    247     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
    248     if (NULL != ctx) {
    249         return ctx->fBaseGlyphCount;
    250     } else {
    251         SkDEBUGF(("--- no context for char %x\n", uni));
    252         return this->fBaseGlyphCount;
    253     }
    254 }
    255 #endif
    256 
    257 /*  This loops through all available fallback contexts (if needed) until it
    258     finds some context that can handle the unichar. If all fail, returns 0
    259  */
    260 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
    261 
    262     uint16_t tempID;
    263     SkScalerContext* ctx = this->getContextFromChar(uni, &tempID);
    264     if (NULL == ctx) {
    265         return 0; // no more contexts, return missing glyph
    266     }
    267     // add the ctx's base, making glyphID unique for chain of contexts
    268     unsigned glyphID = tempID + ctx->fBaseGlyphCount;
    269     // check for overflow of 16bits, since our glyphID cannot exceed that
    270     if (glyphID > 0xFFFF) {
    271         glyphID = 0;
    272     }
    273     return SkToU16(glyphID);
    274 }
    275 
    276 SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) {
    277     SkScalerContext* ctx = this;
    278     unsigned rangeEnd = 0;
    279     do {
    280         unsigned rangeStart = rangeEnd;
    281 
    282         rangeEnd += ctx->getGlyphCount();
    283         if (rangeStart <= glyphID && glyphID < rangeEnd) {
    284             return ctx->generateGlyphToChar(glyphID - rangeStart);
    285         }
    286         ctx = ctx->getNextContext();
    287     } while (NULL != ctx);
    288     return 0;
    289 }
    290 
    291 void SkScalerContext::getAdvance(SkGlyph* glyph) {
    292     // mark us as just having a valid advance
    293     glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE;
    294     // we mark the format before making the call, in case the impl
    295     // internally ends up calling its generateMetrics, which is OK
    296     // albeit slower than strictly necessary
    297     this->getGlyphContext(*glyph)->generateAdvance(glyph);
    298 }
    299 
    300 void SkScalerContext::getMetrics(SkGlyph* glyph) {
    301     this->getGlyphContext(*glyph)->generateMetrics(glyph);
    302 
    303     // for now we have separate cache entries for devkerning on and off
    304     // in the future we might share caches, but make our measure/draw
    305     // code make the distinction. Thus we zap the values if the caller
    306     // has not asked for them.
    307     if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) {
    308         // no devkern, so zap the fields
    309         glyph->fLsbDelta = glyph->fRsbDelta = 0;
    310     }
    311 
    312     // if either dimension is empty, zap the image bounds of the glyph
    313     if (0 == glyph->fWidth || 0 == glyph->fHeight) {
    314         glyph->fWidth   = 0;
    315         glyph->fHeight  = 0;
    316         glyph->fTop     = 0;
    317         glyph->fLeft    = 0;
    318         glyph->fMaskFormat = 0;
    319         return;
    320     }
    321 
    322     if (fGenerateImageFromPath) {
    323         SkPath      devPath, fillPath;
    324         SkMatrix    fillToDevMatrix;
    325 
    326         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
    327 
    328         if (fRasterizer) {
    329             SkMask  mask;
    330 
    331             if (fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
    332                                        fMaskFilter, &mask,
    333                                        SkMask::kJustComputeBounds_CreateMode)) {
    334                 glyph->fLeft    = mask.fBounds.fLeft;
    335                 glyph->fTop     = mask.fBounds.fTop;
    336                 glyph->fWidth   = SkToU16(mask.fBounds.width());
    337                 glyph->fHeight  = SkToU16(mask.fBounds.height());
    338             } else {
    339                 goto SK_ERROR;
    340             }
    341         } else {
    342             // just use devPath
    343             SkIRect ir;
    344             devPath.getBounds().roundOut(&ir);
    345 
    346             if (ir.isEmpty() || !ir.is16Bit()) {
    347                 goto SK_ERROR;
    348             }
    349             glyph->fLeft    = ir.fLeft;
    350             glyph->fTop     = ir.fTop;
    351             glyph->fWidth   = SkToU16(ir.width());
    352             glyph->fHeight  = SkToU16(ir.height());
    353 
    354             if (glyph->fWidth > 0) {
    355                 switch (fRec.fMaskFormat) {
    356                 case SkMask::kLCD16_Format:
    357                 case SkMask::kLCD32_Format:
    358                     glyph->fWidth += 2;
    359                     glyph->fLeft -= 1;
    360                     break;
    361                 default:
    362                     break;
    363                 }
    364             }
    365         }
    366     }
    367 
    368     if (SkMask::kARGB32_Format != glyph->fMaskFormat) {
    369         glyph->fMaskFormat = fRec.fMaskFormat;
    370     }
    371 
    372     // If we are going to create the mask, then we cannot keep the color
    373     if ((fGenerateImageFromPath || fMaskFilter) &&
    374             SkMask::kARGB32_Format == glyph->fMaskFormat) {
    375         glyph->fMaskFormat = SkMask::kA8_Format;
    376     }
    377 
    378     if (fMaskFilter) {
    379         SkMask      src, dst;
    380         SkMatrix    matrix;
    381 
    382         glyph->toMask(&src);
    383         fRec.getMatrixFrom2x2(&matrix);
    384 
    385         src.fImage = NULL;  // only want the bounds from the filter
    386         if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) {
    387             if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) {
    388                 goto SK_ERROR;
    389             }
    390             SkASSERT(dst.fImage == NULL);
    391             glyph->fLeft    = dst.fBounds.fLeft;
    392             glyph->fTop     = dst.fBounds.fTop;
    393             glyph->fWidth   = SkToU16(dst.fBounds.width());
    394             glyph->fHeight  = SkToU16(dst.fBounds.height());
    395             glyph->fMaskFormat = dst.fFormat;
    396         }
    397     }
    398     return;
    399 
    400 SK_ERROR:
    401     // draw nothing 'cause we failed
    402     glyph->fLeft    = 0;
    403     glyph->fTop     = 0;
    404     glyph->fWidth   = 0;
    405     glyph->fHeight  = 0;
    406     // put a valid value here, in case it was earlier set to
    407     // MASK_FORMAT_JUST_ADVANCE
    408     glyph->fMaskFormat = fRec.fMaskFormat;
    409 }
    410 
    411 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
    412 
    413 static void applyLUTToA8Mask(const SkMask& mask, const uint8_t* lut) {
    414     uint8_t* SK_RESTRICT dst = (uint8_t*)mask.fImage;
    415     unsigned rowBytes = mask.fRowBytes;
    416 
    417     for (int y = mask.fBounds.height() - 1; y >= 0; --y) {
    418         for (int x = mask.fBounds.width() - 1; x >= 0; --x) {
    419             dst[x] = lut[dst[x]];
    420         }
    421         dst += rowBytes;
    422     }
    423 }
    424 
    425 template<bool APPLY_PREBLEND>
    426 static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst,
    427                            const SkMaskGamma::PreBlend& maskPreBlend) {
    428 #define SAMPLES_PER_PIXEL 4
    429 #define LCD_PER_PIXEL 3
    430     SkASSERT(SkBitmap::kA8_Config == src.config());
    431     SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
    432 
    433     const int sample_width = src.width();
    434     const int height = src.height();
    435 
    436     uint16_t* dstP = (uint16_t*)dst.fImage;
    437     size_t dstRB = dst.fRowBytes;
    438     // An N tap FIR is defined by
    439     // out[n] = coeff[0]*x[n] + coeff[1]*x[n-1] + ... + coeff[N]*x[n-N]
    440     // or
    441     // out[n] = sum(i, 0, N, coeff[i]*x[n-i])
    442 
    443     // The strategy is to use one FIR (different coefficients) for each of r, g, and b.
    444     // This means using every 4th FIR output value of each FIR and discarding the rest.
    445     // The FIRs are aligned, and the coefficients reach 5 samples to each side of their 'center'.
    446     // (For r and b this is technically incorrect, but the coeffs outside round to zero anyway.)
    447 
    448     // These are in some fixed point repesentation.
    449     // Adding up to more than one simulates ink spread.
    450     // For implementation reasons, these should never add up to more than two.
    451 
    452     // Coefficients determined by a gausian where 5 samples = 3 std deviations (0x110 'contrast').
    453     // Calculated using tools/generate_fir_coeff.py
    454     // With this one almost no fringing is ever seen, but it is imperceptibly blurry.
    455     // The lcd smoothed text is almost imperceptibly different from gray,
    456     // but is still sharper on small stems and small rounded corners than gray.
    457     // This also seems to be about as wide as one can get and only have a three pixel kernel.
    458     // TODO: caculate these at runtime so parameters can be adjusted (esp contrast).
    459     static const unsigned int coefficients[LCD_PER_PIXEL][SAMPLES_PER_PIXEL*3] = {
    460         //The red subpixel is centered inside the first sample (at 1/6 pixel), and is shifted.
    461         { 0x03, 0x0b, 0x1c, 0x33,  0x40, 0x39, 0x24, 0x10,  0x05, 0x01, 0x00, 0x00, },
    462         //The green subpixel is centered between two samples (at 1/2 pixel), so is symetric
    463         { 0x00, 0x02, 0x08, 0x16,  0x2b, 0x3d, 0x3d, 0x2b,  0x16, 0x08, 0x02, 0x00, },
    464         //The blue subpixel is centered inside the last sample (at 5/6 pixel), and is shifted.
    465         { 0x00, 0x00, 0x01, 0x05,  0x10, 0x24, 0x39, 0x40,  0x33, 0x1c, 0x0b, 0x03, },
    466     };
    467 
    468     for (int y = 0; y < height; ++y) {
    469         const uint8_t* srcP = src.getAddr8(0, y);
    470 
    471         // TODO: this fir filter implementation is straight forward, but slow.
    472         // It should be possible to make it much faster.
    473         for (int sample_x = -4, pixel_x = 0; sample_x < sample_width + 4; sample_x += 4, ++pixel_x) {
    474             int fir[LCD_PER_PIXEL] = { 0 };
    475             for (int sample_index = SkMax32(0, sample_x - 4), coeff_index = sample_index - (sample_x - 4)
    476                 ; sample_index < SkMin32(sample_x + 8, sample_width)
    477                 ; ++sample_index, ++coeff_index)
    478             {
    479                 int sample_value = srcP[sample_index];
    480                 for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
    481                     fir[subpxl_index] += coefficients[subpxl_index][coeff_index] * sample_value;
    482                 }
    483             }
    484             for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
    485                 fir[subpxl_index] /= 0x100;
    486                 fir[subpxl_index] = SkMin32(fir[subpxl_index], 255);
    487             }
    488 
    489             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(fir[0], maskPreBlend.fR);
    490             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(fir[1], maskPreBlend.fG);
    491             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(fir[2], maskPreBlend.fB);
    492 #if SK_SHOW_TEXT_BLIT_COVERAGE
    493             r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
    494 #endif
    495             dstP[pixel_x] = SkPack888ToRGB16(r, g, b);
    496         }
    497         dstP = (uint16_t*)((char*)dstP + dstRB);
    498     }
    499 }
    500 
    501 template<bool APPLY_PREBLEND>
    502 static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst,
    503                            const SkMaskGamma::PreBlend& maskPreBlend) {
    504     SkASSERT(SkBitmap::kA8_Config == src.config());
    505     SkASSERT(SkMask::kLCD32_Format == dst.fFormat);
    506 
    507     const int width = dst.fBounds.width();
    508     const int height = dst.fBounds.height();
    509     SkPMColor* dstP = (SkPMColor*)dst.fImage;
    510     size_t dstRB = dst.fRowBytes;
    511 
    512     for (int y = 0; y < height; ++y) {
    513         const uint8_t* srcP = src.getAddr8(0, y);
    514 
    515         // TODO: need to use fir filter here as well.
    516         for (int x = 0; x < width; ++x) {
    517             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fR);
    518             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fG);
    519             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fB);
    520             dstP[x] = SkPackARGB32(0xFF, r, g, b);
    521         }
    522         dstP = (SkPMColor*)((char*)dstP + dstRB);
    523     }
    524 }
    525 
    526 static inline int convert_8_to_1(unsigned byte) {
    527     SkASSERT(byte <= 0xFF);
    528     return byte >> 7;
    529 }
    530 
    531 static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
    532     unsigned bits = 0;
    533     for (int i = 0; i < 8; ++i) {
    534         bits <<= 1;
    535         bits |= convert_8_to_1(alpha[i]);
    536     }
    537     return SkToU8(bits);
    538 }
    539 
    540 static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
    541     const int height = mask.fBounds.height();
    542     const int width = mask.fBounds.width();
    543     const int octs = width >> 3;
    544     const int leftOverBits = width & 7;
    545 
    546     uint8_t* dst = mask.fImage;
    547     const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
    548     SkASSERT(dstPad >= 0);
    549 
    550     const int srcPad = srcRB - width;
    551     SkASSERT(srcPad >= 0);
    552 
    553     for (int y = 0; y < height; ++y) {
    554         for (int i = 0; i < octs; ++i) {
    555             *dst++ = pack_8_to_1(src);
    556             src += 8;
    557         }
    558         if (leftOverBits > 0) {
    559             unsigned bits = 0;
    560             int shift = 7;
    561             for (int i = 0; i < leftOverBits; ++i, --shift) {
    562                 bits |= convert_8_to_1(*src++) << shift;
    563             }
    564             *dst++ = bits;
    565         }
    566         src += srcPad;
    567         dst += dstPad;
    568     }
    569 }
    570 
    571 static void generateMask(const SkMask& mask, const SkPath& path,
    572                          const SkMaskGamma::PreBlend& maskPreBlend) {
    573     SkPaint paint;
    574 
    575     int srcW = mask.fBounds.width();
    576     int srcH = mask.fBounds.height();
    577     int dstW = srcW;
    578     int dstH = srcH;
    579     int dstRB = mask.fRowBytes;
    580 
    581     SkMatrix matrix;
    582     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
    583                         -SkIntToScalar(mask.fBounds.fTop));
    584 
    585     SkBitmap::Config config = SkBitmap::kA8_Config;
    586     paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
    587     switch (mask.fFormat) {
    588         case SkMask::kBW_Format:
    589             dstRB = 0;  // signals we need a copy
    590             break;
    591         case SkMask::kA8_Format:
    592             break;
    593         case SkMask::kLCD16_Format:
    594         case SkMask::kLCD32_Format:
    595             // TODO: trigger off LCD orientation
    596             dstW = 4*dstW - 8;
    597             matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
    598                                 -SkIntToScalar(mask.fBounds.fTop));
    599             matrix.postScale(SkIntToScalar(4), SK_Scalar1);
    600             dstRB = 0;  // signals we need a copy
    601             break;
    602         default:
    603             SkDEBUGFAIL("unexpected mask format");
    604     }
    605 
    606     SkRasterClip clip;
    607     clip.setRect(SkIRect::MakeWH(dstW, dstH));
    608 
    609     SkBitmap bm;
    610     bm.setConfig(config, dstW, dstH, dstRB);
    611 
    612     if (0 == dstRB) {
    613         if (!bm.allocPixels()) {
    614             // can't allocate offscreen, so empty the mask and return
    615             sk_bzero(mask.fImage, mask.computeImageSize());
    616             return;
    617         }
    618         bm.lockPixels();
    619     } else {
    620         bm.setPixels(mask.fImage);
    621     }
    622     sk_bzero(bm.getPixels(), bm.getSafeSize());
    623 
    624     SkDraw  draw;
    625     draw.fRC    = &clip;
    626     draw.fClip  = &clip.bwRgn();
    627     draw.fMatrix = &matrix;
    628     draw.fBitmap = &bm;
    629     draw.drawPath(path, paint);
    630 
    631     switch (mask.fFormat) {
    632         case SkMask::kBW_Format:
    633             packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes());
    634             break;
    635         case SkMask::kA8_Format:
    636             if (maskPreBlend.isApplicable()) {
    637                 applyLUTToA8Mask(mask, maskPreBlend.fG);
    638             }
    639             break;
    640         case SkMask::kLCD16_Format:
    641             if (maskPreBlend.isApplicable()) {
    642                 pack4xHToLCD16<true>(bm, mask, maskPreBlend);
    643             } else {
    644                 pack4xHToLCD16<false>(bm, mask, maskPreBlend);
    645             }
    646             break;
    647         case SkMask::kLCD32_Format:
    648             if (maskPreBlend.isApplicable()) {
    649                 pack4xHToLCD32<true>(bm, mask, maskPreBlend);
    650             } else {
    651                 pack4xHToLCD32<false>(bm, mask, maskPreBlend);
    652             }
    653             break;
    654         default:
    655             break;
    656     }
    657 }
    658 
    659 static void extract_alpha(const SkMask& dst,
    660                           const SkPMColor* srcRow, size_t srcRB) {
    661     int width = dst.fBounds.width();
    662     int height = dst.fBounds.height();
    663     int dstRB = dst.fRowBytes;
    664     uint8_t* dstRow = dst.fImage;
    665 
    666     for (int y = 0; y < height; ++y) {
    667         for (int x = 0; x < width; ++x) {
    668             dstRow[x] = SkGetPackedA32(srcRow[x]);
    669         }
    670         // zero any padding on each row
    671         for (int x = width; x < dstRB; ++x) {
    672             dstRow[x] = 0;
    673         }
    674         dstRow += dstRB;
    675         srcRow = (const SkPMColor*)((const char*)srcRow + srcRB);
    676     }
    677 }
    678 
    679 void SkScalerContext::getImage(const SkGlyph& origGlyph) {
    680     const SkGlyph*  glyph = &origGlyph;
    681     SkGlyph         tmpGlyph;
    682 
    683     // in case we need to call generateImage on a mask-format that is different
    684     // (i.e. larger) than what our caller allocated by looking at origGlyph.
    685     SkAutoMalloc tmpGlyphImageStorage;
    686 
    687     // If we are going to draw-from-path, then we cannot generate color, since
    688     // the path only makes a mask. This case should have been caught up in
    689     // generateMetrics().
    690     SkASSERT(!fGenerateImageFromPath ||
    691              SkMask::kARGB32_Format != origGlyph.fMaskFormat);
    692 
    693     if (fMaskFilter) {   // restore the prefilter bounds
    694         tmpGlyph.init(origGlyph.fID);
    695 
    696         // need the original bounds, sans our maskfilter
    697         SkMaskFilter* mf = fMaskFilter;
    698         fMaskFilter = NULL;             // temp disable
    699         this->getMetrics(&tmpGlyph);
    700         fMaskFilter = mf;               // restore
    701 
    702         // we need the prefilter bounds to be <= filter bounds
    703         SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
    704         SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
    705 
    706         if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
    707             tmpGlyph.fImage = origGlyph.fImage;
    708         } else {
    709             tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize());
    710             tmpGlyph.fImage = tmpGlyphImageStorage.get();
    711         }
    712         glyph = &tmpGlyph;
    713     }
    714 
    715     if (fGenerateImageFromPath) {
    716         SkPath      devPath, fillPath;
    717         SkMatrix    fillToDevMatrix;
    718         SkMask      mask;
    719 
    720         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
    721         glyph->toMask(&mask);
    722 
    723         if (fRasterizer) {
    724             mask.fFormat = SkMask::kA8_Format;
    725             sk_bzero(glyph->fImage, mask.computeImageSize());
    726 
    727             if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
    728                                         fMaskFilter, &mask,
    729                                         SkMask::kJustRenderImage_CreateMode)) {
    730                 return;
    731             }
    732             if (fPreBlend.isApplicable()) {
    733                 applyLUTToA8Mask(mask, fPreBlend.fG);
    734             }
    735         } else {
    736             SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
    737             generateMask(mask, devPath, fPreBlend);
    738         }
    739     } else {
    740         this->getGlyphContext(*glyph)->generateImage(*glyph);
    741     }
    742 
    743     if (fMaskFilter) {
    744         SkMask      srcM, dstM;
    745         SkMatrix    matrix;
    746 
    747         // the src glyph image shouldn't be 3D
    748         SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
    749 
    750         SkAutoSMalloc<32*32> a8storage;
    751         glyph->toMask(&srcM);
    752         if (SkMask::kARGB32_Format == srcM.fFormat) {
    753             // now we need to extract the alpha-channel from the glyph's image
    754             // and copy it into a temp buffer, and then point srcM at that temp.
    755             srcM.fFormat = SkMask::kA8_Format;
    756             srcM.fRowBytes = SkAlign4(srcM.fBounds.width());
    757             size_t size = srcM.computeImageSize();
    758             a8storage.reset(size);
    759             srcM.fImage = (uint8_t*)a8storage.get();
    760             extract_alpha(srcM,
    761                           (const SkPMColor*)glyph->fImage, glyph->rowBytes());
    762         }
    763 
    764         fRec.getMatrixFrom2x2(&matrix);
    765 
    766         if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) {
    767             int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width());
    768             int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height());
    769             int dstRB = origGlyph.rowBytes();
    770             int srcRB = dstM.fRowBytes;
    771 
    772             const uint8_t* src = (const uint8_t*)dstM.fImage;
    773             uint8_t* dst = (uint8_t*)origGlyph.fImage;
    774 
    775             if (SkMask::k3D_Format == dstM.fFormat) {
    776                 // we have to copy 3 times as much
    777                 height *= 3;
    778             }
    779 
    780             // clean out our glyph, since it may be larger than dstM
    781             //sk_bzero(dst, height * dstRB);
    782 
    783             while (--height >= 0) {
    784                 memcpy(dst, src, width);
    785                 src += srcRB;
    786                 dst += dstRB;
    787             }
    788             SkMask::FreeImage(dstM.fImage);
    789 
    790             if (fPreBlendForFilter.isApplicable()) {
    791                 applyLUTToA8Mask(srcM, fPreBlendForFilter.fG);
    792             }
    793         }
    794     }
    795 }
    796 
    797 void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) {
    798     this->internalGetPath(glyph, NULL, path, NULL);
    799 }
    800 
    801 void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) {
    802     // All of this complexity should go away when we change generateFontMetrics
    803     // to just take one parameter (since it knows if it is vertical or not)
    804     SkPaint::FontMetrics* mx = NULL;
    805     SkPaint::FontMetrics* my = NULL;
    806     if (fRec.fFlags & kVertical_Flag) {
    807         mx = fm;
    808     } else {
    809         my = fm;
    810     }
    811     this->generateFontMetrics(mx, my);
    812 }
    813 
    814 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
    815     return 0;
    816 }
    817 
    818 ///////////////////////////////////////////////////////////////////////////////
    819 
    820 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
    821                                   SkPath* devPath, SkMatrix* fillToDevMatrix) {
    822     SkPath  path;
    823 
    824     this->getGlyphContext(glyph)->generatePath(glyph, &path);
    825 
    826     if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
    827         SkFixed dx = glyph.getSubXFixed();
    828         SkFixed dy = glyph.getSubYFixed();
    829         if (dx | dy) {
    830             path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy));
    831         }
    832     }
    833 
    834     if (fRec.fFrameWidth > 0 || fPathEffect != NULL) {
    835         // need the path in user-space, with only the point-size applied
    836         // so that our stroking and effects will operate the same way they
    837         // would if the user had extracted the path themself, and then
    838         // called drawPath
    839         SkPath      localPath;
    840         SkMatrix    matrix, inverse;
    841 
    842         fRec.getMatrixFrom2x2(&matrix);
    843         if (!matrix.invert(&inverse)) {
    844             // assume fillPath and devPath are already empty.
    845             return;
    846         }
    847         path.transform(inverse, &localPath);
    848         // now localPath is only affected by the paint settings, and not the canvas matrix
    849 
    850         SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
    851 
    852         if (fRec.fFrameWidth > 0) {
    853             rec.setStrokeStyle(fRec.fFrameWidth,
    854                                SkToBool(fRec.fFlags & kFrameAndFill_Flag));
    855             // glyphs are always closed contours, so cap type is ignored,
    856             // so we just pass something.
    857             rec.setStrokeParams(SkPaint::kButt_Cap,
    858                                 (SkPaint::Join)fRec.fStrokeJoin,
    859                                 fRec.fMiterLimit);
    860         }
    861 
    862         if (fPathEffect) {
    863             SkPath effectPath;
    864             if (fPathEffect->filterPath(&effectPath, localPath, &rec, NULL)) {
    865                 localPath.swap(effectPath);
    866             }
    867         }
    868 
    869         if (rec.needToApply()) {
    870             SkPath strokePath;
    871             if (rec.applyToPath(&strokePath, localPath)) {
    872                 localPath.swap(strokePath);
    873             }
    874         }
    875 
    876         // now return stuff to the caller
    877         if (fillToDevMatrix) {
    878             *fillToDevMatrix = matrix;
    879         }
    880         if (devPath) {
    881             localPath.transform(matrix, devPath);
    882         }
    883         if (fillPath) {
    884             fillPath->swap(localPath);
    885         }
    886     } else {   // nothing tricky to do
    887         if (fillToDevMatrix) {
    888             fillToDevMatrix->reset();
    889         }
    890         if (devPath) {
    891             if (fillPath == NULL) {
    892                 devPath->swap(path);
    893             } else {
    894                 *devPath = path;
    895             }
    896         }
    897 
    898         if (fillPath) {
    899             fillPath->swap(path);
    900         }
    901     }
    902 
    903     if (devPath) {
    904         devPath->updateBoundsCache();
    905     }
    906     if (fillPath) {
    907         fillPath->updateBoundsCache();
    908     }
    909 }
    910 
    911 
    912 void SkScalerContextRec::getMatrixFrom2x2(SkMatrix* dst) const {
    913     dst->setAll(fPost2x2[0][0], fPost2x2[0][1], 0,
    914                 fPost2x2[1][0], fPost2x2[1][1], 0,
    915                 0,              0,              SkScalarToPersp(SK_Scalar1));
    916 }
    917 
    918 void SkScalerContextRec::getLocalMatrix(SkMatrix* m) const {
    919     SkPaint::SetTextMatrix(m, fTextSize, fPreScaleX, fPreSkewX);
    920 }
    921 
    922 void SkScalerContextRec::getSingleMatrix(SkMatrix* m) const {
    923     this->getLocalMatrix(m);
    924 
    925     //  now concat the device matrix
    926     SkMatrix    deviceMatrix;
    927     this->getMatrixFrom2x2(&deviceMatrix);
    928     m->postConcat(deviceMatrix);
    929 }
    930 
    931 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix) {
    932     SkASSERT(!matrix.hasPerspective());
    933 
    934     if (0 == matrix[SkMatrix::kMSkewY]) {
    935         return kX_SkAxisAlignment;
    936     }
    937     if (0 == matrix[SkMatrix::kMScaleX]) {
    938         return kY_SkAxisAlignment;
    939     }
    940     return kNone_SkAxisAlignment;
    941 }
    942 
    943 ///////////////////////////////////////////////////////////////////////////////
    944 
    945 #include "SkFontHost.h"
    946 
    947 class SkScalerContext_Empty : public SkScalerContext {
    948 public:
    949     SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc)
    950         : SkScalerContext(face, desc) {}
    951 
    952 protected:
    953     virtual unsigned generateGlyphCount() SK_OVERRIDE {
    954         return 0;
    955     }
    956     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE {
    957         return 0;
    958     }
    959     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE {
    960         glyph->zeroMetrics();
    961     }
    962     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE {
    963         glyph->zeroMetrics();
    964     }
    965     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {}
    966     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {}
    967     virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
    968                                      SkPaint::FontMetrics* my) SK_OVERRIDE {
    969         if (mx) {
    970             sk_bzero(mx, sizeof(*mx));
    971         }
    972         if (my) {
    973             sk_bzero(my, sizeof(*my));
    974         }
    975     }
    976 };
    977 
    978 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc);
    979 
    980 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc,
    981                                                  bool allowFailure) const {
    982     SkScalerContext* c = this->onCreateScalerContext(desc);
    983 
    984     if (!c && !allowFailure) {
    985         c = SkNEW_ARGS(SkScalerContext_Empty,
    986                        (const_cast<SkTypeface*>(this), desc));
    987     }
    988     return c;
    989 }
    990