aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/textblobrandomfont.cpp85
-rw-r--r--src/core/SkScalerContext.cpp15
-rw-r--r--tools/fonts/SkRandomScalerContext.cpp160
3 files changed, 120 insertions, 140 deletions
diff --git a/gm/textblobrandomfont.cpp b/gm/textblobrandomfont.cpp
index 2e6468a6fc..4aad888dbc 100644
--- a/gm/textblobrandomfont.cpp
+++ b/gm/textblobrandomfont.cpp
@@ -37,19 +37,23 @@ protected:
// make textbloben
SkPaint paint;
paint.setTextSize(32);
+ paint.setAntiAlias(true);
paint.setLCDRenderText(true);
// Setup our random scaler context
- sk_sp<SkTypeface> orig(sk_tool_utils::create_portable_typeface(
- "sans-serif", SkFontStyle::Bold()));
- if (nullptr == orig) {
- orig = SkTypeface::MakeDefault();
+ auto typeface = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Bold());
+ if (!typeface) {
+ typeface = SkTypeface::MakeDefault();
}
- paint.setTypeface(sk_make_sp<SkRandomTypeface>(orig, paint, false));
+ paint.setColor(SK_ColorMAGENTA);
+ paint.setTypeface(sk_make_sp<SkRandomTypeface>(std::move(typeface), paint, false));
+ SkScalar y = 0;
SkRect bounds;
paint.measureText(text, strlen(text), &bounds);
- sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0);
+ y -= bounds.fTop;
+ sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, y);
+ y += bounds.fBottom;
// A8
const char* bigtext1 = "The quick brown fox";
@@ -58,20 +62,23 @@ protected:
paint.setSubpixelText(false);
paint.setLCDRenderText(false);
paint.measureText(bigtext1, strlen(bigtext1), &bounds);
- SkScalar offset = bounds.height();
- sk_tool_utils::add_to_text_blob(&builder, bigtext1, paint, 0, offset);
+ y -= bounds.fTop;
+ sk_tool_utils::add_to_text_blob(&builder, bigtext1, paint, 0, y);
+ y += bounds.fBottom;
paint.measureText(bigtext2, strlen(bigtext2), &bounds);
- offset += bounds.height();
- sk_tool_utils::add_to_text_blob(&builder, bigtext2, paint, 0, offset);
+ y -= bounds.fTop;
+ sk_tool_utils::add_to_text_blob(&builder, bigtext2, paint, 0, y);
+ y += bounds.fBottom;
// color emoji
if (sk_sp<SkTypeface> origEmoji = sk_tool_utils::emoji_typeface()) {
+ paint.setTypeface(sk_make_sp<SkRandomTypeface>(origEmoji, paint, false));
const char* emojiText = sk_tool_utils::emoji_sample_text();
paint.measureText(emojiText, strlen(emojiText), &bounds);
- offset += bounds.height();
- paint.setTypeface(sk_make_sp<SkRandomTypeface>(origEmoji, paint, false));
- sk_tool_utils::add_to_text_blob(&builder, emojiText, paint, 0, offset);
+ y -= bounds.fTop;
+ sk_tool_utils::add_to_text_blob(&builder, emojiText, paint, 0, y);
+ y += bounds.fBottom;
}
// build
@@ -88,6 +95,8 @@ protected:
void onDraw(SkCanvas* canvas) override {
// This GM exists to test a specific feature of the GPU backend.
+ // This GM uses sk_tool_utils::makeSurface which doesn't work well with vias.
+ // This GM uses SkRandomTypeface which doesn't work well with serialization.
if (nullptr == canvas->getGrContext()) {
skiagm::GM::DrawGpuOnlyMessage(canvas);
return;
@@ -100,37 +109,43 @@ protected:
canvas->imageInfo().refColorSpace());
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
auto surface(sk_tool_utils::makeSurface(canvas, info, &props));
- if (surface) {
+ if (!surface) {
+ const char* text = "This test requires a surface";
+ size_t len = strlen(text);
SkPaint paint;
- paint.setAntiAlias(true);
+ canvas->drawText(text, len, 10, 100, paint);
+ return;
+ }
+
+ SkPaint paint;
+ paint.setAntiAlias(true);
+
+ SkCanvas* c = surface->getCanvas();
- SkCanvas* c = surface->getCanvas();
+ SkScalar stride = SkScalarCeilToScalar(fBlob->bounds().height());
+ SkScalar yOffset = 5;
+ for (int i = 0; i < 1; i++) {
+ // fiddle the canvas to force regen of textblobs
+ canvas->rotate(i % 2 ? 0.0f : -0.05f);
- int stride = SkScalarCeilToInt(fBlob->bounds().height());
- int yOffset = stride / 8;
- for (int i = 0; i < 1; i++) {
- // fiddle the canvas to force regen of textblobs
- canvas->rotate(i % 2 ? 0.0f : -0.05f);
- canvas->drawTextBlob(fBlob, 10.0f, SkIntToScalar(yOffset), paint);
- yOffset += stride;
+ canvas->drawTextBlob(fBlob, 10, yOffset, paint);
+ yOffset += stride;
- // This will draw as black boxes
- c->drawTextBlob(fBlob, 10, SkIntToScalar(yOffset), paint);
+ // this will test lcd masks when not requested
+ // on cpu this currently causes unspecified behavior, so avoid until it is fixed
+ if (canvas->getGrContext()) {
+ c->drawTextBlob(fBlob, 10, yOffset, paint);
surface->draw(canvas, 0, 0, nullptr);
+ }
+ yOffset += stride;
- // free gpu resources and verify
- yOffset += stride;
+ // free gpu resources and verify
+ if (canvas->getGrContext()) {
canvas->getGrContext()->freeGpuResources();
- canvas->drawTextBlob(fBlob, 10, SkIntToScalar(yOffset), paint);
-
- yOffset += stride;
}
- } else {
- const char* text = "This test requires a surface";
- size_t len = strlen(text);
- SkPaint paint;
- canvas->drawText(text, len, 10, 100, paint);
+ canvas->drawTextBlob(fBlob, 10, yOffset, paint);
+ yOffset += stride;
}
}
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index 7ad3a030bb..232129c478 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -76,13 +76,22 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
bool generatingImageFromPath = fGenerateImageFromPath;
if (!generatingImageFromPath) {
generateMetrics(glyph);
+ if (glyph->fMaskFormat == MASK_FORMAT_UNKNOWN) {
+ glyph->fMaskFormat = fRec.fMaskFormat;
+ }
} else {
SkPath devPath;
generatingImageFromPath = this->internalGetPath(glyph->getPackedID(), &devPath);
if (!generatingImageFromPath) {
generateMetrics(glyph);
+ if (glyph->fMaskFormat == MASK_FORMAT_UNKNOWN) {
+ glyph->fMaskFormat = fRec.fMaskFormat;
+ }
} else {
generateAdvance(glyph);
+ if (glyph->fMaskFormat == MASK_FORMAT_UNKNOWN) {
+ glyph->fMaskFormat = fRec.fMaskFormat;
+ }
const SkIRect ir = devPath.getBounds().roundOut();
if (ir.isEmpty() || !SkRectPriv::Is16Bit(ir)) {
@@ -94,7 +103,7 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
glyph->fHeight = SkToU16(ir.height());
if (glyph->fWidth > 0) {
- switch (fRec.fMaskFormat) {
+ switch (glyph->fMaskFormat) {
case SkMask::kLCD16_Format:
glyph->fWidth += 2;
glyph->fLeft -= 1;
@@ -116,10 +125,6 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
return;
}
- if (SkMask::kARGB32_Format != glyph->fMaskFormat) {
- glyph->fMaskFormat = fRec.fMaskFormat;
- }
-
// If we are going to create the mask, then we cannot keep the color
if (generatingImageFromPath && SkMask::kARGB32_Format == glyph->fMaskFormat) {
glyph->fMaskFormat = SkMask::kA8_Format;
diff --git a/tools/fonts/SkRandomScalerContext.cpp b/tools/fonts/SkRandomScalerContext.cpp
index feeca48073..2d472129a1 100644
--- a/tools/fonts/SkRandomScalerContext.cpp
+++ b/tools/fonts/SkRandomScalerContext.cpp
@@ -43,8 +43,10 @@ SkRandomScalerContext::SkRandomScalerContext(sk_sp<SkRandomTypeface> face,
const SkDescriptor* desc,
bool fakeIt)
: SkScalerContext(std::move(face), effects, desc)
- , fFakeIt(fakeIt) {
- fProxy = this->getRandomTypeface()->proxy()->createScalerContext(effects, desc);
+ , fProxy(getRandomTypeface()->proxy()->createScalerContext(SkScalerContextEffects(), desc))
+ , fFakeIt(fakeIt)
+{
+ fProxy->forceGenerateImageFromPath();
}
unsigned SkRandomScalerContext::generateGlyphCount() {
@@ -61,118 +63,77 @@ void SkRandomScalerContext::generateAdvance(SkGlyph* glyph) {
void SkRandomScalerContext::generateMetrics(SkGlyph* glyph) {
// Here we will change the mask format of the glyph
- // NOTE this is being overridden by the base class
- SkMask::Format format = SkMask::kARGB32_Format; // init to handle defective compilers
+ // NOTE: this may be overridden by the base class (e.g. if a mask filter is applied).
switch (glyph->getGlyphID() % 4) {
- case 0:
- format = SkMask::kLCD16_Format;
- break;
- case 1:
- format = SkMask::kA8_Format;
- break;
- case 2:
- format = SkMask::kARGB32_Format;
- break;
- case 3:
- format = SkMask::kBW_Format;
- break;
+ case 0: glyph->fMaskFormat = SkMask::kLCD16_Format; break;
+ case 1: glyph->fMaskFormat = SkMask::kA8_Format; break;
+ case 2: glyph->fMaskFormat = SkMask::kARGB32_Format; break;
+ case 3: glyph->fMaskFormat = SkMask::kBW_Format; break;
}
fProxy->getMetrics(glyph);
- glyph->fMaskFormat = format;
- if (fFakeIt) {
+ if (fFakeIt || (glyph->getGlyphID() % 4) != 2) {
return;
}
- if (SkMask::kARGB32_Format == format) {
- SkPath path;
- sk_ignore_unused_variable(fProxy->getPath(glyph->getPackedID(), &path));
-
- SkRect storage;
- const SkPaint& paint = this->getRandomTypeface()->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;
- this->internalGetPath(glyph->getPackedID(), &devPath);
-
- // just use devPath
- const SkIRect ir = devPath.getBounds().roundOut();
-
- if (ir.isEmpty() || !SkRectPriv::Is16Bit(ir)) {
- 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;
- }
- }
+
+ SkPath path;
+ if (!fProxy->getPath(glyph->getPackedID(), &path)) {
+ return;
}
+ glyph->fMaskFormat = SkMask::kARGB32_Format;
+
+ SkRect storage;
+ const SkPaint& paint = this->getRandomTypeface()->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();
}
void SkRandomScalerContext::generateImage(const SkGlyph& glyph) {
+ // TODO: can force down but not up
+ /*
SkMask::Format format = (SkMask::Format)glyph.fMaskFormat;
switch (glyph.getGlyphID() % 4) {
- case 0:
- format = SkMask::kLCD16_Format;
- break;
- case 1:
- format = SkMask::kA8_Format;
- break;
- case 2:
- format = SkMask::kARGB32_Format;
- break;
- case 3:
- format = SkMask::kBW_Format;
- break;
+ case 0: format = SkMask::kLCD16_Format; break;
+ case 1: format = SkMask::kA8_Format; break;
+ case 2: format = SkMask::kARGB32_Format; break;
+ case 3: format = SkMask::kBW_Format; break;
}
const_cast<SkGlyph&>(glyph).fMaskFormat = format;
+ */
- // 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 (!fFakeIt) {
- if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
- SkPath path;
- sk_ignore_unused_variable(fProxy->getPath(glyph.getPackedID(), &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.drawPath(path, this->getRandomTypeface()->paint());
- } else {
- fProxy->forceGenerateImageFromPath();
- fProxy->getImage(glyph);
- fProxy->forceOffGenerateImageFromPath();
- }
- } else {
+ if (fFakeIt) {
sk_bzero(glyph.fImage, glyph.computeImageSize());
+ return;
+ }
+
+ if (SkMask::kARGB32_Format != glyph.fMaskFormat) {
+ fProxy->getImage(glyph);
+ return;
+ }
+
+ // If the format is ARGB, just draw the glyph from path.
+ SkPath path;
+ if (!fProxy->getPath(glyph.getPackedID(), &path)) {
+ fProxy->getImage(glyph);
+ return;
}
+
+ 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.drawPath(path, this->getRandomTypeface()->paint());
}
bool SkRandomScalerContext::generatePath(SkGlyphID glyph, SkPath* path) {
@@ -185,8 +146,6 @@ void SkRandomScalerContext::generateFontMetrics(SkPaint::FontMetrics* metrics) {
///////////////////////////////////////////////////////////////////////////////
-#include "SkTypefaceCache.h"
-
SkRandomTypeface::SkRandomTypeface(sk_sp<SkTypeface> proxy, const SkPaint& paint, bool fakeIt)
: SkTypeface(proxy->fontStyle(), false)
, fProxy(std::move(proxy))
@@ -213,8 +172,9 @@ SkStreamAsset* SkRandomTypeface::onOpenStream(int* ttcIndex) const {
return fProxy->openStream(ttcIndex);
}
-void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
- bool* isLocal) const {
+void SkRandomTypeface::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+ // TODO: anything that uses this typeface isn't correctly serializable, since this typeface
+ // cannot be deserialized.
fProxy->getFontDescriptor(desc, isLocal);
}