From 08576e618883c3f8eb2cdf425e2f2bd7842f3f2e Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Wed, 16 Nov 2016 10:15:23 -0500 Subject: [PATCH] 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 Reviewed-by: Brian Salomon Commit-Queue: Jim Van Verth --- gm/clip_error.cpp | 83 ++++++++++++++++++++++++++++++++++++++++ gn/gm.gni | 1 + src/gpu/text/GrAtlasTextBlob.cpp | 12 +++--- src/gpu/text/GrAtlasTextBlob.h | 10 ++--- src/gpu/text/GrTextUtils.cpp | 4 +- 5 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 gm/clip_error.cpp 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 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 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_sources = [ "$_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 @@ void GrAtlasTextBlob::appendGlyph(int runIndex, 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::appendGlyph(int runIndex, } 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 @@ void GrAtlasTextBlob::appendLargeGlyph(GrGlyph* glyph, SkGlyphCache* cache, cons 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 @@ void GrAtlasTextBlob::flushBigGlyphs(GrContext* context, GrRenderTargetContext* 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 @@ public: 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 @@ private: , 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 @@ private: 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 @@ void GrTextUtils::BmpAppendGlyph(GrAtlasTextBlob* blob, int runIndex, 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 @@ bool GrTextUtils::DfAppendGlyph(GrAtlasTextBlob* blob, int runIndex, GrBatchFont 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; } -- 2.7.4