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 "SkReadBuffer.h"
     19 #include "SkWriteBuffer.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         SkReadBuffer 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("SkScalerContext 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         SkReadBuffer 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     SkWriteBuffer androidBuffer;
    151     fPaintOptionsAndroid.flatten(androidBuffer);
    152 
    153     SkAutoDescriptor    ad(sizeof(fRec) + androidBuffer.bytesWritten()
    154                            + SkDescriptor::ComputeOverhead(2));
    155     SkDescriptor*       desc = ad.getDesc();
    156 
    157     desc->init();
    158     SkScalerContext::Rec* newRec =
    159     (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
    160                                           sizeof(fRec), &fRec);
    161     androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
    162                                                androidBuffer.bytesWritten(), NULL));
    163 
    164     newRec->fFontID = newFontID;
    165     desc->computeChecksum();
    166 
    167     return newFace->createScalerContext(desc);
    168 #else
    169     return NULL;
    170 #endif
    171 }
    172 
    173 /*  Return the next context, creating it if its not already created, but return
    174     NULL if the fonthost says there are no more fonts to fallback to.
    175  */
    176 SkScalerContext* SkScalerContext::getNextContext() {
    177     SkScalerContext* next = fNextContext;
    178     // if next is null, then either it isn't cached yet, or we're at the
    179     // end of our possible chain
    180     if (NULL == next) {
    181         next = this->allocNextContext();
    182         if (NULL == next) {
    183             return NULL;
    184         }
    185         // next's base is our base + our local count
    186         next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount());
    187         // cache the answer
    188         fNextContext = next;
    189     }
    190     return next;
    191 }
    192 
    193 SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
    194     unsigned glyphID = glyph.getGlyphID();
    195     SkScalerContext* ctx = this;
    196     for (;;) {
    197         unsigned count = ctx->getGlyphCount();
    198         if (glyphID < count) {
    199             break;
    200         }
    201         glyphID -= count;
    202         ctx = ctx->getNextContext();
    203         if (NULL == ctx) {
    204 //            SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID());
    205             // just return the original context (this)
    206             return this;
    207         }
    208     }
    209     return ctx;
    210 }
    211 
    212 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni,
    213                                                      uint16_t* glyphID) {
    214     SkScalerContext* ctx = this;
    215     for (;;) {
    216         const uint16_t glyph = ctx->generateCharToGlyph(uni);
    217         if (glyph) {
    218             if (NULL != glyphID) {
    219                 *glyphID = glyph;
    220             }
    221             break;  // found it
    222         }
    223         ctx = ctx->getNextContext();
    224         if (NULL == ctx) {
    225             return NULL;
    226         }
    227     }
    228     return ctx;
    229 }
    230 
    231 #ifdef SK_BUILD_FOR_ANDROID
    232 SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
    233     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
    234     if (NULL != ctx) {
    235         return ctx->fRec.fFontID;
    236     } else {
    237         return 0;
    238     }
    239 }
    240 
    241 /*  This loops through all available fallback contexts (if needed) until it
    242     finds some context that can handle the unichar and return it.
    243 
    244     As this is somewhat expensive operation, it should only be done on the first
    245     char of a run.
    246  */
    247 unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
    248     SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
    249     if (NULL != ctx) {
    250         return ctx->fBaseGlyphCount;
    251     } else {
    252         SkDEBUGF(("--- no context for char %x\n", uni));
    253         return this->fBaseGlyphCount;
    254     }
    255 }
    256 #endif
    257 
    258 /*  This loops through all available fallback contexts (if needed) until it
    259     finds some context that can handle the unichar. If all fail, returns 0
    260  */
    261 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
    262 
    263     uint16_t tempID;
    264     SkScalerContext* ctx = this->getContextFromChar(uni, &tempID);
    265     if (NULL == ctx) {
    266         return 0; // no more contexts, return missing glyph
    267     }
    268     // add the ctx's base, making glyphID unique for chain of contexts
    269     unsigned glyphID = tempID + ctx->fBaseGlyphCount;
    270     // check for overflow of 16bits, since our glyphID cannot exceed that
    271     if (glyphID > 0xFFFF) {
    272         glyphID = 0;
    273     }
    274     return SkToU16(glyphID);
    275 }
    276 
    277 SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) {
    278     SkScalerContext* ctx = this;
    279     unsigned rangeEnd = 0;
    280     do {
    281         unsigned rangeStart = rangeEnd;
    282 
    283         rangeEnd += ctx->getGlyphCount();
    284         if (rangeStart <= glyphID && glyphID < rangeEnd) {
    285             return ctx->generateGlyphToChar(glyphID - rangeStart);
    286         }
    287         ctx = ctx->getNextContext();
    288     } while (NULL != ctx);
    289     return 0;
    290 }
    291 
    292 void SkScalerContext::getAdvance(SkGlyph* glyph) {
    293     // mark us as just having a valid advance
    294     glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE;
    295     // we mark the format before making the call, in case the impl
    296     // internally ends up calling its generateMetrics, which is OK
    297     // albeit slower than strictly necessary
    298     this->getGlyphContext(*glyph)->generateAdvance(glyph);
    299 }
    300 
    301 void SkScalerContext::getMetrics(SkGlyph* glyph) {
    302     this->getGlyphContext(*glyph)->generateMetrics(glyph);
    303 
    304     // for now we have separate cache entries for devkerning on and off
    305     // in the future we might share caches, but make our measure/draw
    306     // code make the distinction. Thus we zap the values if the caller
    307     // has not asked for them.
    308     if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) {
    309         // no devkern, so zap the fields
    310         glyph->fLsbDelta = glyph->fRsbDelta = 0;
    311     }
    312 
    313     // if either dimension is empty, zap the image bounds of the glyph
    314     if (0 == glyph->fWidth || 0 == glyph->fHeight) {
    315         glyph->fWidth   = 0;
    316         glyph->fHeight  = 0;
    317         glyph->fTop     = 0;
    318         glyph->fLeft    = 0;
    319         glyph->fMaskFormat = 0;
    320         return;
    321     }
    322 
    323     if (fGenerateImageFromPath) {
    324         SkPath      devPath, fillPath;
    325         SkMatrix    fillToDevMatrix;
    326 
    327         this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
    328 
    329         if (fRasterizer) {
    330             SkMask  mask;
    331 
    332             if (fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL,
    333                                        fMaskFilter, &mask,
    334                                        SkMask::kJustComputeBounds_CreateMode)) {
    335                 glyph->fLeft    = mask.fBounds.fLeft;
    336                 glyph->fTop     = mask.fBounds.fTop;
    337                 glyph->fWidth   = SkToU16(mask.fBounds.width());
    338                 glyph->fHeight  = SkToU16(mask.fBounds.height());
    339             } else {
    340                 goto SK_ERROR;
    341             }
    342         } else {
    343             // just use devPath
    344             SkIRect ir;
    345             devPath.getBounds().roundOut(&ir);
    346 
    347             if (ir.isEmpty() || !ir.is16Bit()) {
    348                 goto SK_ERROR;
    349             }
    350             glyph->fLeft    = ir.fLeft;
    351             glyph->fTop     = ir.fTop;
    352             glyph->fWidth   = SkToU16(ir.width());
    353             glyph->fHeight  = SkToU16(ir.height());
    354 
    355             if (glyph->fWidth > 0) {
    356                 switch (fRec.fMaskFormat) {
    357                 case SkMask::kLCD16_Format:
    358                 case SkMask::kLCD32_Format:
    359                     glyph->fWidth += 2;
    360                     glyph->fLeft -= 1;
    361                     break;
    362                 default:
    363                     break;
    364                 }
    365             }
    366         }
    367     }
    368 
    369     if (SkMask::kARGB32_Format != glyph->fMaskFormat) {
    370         glyph->fMaskFormat = fRec.fMaskFormat;
    371     }
    372 
    373     // If we are going to create the mask, then we cannot keep the color
    374     if ((fGenerateImageFromPath || fMaskFilter) &&
    375             SkMask::kARGB32_Format == glyph->fMaskFormat) {
    376         glyph->fMaskFormat = SkMask::kA8_Format;
    377     }
    378 
    379     if (fMaskFilter) {
    380         SkMask      src, dst;
    381         SkMatrix    matrix;
    382 
    383         glyph->toMask(&src);
    384         fRec.getMatrixFrom2x2(&matrix);
    385 
    386         src.fImage = NULL;  // only want the bounds from the filter
    387         if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) {
    388             if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) {
    389                 goto SK_ERROR;
    390             }
    391             SkASSERT(dst.fImage == NULL);
    392             glyph->fLeft    = dst.fBounds.fLeft;
    393             glyph->fTop     = dst.fBounds.fTop;
    394             glyph->fWidth   = SkToU16(dst.fBounds.width());
    395             glyph->fHeight  = SkToU16(dst.fBounds.height());
    396             glyph->fMaskFormat = dst.fFormat;
    397         }
    398     }
    399     return;
    400 
    401 SK_ERROR:
    402     // draw nothing 'cause we failed
    403     glyph->fLeft    = 0;
    404     glyph->fTop     = 0;
    405     glyph->fWidth   = 0;
    406     glyph->fHeight  = 0;
    407     // put a valid value here, in case it was earlier set to
    408     // MASK_FORMAT_JUST_ADVANCE
    409     glyph->fMaskFormat = fRec.fMaskFormat;
    410 }
    411 
    412 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
    413 
    414 static void applyLUTToA8Mask(const SkMask& mask, const uint8_t* lut) {
    415     uint8_t* SK_RESTRICT dst = (uint8_t*)mask.fImage;
    416     unsigned rowBytes = mask.fRowBytes;
    417 
    418     for (int y = mask.fBounds.height() - 1; y >= 0; --y) {
    419         for (int x = mask.fBounds.width() - 1; x >= 0; --x) {
    420             dst[x] = lut[dst[x]];
    421         }
    422         dst += rowBytes;
    423     }
    424 }
    425 
    426 template<bool APPLY_PREBLEND>
    427 static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst,
    428                            const SkMaskGamma::PreBlend& maskPreBlend) {
    429 #define SAMPLES_PER_PIXEL 4
    430 #define LCD_PER_PIXEL 3
    431     SkASSERT(kAlpha_8_SkColorType == src.colorType());
    432     SkASSERT(SkMask::kLCD16_Format == dst.fFormat);
    433 
    434     const int sample_width = src.width();
    435     const int height = src.height();
    436 
    437     uint16_t* dstP = (uint16_t*)dst.fImage;
    438     size_t dstRB = dst.fRowBytes;
    439     // An N tap FIR is defined by
    440     // out[n] = coeff[0]*x[n] + coeff[1]*x[n-1] + ... + coeff[N]*x[n-N]
    441     // or
    442     // out[n] = sum(i, 0, N, coeff[i]*x[n-i])
    443 
    444     // The strategy is to use one FIR (different coefficients) for each of r, g, and b.
    445     // This means using every 4th FIR output value of each FIR and discarding the rest.
    446     // The FIRs are aligned, and the coefficients reach 5 samples to each side of their 'center'.
    447     // (For r and b this is technically incorrect, but the coeffs outside round to zero anyway.)
    448 
    449     // These are in some fixed point repesentation.
    450     // Adding up to more than one simulates ink spread.
    451     // For implementation reasons, these should never add up to more than two.
    452 
    453     // Coefficients determined by a gausian where 5 samples = 3 std deviations (0x110 'contrast').
    454     // Calculated using tools/generate_fir_coeff.py
    455     // With this one almost no fringing is ever seen, but it is imperceptibly blurry.
    456     // The lcd smoothed text is almost imperceptibly different from gray,
    457     // but is still sharper on small stems and small rounded corners than gray.
    458     // This also seems to be about as wide as one can get and only have a three pixel kernel.
    459     // TODO: caculate these at runtime so parameters can be adjusted (esp contrast).
    460     static const unsigned int coefficients[LCD_PER_PIXEL][SAMPLES_PER_PIXEL*3] = {
    461         //The red subpixel is centered inside the first sample (at 1/6 pixel), and is shifted.
    462         { 0x03, 0x0b, 0x1c, 0x33,  0x40, 0x39, 0x24, 0x10,  0x05, 0x01, 0x00, 0x00, },
    463         //The green subpixel is centered between two samples (at 1/2 pixel), so is symetric
    464         { 0x00, 0x02, 0x08, 0x16,  0x2b, 0x3d, 0x3d, 0x2b,  0x16, 0x08, 0x02, 0x00, },
    465         //The blue subpixel is centered inside the last sample (at 5/6 pixel), and is shifted.
    466         { 0x00, 0x00, 0x01, 0x05,  0x10, 0x24, 0x39, 0x40,  0x33, 0x1c, 0x0b, 0x03, },
    467     };
    468 
    469     for (int y = 0; y < height; ++y) {
    470         const uint8_t* srcP = src.getAddr8(0, y);
    471 
    472         // TODO: this fir filter implementation is straight forward, but slow.
    473         // It should be possible to make it much faster.
    474         for (int sample_x = -4, pixel_x = 0; sample_x < sample_width + 4; sample_x += 4, ++pixel_x) {
    475             int fir[LCD_PER_PIXEL] = { 0 };
    476             for (int sample_index = SkMax32(0, sample_x - 4), coeff_index = sample_index - (sample_x - 4)
    477                 ; sample_index < SkMin32(sample_x + 8, sample_width)
    478                 ; ++sample_index, ++coeff_index)
    479             {
    480                 int sample_value = srcP[sample_index];
    481                 for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
    482                     fir[subpxl_index] += coefficients[subpxl_index][coeff_index] * sample_value;
    483                 }
    484             }
    485             for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) {
    486                 fir[subpxl_index] /= 0x100;
    487                 fir[subpxl_index] = SkMin32(fir[subpxl_index], 255);
    488             }
    489 
    490             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(fir[0], maskPreBlend.fR);
    491             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(fir[1], maskPreBlend.fG);
    492             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(fir[2], maskPreBlend.fB);
    493 #if SK_SHOW_TEXT_BLIT_COVERAGE
    494             r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
    495 #endif
    496             dstP[pixel_x] = SkPack888ToRGB16(r, g, b);
    497         }
    498         dstP = (uint16_t*)((char*)dstP + dstRB);
    499     }
    500 }
    501 
    502 template<bool APPLY_PREBLEND>
    503 static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst,
    504                            const SkMaskGamma::PreBlend& maskPreBlend) {
    505     SkASSERT(kAlpha_8_SkColorType == src.colorType());
    506     SkASSERT(SkMask::kLCD32_Format == dst.fFormat);
    507 
    508     const int width = dst.fBounds.width();
    509     const int height = dst.fBounds.height();
    510     SkPMColor* dstP = (SkPMColor*)dst.fImage;
    511     size_t dstRB = dst.fRowBytes;
    512 
    513     for (int y = 0; y < height; ++y) {
    514         const uint8_t* srcP = src.getAddr8(0, y);
    515 
    516         // TODO: need to use fir filter here as well.
    517         for (int x = 0; x < width; ++x) {
    518             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fR);
    519             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fG);
    520             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fB);
    521             dstP[x] = SkPackARGB32(0xFF, r, g, b);
    522         }
    523         dstP = (SkPMColor*)((char*)dstP + dstRB);
    524     }
    525 }
    526 
    527 static inline int convert_8_to_1(unsigned byte) {
    528     SkASSERT(byte <= 0xFF);
    529     return byte >> 7;
    530 }
    531 
    532 static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
    533     unsigned bits = 0;
    534     for (int i = 0; i < 8; ++i) {
    535         bits <<= 1;
    536         bits |= convert_8_to_1(alpha[i]);
    537     }
    538     return SkToU8(bits);
    539 }
    540 
    541 static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
    542     const int height = mask.fBounds.height();
    543     const int width = mask.fBounds.width();
    544     const int octs = width >> 3;
    545     const int leftOverBits = width & 7;
    546 
    547     uint8_t* dst = mask.fImage;
    548     const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
    549     SkASSERT(dstPad >= 0);
    550 
    551     SkASSERT(width >= 0);
    552     SkASSERT(srcRB >= (size_t)width);
    553     const size_t srcPad = srcRB - width;
    554 
    555     for (int y = 0; y < height; ++y) {
    556         for (int i = 0; i < octs; ++i) {
    557             *dst++ = pack_8_to_1(src);
    558             src += 8;
    559         }
    560         if (leftOverBits > 0) {
    561             unsigned bits = 0;
    562             int shift = 7;
    563             for (int i = 0; i < leftOverBits; ++i, --shift) {
    564                 bits |= convert_8_to_1(*src++) << shift;
    565             }
    566             *dst++ = bits;
    567         }
    568         src += srcPad;
    569         dst += dstPad;
    570     }
    571 }
    572 
    573 static void generateMask(const SkMask& mask, const SkPath& path,
    574                          const SkMaskGamma::PreBlend& maskPreBlend) {
    575     SkPaint paint;
    576 
    577     int srcW = mask.fBounds.width();
    578     int srcH = mask.fBounds.height();
    579     int dstW = srcW;
    580     int dstH = srcH;
    581     int dstRB = mask.fRowBytes;
    582 
    583     SkMatrix matrix;
    584     matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft),
    585                         -SkIntToScalar(mask.fBounds.fTop));
    586 
    587     paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat);
    588     switch (mask.fFormat) {
    589         case SkMask::kBW_Format:
    590             dstRB = 0;  // signals we need a copy
    591             break;
    592         case SkMask::kA8_Format:
    593             break;
    594         case SkMask::kLCD16_Format:
    595         case SkMask::kLCD32_Format:
    596             // TODO: trigger off LCD orientation
    597             dstW = 4*dstW - 8;
    598             matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1),
    599                                 -SkIntToScalar(mask.fBounds.fTop));
    600             matrix.postScale(SkIntToScalar(4), SK_Scalar1);
    601             dstRB = 0;  // signals we need a copy
    602             break;
    603         default:
    604             SkDEBUGFAIL("unexpected mask format");
    605     }
    606 
    607     SkRasterClip clip;
    608     clip.setRect(SkIRect::MakeWH(dstW, dstH));
    609 
    610     const SkImageInfo info = SkImageInfo::MakeA8(dstW, dstH);
    611     SkBitmap bm;
    612 
    613     if (0 == dstRB) {
    614         if (!bm.allocPixels(info)) {
    615             // can't allocate offscreen, so empty the mask and return
    616             sk_bzero(mask.fImage, mask.computeImageSize());
    617             return;
    618         }
    619     } else {
    620         bm.installPixels(info, mask.fImage, dstRB);
    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