aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkScalerContext.h2
-rw-r--r--src/fonts/SkRandomScalerContext.cpp150
-rw-r--r--src/fonts/SkRandomScalerContext.h3
-rw-r--r--src/gpu/GrAtlasTextContext.cpp6
-rw-r--r--src/gpu/GrBatchAtlas.cpp5
-rw-r--r--src/gpu/GrBatchFontCache.cpp1
-rw-r--r--tests/TextBlobCacheTest.cpp13
7 files changed, 116 insertions, 64 deletions
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index 7fa1ef5fcd..6addf736fc 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -301,6 +301,8 @@ protected:
void forceOffGenerateImageFromPath() { fGenerateImageFromPath = false; }
private:
+ friend class SkRandomScalerContext; // For debug purposes
+
// never null
SkAutoTUnref<SkTypeface> fTypeface;
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 {
diff --git a/src/fonts/SkRandomScalerContext.h b/src/fonts/SkRandomScalerContext.h
index 8ad22beff0..24b203f05c 100644
--- a/src/fonts/SkRandomScalerContext.h
+++ b/src/fonts/SkRandomScalerContext.h
@@ -18,7 +18,7 @@
class SkRandomTypeface : public SkTypeface {
public:
- SkRandomTypeface(SkTypeface* proxy, const SkPaint&);
+ SkRandomTypeface(SkTypeface* proxy, const SkPaint&, bool fakeit);
virtual ~SkRandomTypeface();
SkTypeface* proxy() const { return fProxy; }
@@ -49,6 +49,7 @@ protected:
private:
SkTypeface* fProxy;
SkPaint fPaint;
+ bool fFakeIt;
};
#endif
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 08fbf5887a..f5976392cc 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -1678,8 +1678,10 @@ public:
}
glyph = blob->fGlyphs[glyphOffset];
SkASSERT(glyph);
- SkASSERT(id == glyph->fPackedID &&
- glyph->fMaskFormat == this->maskFormat());
+ SkASSERT(id == glyph->fPackedID);
+ // We want to be able to assert this but cannot for testing purposes.
+ // once skbug:4143 has landed we can revist this assert
+ //SkASSERT(glyph->fMaskFormat == this->maskFormat());
if (!fFontCache->hasGlyph(glyph) &&
!strike->addGlyphToAtlas(batchTarget, glyph, scaler, skGlyph,
diff --git a/src/gpu/GrBatchAtlas.cpp b/src/gpu/GrBatchAtlas.cpp
index c11c32b38d..59f2428cd9 100644
--- a/src/gpu/GrBatchAtlas.cpp
+++ b/src/gpu/GrBatchAtlas.cpp
@@ -42,7 +42,10 @@ public:
// across atlas spills)
int index() const { return fIndex; }
int genID() const { return fGenID; }
- GrBatchAtlas::AtlasID id() { return fID; }
+ GrBatchAtlas::AtlasID id() {
+ SkASSERT(GrBatchAtlas::kInvalidAtlasID != fID);
+ return fID;
+ }
GrTexture* texture() const { return fTexture; }
diff --git a/src/gpu/GrBatchFontCache.cpp b/src/gpu/GrBatchFontCache.cpp
index d6ffc507e7..64d6bb1a1c 100644
--- a/src/gpu/GrBatchFontCache.cpp
+++ b/src/gpu/GrBatchFontCache.cpp
@@ -226,6 +226,7 @@ bool GrBatchTextStrike::addGlyphToAtlas(GrBatchTarget* batchTarget, GrGlyph* gly
glyph->width(), glyph->height(),
storage.get(), &glyph->fAtlasLocation);
if (success) {
+ SkASSERT(GrBatchAtlas::kInvalidAtlasID != glyph->fID);
fAtlasedGlyphs++;
}
return success;
diff --git a/tests/TextBlobCacheTest.cpp b/tests/TextBlobCacheTest.cpp
index 3cbc8a35ad..c42ef89890 100644
--- a/tests/TextBlobCacheTest.cpp
+++ b/tests/TextBlobCacheTest.cpp
@@ -14,6 +14,8 @@
#include "SkGraphics.h"
#include "SkSurface.h"
#include "SkTypeface.h"
+#include "../src/fonts/SkRandomScalerContext.h"
+#include "../src/fonts/SkGScalerContext.h"
#ifdef SK_BUILD_FOR_WIN
#include "SkTypeface_win.h"
@@ -59,7 +61,8 @@ DEF_GPUTEST(TextBlobCache, reporter, factory) {
uint32_t flags = 0;
SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
- GrContext* ctx = factory->get(GrContextFactory::kNative_GLContextType);
+ // We don't typically actually draw with this unittest
+ GrContext* ctx = factory->get(GrContextFactory::kNull_GLContextType);
SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, kN32_SkColorType, kPremul_SkAlphaType);
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info,
0, &props));
@@ -94,7 +97,10 @@ DEF_GPUTEST(TextBlobCache, reporter, factory) {
SkFontStyle fs;
set->getStyle(j, &fs, NULL);
- SkSafeUnref(paint.setTypeface(set->createTypeface(j)));
+ // We use a typeface which randomy returns unexpected mask formats to fuzz
+ SkAutoTUnref<SkTypeface> orig(set->createTypeface(j));
+ SkAutoTUnref<SkTypeface> typeface(SkNEW_ARGS(SkRandomTypeface, (orig, paint, true)));
+ paint.setTypeface(typeface);
SkTextBlobBuilder builder;
for (int aa = 0; aa < 2; aa++) {
@@ -103,6 +109,9 @@ DEF_GPUTEST(TextBlobCache, reporter, factory) {
paint.setAntiAlias(SkToBool(aa));
paint.setSubpixelText(SkToBool(subpixel));
paint.setLCDRenderText(SkToBool(lcd));
+ if (!SkToBool(lcd)) {
+ paint.setTextSize(160);
+ }
const SkTextBlobBuilder::RunBuffer& run = builder.allocRun(paint,
MAX_TOTAL_TEXT,
0, 0,