diff options
Diffstat (limited to 'src/fonts/SkRandomScalerContext.cpp')
-rw-r--r-- | src/fonts/SkRandomScalerContext.cpp | 150 |
1 files changed, 92 insertions, 58 deletions
diff --git a/src/fonts/SkRandomScalerContext.cpp b/src/fonts/SkRandomScalerContext.cpp index 2bfa289937..9a68e50376 100644 --- a/src/fonts/SkRandomScalerContext.cpp +++ b/src/fonts/SkRandomScalerContext.cpp @@ -9,10 +9,11 @@ #include "SkGlyph.h" #include "SkPath.h" #include "SkCanvas.h" +#include "SkRasterizer.h" class SkRandomScalerContext : public SkScalerContext { public: - SkRandomScalerContext(SkRandomTypeface*, const SkDescriptor*); + SkRandomScalerContext(SkRandomTypeface*, const SkDescriptor*, bool fFakeIt); virtual ~SkRandomScalerContext(); protected: @@ -28,15 +29,18 @@ private: SkRandomTypeface* fFace; SkScalerContext* fProxy; SkMatrix fMatrix; + bool fFakeIt; }; #define STD_SIZE 1 #include "SkDescriptor.h" -SkRandomScalerContext::SkRandomScalerContext(SkRandomTypeface* face, const SkDescriptor* desc) +SkRandomScalerContext::SkRandomScalerContext(SkRandomTypeface* face, const SkDescriptor* desc, + bool fakeIt) : SkScalerContext(face, desc) - , fFace(face) { + , fFace(face) + , fFakeIt(fakeIt) { size_t descSize = SkDescriptor::ComputeOverhead(1) + sizeof(SkScalerContext::Rec); SkAutoDescriptor ad(descSize); SkDescriptor* newDesc = ad.getDesc(); @@ -84,34 +88,10 @@ void SkRandomScalerContext::generateAdvance(SkGlyph* glyph) { } void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) { - fProxy->getAdvance(glyph); - - SkVector advance; - fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), - SkFixedToScalar(glyph->fAdvanceY), &advance); - glyph->fAdvanceX = SkScalarToFixed(advance.fX); - glyph->fAdvanceY = SkScalarToFixed(advance.fY); - - SkPath path; - fProxy->getPath(*glyph, &path); - path.transform(fMatrix); - - SkRect storage; - const SkPaint& paint = fFace->paint(); - const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), - &storage, - SkPaint::kFill_Style); - SkIRect ibounds; - newBounds.roundOut(&ibounds); - glyph->fLeft = ibounds.fLeft; - glyph->fTop = ibounds.fTop; - glyph->fWidth = ibounds.width(); - glyph->fHeight = ibounds.height(); - // Here we will change the mask format of the glyph // NOTE this is being overridden by the base class SkMask::Format format; - switch (glyph->getGlyphID() % 6) { + switch (glyph->getGlyphID() % 3) { case 0: format = SkMask::kLCD16_Format; break; @@ -121,28 +101,77 @@ void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) { case 2: format = SkMask::kARGB32_Format; break; - default: - // we will fiddle with these in generate image - format = (SkMask::Format)MASK_FORMAT_UNKNOWN; } glyph->fMaskFormat = format; + fProxy->getMetrics(glyph); + + if (SkMask::kARGB32_Format == format) { + SkVector advance; + fMatrix.mapXY(SkFixedToScalar(glyph->fAdvanceX), + SkFixedToScalar(glyph->fAdvanceY), &advance); + glyph->fAdvanceX = SkScalarToFixed(advance.fX); + glyph->fAdvanceY = SkScalarToFixed(advance.fY); + + SkPath path; + fProxy->getPath(*glyph, &path); + path.transform(fMatrix); + + SkRect storage; + const SkPaint& paint = fFace->paint(); + const SkRect& newBounds = paint.doComputeFastBounds(path.getBounds(), + &storage, + SkPaint::kFill_Style); + SkIRect ibounds; + newBounds.roundOut(&ibounds); + glyph->fLeft = ibounds.fLeft; + glyph->fTop = ibounds.fTop; + glyph->fWidth = ibounds.width(); + glyph->fHeight = ibounds.height(); + } else { + SkPath devPath, fillPath; + SkMatrix fillToDevMatrix; + + this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); + + // just use devPath + const SkIRect ir = devPath.getBounds().roundOut(); + + if (ir.isEmpty() || !ir.is16Bit()) { + glyph->fLeft = 0; + glyph->fTop = 0; + glyph->fWidth = 0; + glyph->fHeight = 0; + return; + } + glyph->fLeft = ir.fLeft; + glyph->fTop = ir.fTop; + glyph->fWidth = SkToU16(ir.width()); + glyph->fHeight = SkToU16(ir.height()); + + if (glyph->fWidth > 0) { + switch (glyph->fMaskFormat) { + case SkMask::kLCD16_Format: + glyph->fWidth += 2; + glyph->fLeft -= 1; + break; + default: + break; + } + } + } } void SkRandomScalerContext::generateImage(const SkGlyph& glyph) { SkMask::Format format = (SkMask::Format)glyph.fMaskFormat; - switch (glyph.getGlyphID() % 6) { + switch (glyph.getGlyphID() % 3) { case 0: - case 1: - case 2: - break; - case 3: format = SkMask::kLCD16_Format; break; - case 4: + case 1: format = SkMask::kA8_Format; break; - case 5: + case 2: format = SkMask::kARGB32_Format; break; } @@ -150,24 +179,28 @@ void SkRandomScalerContext::generateImage(const SkGlyph& glyph) { // if the format is ARGB, we just draw the glyph from path ourselves. Otherwise, we force // our proxy context to generate the image from paths. - if (SkMask::kARGB32_Format == glyph.fMaskFormat) { - SkPath path; - fProxy->getPath(glyph, &path); - - SkBitmap bm; - bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), - glyph.fImage, glyph.rowBytes()); - bm.eraseColor(0); - - SkCanvas canvas(bm); - canvas.translate(-SkIntToScalar(glyph.fLeft), - -SkIntToScalar(glyph.fTop)); - canvas.concat(fMatrix); - canvas.drawPath(path, fFace->paint()); + if (!fFakeIt) { + if (SkMask::kARGB32_Format == glyph.fMaskFormat) { + SkPath path; + fProxy->getPath(glyph, &path); + + SkBitmap bm; + bm.installPixels(SkImageInfo::MakeN32Premul(glyph.fWidth, glyph.fHeight), + glyph.fImage, glyph.rowBytes()); + bm.eraseColor(0); + + SkCanvas canvas(bm); + canvas.translate(-SkIntToScalar(glyph.fLeft), + -SkIntToScalar(glyph.fTop)); + canvas.concat(fMatrix); + canvas.drawPath(path, fFace->paint()); + } else { + fProxy->forceGenerateImageFromPath(); + fProxy->getImage(glyph); + fProxy->forceOffGenerateImageFromPath(); + } } else { - this->forceGenerateImageFromPath(); - fProxy->getImage(glyph); - this->forceOffGenerateImageFromPath(); + sk_bzero(glyph.fImage, glyph.computeImageSize()); } } @@ -196,10 +229,11 @@ void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) { #include "SkTypefaceCache.h" -SkRandomTypeface::SkRandomTypeface(SkTypeface* proxy, const SkPaint& paint) +SkRandomTypeface::SkRandomTypeface(SkTypeface* proxy, const SkPaint& paint, bool fakeIt) : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false) , fProxy(SkRef(proxy)) - , fPaint(paint) {} + , fPaint(paint) + , fFakeIt(fakeIt) {} SkRandomTypeface::~SkRandomTypeface() { fProxy->unref(); @@ -207,7 +241,7 @@ SkRandomTypeface::~SkRandomTypeface() { SkScalerContext* SkRandomTypeface::onCreateScalerContext( const SkDescriptor* desc) const { - return SkNEW_ARGS(SkRandomScalerContext, (const_cast<SkRandomTypeface*>(this), desc)); + return SkNEW_ARGS(SkRandomScalerContext, (const_cast<SkRandomTypeface*>(this), desc, fFakeIt)); } void SkRandomTypeface::onFilterRec(SkScalerContextRec* rec) const { |