aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2018-03-05 17:20:15 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-06 16:07:56 +0000
commitba8feb56c301563186852023eb531bb2076eaf9a (patch)
treecf5260aba615ab3f0695bf1458446a19413d4aed
parent9d5c6743f614973bd241cde451ad2d1d6c31525b (diff)
Draw glyphs from paths if they have an empty path.
This distuguishes between glyphs which do not have a path and glyphs which have a path but that path resolves to the empty path. BUG=chromium:816763 Change-Id: Id6c7dd66cdad3868bf3fe15bcb6e5e6f2ca82405 Reviewed-on: https://skia-review.googlesource.com/112484 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
-rw-r--r--src/core/SkScalerContext.cpp15
-rw-r--r--src/core/SkScalerContext.h3
-rw-r--r--tests/DrawTextTest.cpp51
3 files changed, 61 insertions, 8 deletions
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index e0bded01ad..0f1acf3832 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -128,8 +128,7 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
SkPath devPath, fillPath;
SkMatrix fillToDevMatrix;
- this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix);
- if (fillPath.isEmpty()) {
+ if (!this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix)) {
generatingImageFromPath = false;
} else {
// just use devPath
@@ -465,10 +464,8 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) {
SkMatrix fillToDevMatrix;
SkMask mask;
- this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix);
glyph->toMask(&mask);
-
- if (fillPath.isEmpty()) {
+ if (!this->internalGetPath(glyph->getPackedID(), &fillPath, &devPath, &fillToDevMatrix)) {
generateImage(*glyph);
} else {
SkASSERT(SkMask::kARGB32_Format != origGlyph.fMaskFormat);
@@ -548,10 +545,13 @@ SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
///////////////////////////////////////////////////////////////////////////////
-void SkScalerContext::internalGetPath(SkPackedGlyphID glyphID, SkPath* fillPath,
+bool SkScalerContext::internalGetPath(SkPackedGlyphID glyphID, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix) {
SkPath path;
generatePath(glyphID.code(), &path);
+ if (path.isEmpty()) {
+ return false;
+ }
if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
SkFixed dx = glyphID.getSubXFixed();
@@ -572,7 +572,7 @@ void SkScalerContext::internalGetPath(SkPackedGlyphID glyphID, SkPath* fillPath,
fRec.getMatrixFrom2x2(&matrix);
if (!matrix.invert(&inverse)) {
// assume fillPath and devPath are already empty.
- return;
+ return true;
}
path.transform(inverse, &localPath);
// now localPath is only affected by the paint settings, and not the canvas matrix
@@ -636,6 +636,7 @@ void SkScalerContext::internalGetPath(SkPackedGlyphID glyphID, SkPath* fillPath,
if (fillPath) {
fillPath->updateBoundsCache();
}
+ return true;
}
diff --git a/src/core/SkScalerContext.h b/src/core/SkScalerContext.h
index 086296d2e4..21c05dc808 100644
--- a/src/core/SkScalerContext.h
+++ b/src/core/SkScalerContext.h
@@ -412,7 +412,8 @@ private:
// calling generateImage.
bool fGenerateImageFromPath;
- void internalGetPath(SkPackedGlyphID id, SkPath* fillPath,
+ /** Returns false if the glyph has no path at all. */
+ bool internalGetPath(SkPackedGlyphID id, SkPath* fillPath,
SkPath* devPath, SkMatrix* fillToDevMatrix);
// SkMaskGamma::PreBlend converts linear masks to gamma correcting masks.
diff --git a/tests/DrawTextTest.cpp b/tests/DrawTextTest.cpp
index 0134d0585d..6ec0a65b52 100644
--- a/tests/DrawTextTest.cpp
+++ b/tests/DrawTextTest.cpp
@@ -8,12 +8,18 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
+#include "SkDashPathEffect.h"
+#include "SkMatrix.h"
#include "SkPaint.h"
+#include "SkPathEffect.h"
#include "SkPoint.h"
#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkScalar.h"
#include "SkSurface.h"
#include "SkTypes.h"
#include "Test.h"
+
#include <math.h>
static const SkColor bgColor = SK_ColorWHITE;
@@ -111,6 +117,51 @@ DEF_TEST(DrawText, reporter) {
}
}
+/** Test that drawing glyphs with empty paths is different from drawing glyphs without paths. */
+DEF_TEST(DrawText_dashout, reporter) {
+ SkIRect size = SkIRect::MakeWH(64, 64);
+
+ SkBitmap drawTextBitmap;
+ create(&drawTextBitmap, size);
+ SkCanvas drawTextCanvas(drawTextBitmap);
+
+ SkBitmap drawDashedTextBitmap;
+ create(&drawDashedTextBitmap, size);
+ SkCanvas drawDashedTextCanvas(drawDashedTextBitmap);
+
+ SkBitmap emptyBitmap;
+ create(&emptyBitmap, size);
+ SkCanvas emptyCanvas(emptyBitmap);
+
+ SkPoint point = SkPoint::Make(25.0f, 25.0f);
+ SkPaint paint;
+ paint.setColor(SK_ColorGRAY);
+ paint.setTextSize(SkIntToScalar(20));
+ paint.setAntiAlias(true);
+ paint.setSubpixelText(true);
+ paint.setLCDRenderText(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+
+ // Draw a stroked "A" without a dash which will draw something.
+ drawBG(&drawTextCanvas);
+ drawTextCanvas.drawText("A", 1, point.fX, point.fY, paint);
+
+ // Draw an "A" but with a dash which will never draw anything.
+ paint.setStrokeWidth(2);
+ constexpr SkScalar bigInterval = 10000;
+ static constexpr SkScalar intervals[] = { 1, bigInterval };
+ paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 2));
+
+ drawBG(&drawDashedTextCanvas);
+ drawDashedTextCanvas.drawText("A", 1, point.fX, point.fY, paint);
+
+ // Draw nothing.
+ drawBG(&emptyCanvas);
+
+ REPORTER_ASSERT(reporter, !compare(drawTextBitmap, size, emptyBitmap, size));
+ REPORTER_ASSERT(reporter, compare(drawDashedTextBitmap, size, emptyBitmap, size));
+}
+
// Test drawing text at some unusual coordinates.
// We measure success by not crashing or asserting.
DEF_TEST(DrawText_weirdCoordinates, r) {