Index: src/core/SkScalerContext.cpp |
=================================================================== |
--- src/core/SkScalerContext.cpp (revision 8931) |
+++ src/core/SkScalerContext.cpp (working copy) |
@@ -337,6 +337,12 @@ |
glyph->fMaskFormat = fRec.fMaskFormat; |
} |
+ // If we are going to create the mask, then we cannot keep the color |
+ if ((fGenerateImageFromPath || fMaskFilter) && |
+ SkMask::kARGB32_Format == glyph->fMaskFormat) { |
+ glyph->fMaskFormat = SkMask::kA8_Format; |
+ } |
+ |
if (fMaskFilter) { |
SkMask src, dst; |
SkMatrix matrix; |
@@ -515,10 +521,40 @@ |
} |
} |
+static void extract_alpha(const SkMask& dst, |
+ const SkPMColor* srcRow, size_t srcRB) { |
+ int width = dst.fBounds.width(); |
+ int height = dst.fBounds.height(); |
+ int dstRB = dst.fRowBytes; |
+ uint8_t* dstRow = dst.fImage; |
+ |
+ for (int y = 0; y < height; ++y) { |
+ for (int x = 0; x < width; ++x) { |
+ dstRow[x] = SkGetPackedA32(srcRow[x]); |
+ } |
+ // zero any padding on each row |
+ for (int x = width; x < dstRB; ++x) { |
+ dstRow[x] = 0; |
+ } |
+ dstRow += dstRB; |
+ srcRow = (const SkPMColor*)((const char*)srcRow + srcRB); |
+ } |
+} |
+ |
void SkScalerContext::getImage(const SkGlyph& origGlyph) { |
const SkGlyph* glyph = &origGlyph; |
SkGlyph tmpGlyph; |
+ // in case we need to call generateImage on a mask-format that is different |
+ // (i.e. larger) than what our caller allocated by looking at origGlyph. |
+ SkAutoMalloc tmpGlyphImageStorage; |
+ |
+ // If we are going to draw-from-path, then we cannot generate color, since |
+ // the path only makes a mask. This case should have been caught up in |
+ // generateMetrics(). |
+ SkASSERT(!fGenerateImageFromPath || |
+ SkMask::kARGB32_Format != origGlyph.fMaskFormat); |
+ |
if (fMaskFilter) { // restore the prefilter bounds |
tmpGlyph.init(origGlyph.fID); |
@@ -528,11 +564,16 @@ |
this->getMetrics(&tmpGlyph); |
fMaskFilter = mf; // restore |
- tmpGlyph.fImage = origGlyph.fImage; |
- |
// we need the prefilter bounds to be <= filter bounds |
SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); |
SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); |
+ |
+ if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { |
+ tmpGlyph.fImage = origGlyph.fImage; |
+ } else { |
+ tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); |
+ tmpGlyph.fImage = tmpGlyphImageStorage.get(); |
+ } |
glyph = &tmpGlyph; |
} |
@@ -557,6 +598,7 @@ |
applyLUTToA8Mask(mask, fPreBlend.fG); |
} |
} else { |
+ SkASSERT(SkMask::kARGB32_Format != mask.fFormat); |
generateMask(mask, devPath, fPreBlend); |
} |
} else { |
@@ -569,7 +611,21 @@ |
// the src glyph image shouldn't be 3D |
SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); |
+ |
+ SkAutoSMalloc<32*32> a8storage; |
glyph->toMask(&srcM); |
+ if (SkMask::kARGB32_Format == srcM.fFormat) { |
+ // now we need to extract the alpha-channel from the glyph's image |
+ // and copy it into a temp buffer, and then point srcM at that temp. |
+ srcM.fFormat = SkMask::kA8_Format; |
+ srcM.fRowBytes = SkAlign4(srcM.fBounds.width()); |
+ size_t size = srcM.computeImageSize(); |
+ a8storage.reset(size); |
+ srcM.fImage = (uint8_t*)a8storage.get(); |
+ extract_alpha(srcM, |
+ (const SkPMColor*)glyph->fImage, glyph->rowBytes()); |
+ } |
+ |
fRec.getMatrixFrom2x2(&matrix); |
if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) { |