Fix error with transforming custom/large glyphs
BUG=661244
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4738
Change-Id: I9f14ca830f9de92000e751a4a99ff1eb9b01db33
Reviewed-on: https://skia-review.googlesource.com/4866
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/gm/clip_error.cpp b/gm/clip_error.cpp
new file mode 100644
index 0000000..28f7432
--- /dev/null
+++ b/gm/clip_error.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkBlurMask.h"
+#include "SkBlurMaskFilter.h"
+#include "SkCanvas.h"
+#include "SkTextBlob.h"
+
+#define WIDTH 800
+#define HEIGHT 800
+
+static void draw_text(SkCanvas* canvas, sk_sp<SkTextBlob> blob,
+ const SkPaint& paint, const SkPaint& blurPaint,
+ const SkPaint& clearPaint) {
+ canvas->save();
+ canvas->clipRect(SkRect::MakeLTRB(0, 0, 1081, 665));
+ canvas->drawRect(SkRect::MakeLTRB(0, 0, 1081, 665), clearPaint);
+ // draw as blurred to push glyph to be too large for atlas
+ canvas->drawTextBlob(blob, 0, 256, blurPaint);
+ canvas->drawTextBlob(blob, 0, 477, paint);
+ canvas->restore();
+}
+
+// This test ensures that glyphs that are too large for the atlas
+// are both translated and clipped correctly.
+class ClipErrorGM : public skiagm::GM {
+public:
+ ClipErrorGM() {}
+
+protected:
+ SkString onShortName() override { return SkString("cliperror"); }
+
+ SkISize onISize() override { return SkISize::Make(WIDTH, HEIGHT); }
+
+ void onDraw(SkCanvas* canvas) override {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ const char text[] = "hambur";
+
+ sk_tool_utils::set_portable_typeface(&paint);
+ paint.setTextSize(256);
+ paint.setAntiAlias(true);
+
+ // setup up maskfilter
+ const SkScalar kSigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(50));
+
+ SkPaint blurPaint(paint);
+ blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, kSigma));
+
+ SkTextBlobBuilder builder;
+
+ sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, 0);
+
+ sk_sp<SkTextBlob> blob(builder.make());
+
+ SkPaint clearPaint(paint);
+ clearPaint.setColor(SK_ColorWHITE);
+
+ canvas->save();
+ canvas->translate(0, 0);
+ canvas->clipRect(SkRect::MakeLTRB(0, 0, WIDTH, 256));
+ draw_text(canvas, blob, paint, blurPaint, clearPaint);
+ canvas->restore();
+
+ canvas->save();
+ canvas->translate(0, 256);
+ canvas->clipRect(SkRect::MakeLTRB(0, 256, WIDTH, 510));
+ draw_text(canvas, blob, paint, blurPaint, clearPaint);
+ canvas->restore();
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+
+DEF_GM(return new ClipErrorGM;)
diff --git a/gn/gm.gni b/gn/gm.gni
index 6a0b89f..0b11b2e 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -53,6 +53,7 @@
"$_gm/circles.cpp",
"$_gm/circulararcs.cpp",
"$_gm/circularclips.cpp",
+ "$_gm/clip_error.cpp",
"$_gm/clip_strokerect.cpp",
"$_gm/clipdrawdraw.cpp",
"$_gm/clippedbitmapshaders.cpp",
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 9c6fdf3..a160cb5 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -74,11 +74,11 @@
GrBatchTextStrike* strike,
GrGlyph* glyph,
SkGlyphCache* cache, const SkGlyph& skGlyph,
- SkScalar x, SkScalar y, SkScalar scale, bool applyVM) {
+ SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP) {
// If the glyph is too large we fall back to paths
if (glyph->fTooLargeForAtlas) {
- this->appendLargeGlyph(glyph, cache, skGlyph, x, y, scale, applyVM);
+ this->appendLargeGlyph(glyph, cache, skGlyph, x, y, scale, treatAsBMP);
return;
}
@@ -157,7 +157,7 @@
}
void GrAtlasTextBlob::appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
- SkScalar x, SkScalar y, SkScalar scale, bool applyVM) {
+ SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP) {
if (nullptr == glyph->fPath) {
const SkPath* glyphPath = cache->findPath(skGlyph);
if (!glyphPath) {
@@ -166,7 +166,7 @@
glyph->fPath = new SkPath(*glyphPath);
}
- fBigGlyphs.push_back(GrAtlasTextBlob::BigGlyph(*glyph->fPath, x, y, scale, applyVM));
+ fBigGlyphs.push_back(GrAtlasTextBlob::BigGlyph(*glyph->fPath, x, y, scale, treatAsBMP));
}
bool GrAtlasTextBlob::mustRegenerate(const SkPaint& paint,
@@ -359,12 +359,12 @@
SkScalar transX, transY;
for (int i = 0; i < fBigGlyphs.count(); i++) {
GrAtlasTextBlob::BigGlyph& bigGlyph = fBigGlyphs[i];
- calculate_translation(bigGlyph.fApplyVM, viewMatrix, x, y,
+ calculate_translation(bigGlyph.fTreatAsBMP, viewMatrix, x, y,
fInitialViewMatrix, fInitialX, fInitialY, &transX, &transY);
SkMatrix ctm;
ctm.setScale(bigGlyph.fScale, bigGlyph.fScale);
ctm.postTranslate(bigGlyph.fX + transX, bigGlyph.fY + transY);
- if (bigGlyph.fApplyVM) {
+ if (!bigGlyph.fTreatAsBMP) {
ctm.postConcat(viewMatrix);
}
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index f24147f..1bbe38e 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -164,7 +164,7 @@
GrBatchTextStrike* strike,
GrGlyph* glyph,
SkGlyphCache*, const SkGlyph& skGlyph,
- SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
+ SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP);
static size_t GetVertexStride(GrMaskFormat maskFormat) {
switch (maskFormat) {
@@ -292,7 +292,7 @@
, fTextType(0) {}
void appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph,
- SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
+ SkScalar x, SkScalar y, SkScalar scale, bool treatAsBMP);
inline void flushRun(GrRenderTargetContext* rtc, const GrPaint&, const GrClip&,
int run, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
@@ -515,17 +515,17 @@
GrBatchFontCache* cache);
struct BigGlyph {
- BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, bool applyVM)
+ BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, bool treatAsBMP)
: fPath(path)
, fScale(scale)
, fX(vx)
, fY(vy)
- , fApplyVM(applyVM) {}
+ , fTreatAsBMP(treatAsBMP) {}
SkPath fPath;
SkScalar fScale;
SkScalar fX;
SkScalar fY;
- bool fApplyVM;
+ bool fTreatAsBMP;
};
struct StrokeInfo {
diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp
index 14c4e8d..7f7dc68 100644
--- a/src/gpu/text/GrTextUtils.cpp
+++ b/src/gpu/text/GrTextUtils.cpp
@@ -145,7 +145,7 @@
r.fBottom = r.fTop + SkIntToScalar(height);
blob->appendGlyph(runIndex, r, color, *strike, glyph, cache, skGlyph,
- SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, false);
+ SkIntToScalar(vx), SkIntToScalar(vy), 1.0f, true);
}
bool GrTextUtils::CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
@@ -464,7 +464,7 @@
SkRect glyphRect = SkRect::MakeXYWH(sx, sy, width, height);
blob->appendGlyph(runIndex, glyphRect, color, *strike, glyph, glyphCache, skGlyph,
- sx - dx, sy - dy, scale, true);
+ sx - dx, sy - dy, scale, false);
return true;
}