Fix error with transforming custom/large glyphs
authorJim Van Verth <jvanverth@google.com>
Wed, 16 Nov 2016 15:15:23 +0000 (10:15 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 16 Nov 2016 15:48:48 +0000 (15:48 +0000)
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>

gm/clip_error.cpp [new file with mode: 0644]
gn/gm.gni
src/gpu/text/GrAtlasTextBlob.cpp
src/gpu/text/GrAtlasTextBlob.h
src/gpu/text/GrTextUtils.cpp

diff --git a/gm/clip_error.cpp b/gm/clip_error.cpp
new file mode 100644 (file)
index 0000000..28f7432
--- /dev/null
@@ -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;)
index 6a0b89f..0b11b2e 100644 (file)
--- 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",
index 9c6fdf3..a160cb5 100644 (file)
@@ -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);
         }
 
index f24147f..1bbe38e 100644 (file)
@@ -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 {
index 14c4e8d..7f7dc68 100644 (file)
@@ -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;
 }