change SkTextToPathIter to allow continuation even when there is no path for
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 7 Aug 2012 15:53:00 +0000 (15:53 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 7 Aug 2012 15:53:00 +0000 (15:53 +0000)
the current glyph. Fixes bug in getTextPath() if there are spaces in the text.

Update gm to add space-characters, so images will have to be rebaselined.

git-svn-id: http://skia.googlecode.com/svn/trunk@4979 2bbb7eff-a529-9590-31e7-b0007b416f81

gm/getpostextpath.cpp
src/core/SkDraw.cpp
src/core/SkPaint.cpp
src/core/SkTextToPathIter.h

index f1b810c..4f32a41 100644 (file)
@@ -22,13 +22,30 @@ protected:
 
     SkISize onISize() { return skiagm::make_isize(480, 780); }
 
+    static void strokePath(SkCanvas* canvas, const SkPath& path) {
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(SK_ColorRED);
+        paint.setStyle(SkPaint::kStroke_Style);
+        canvas->drawPath(path, paint);
+    }
+
     virtual void onDraw(SkCanvas* canvas) {
-        const char* text = "Hamburgefons";
+        // explicitly add spaces, to test a prev. bug
+        const char* text = "Ham bur ge fons";
         size_t len = strlen(text);
+        SkPath path;
 
         SkPaint paint;
         paint.setAntiAlias(true);
         paint.setTextSize(SkIntToScalar(48));
+
+        canvas->translate(SkIntToScalar(10), SkIntToScalar(64));
+
+        canvas->drawText(text, len, 0, 0, paint);
+        paint.getTextPath(text, len, 0, 0, &path);
+        strokePath(canvas, path);
+        path.reset();
         
         SkAutoTArray<SkPoint>  pos(len);
         SkAutoTArray<SkScalar> widths(len);
@@ -42,19 +59,16 @@ protected:
             x += widths[i];
         }
         
-        canvas->drawPosText(text, len, &pos[0], paint);
+        canvas->translate(0, SkIntToScalar(64));
         
-        SkPath path;
-        paint.setColor(SK_ColorRED);
-        paint.setStyle(SkPaint::kStroke_Style);
+        canvas->drawPosText(text, len, &pos[0], paint);
         paint.getPosTextPath(text, len, &pos[0], &path);
-        canvas->drawPath(path, paint);
+        strokePath(canvas, path);
     }
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
 static skiagm::GM* F(void*) { return new GetPosTextPathGM; }
-
 static skiagm::GMRegistry gR(F);
 
index 83cec4b..9e8e9ef 100644 (file)
@@ -1321,13 +1321,15 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength,
     const SkPath* iterPath;
     SkScalar xpos, prevXPos = 0;
 
-    while ((iterPath = iter.next(&xpos)) != NULL) {
+    while (iter.next(&iterPath, &xpos)) {
         matrix.postTranslate(xpos - prevXPos, 0);
-        const SkPaint& pnt = iter.getPaint();
-        if (fDevice) {
-            fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
-        } else {
-            this->drawPath(*iterPath, pnt, &matrix, false);
+        if (iterPath) {
+            const SkPaint& pnt = iter.getPaint();
+            if (fDevice) {
+                fDevice->drawPath(*this, *iterPath, pnt, &matrix, false);
+            } else {
+                this->drawPath(*iterPath, pnt, &matrix, false);
+            }
         }
         prevXPos = xpos;
     }
@@ -1999,19 +2001,21 @@ void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
 
     scaledMatrix.setScale(scale, scale);
 
-    while ((iterPath = iter.next(&xpos)) != NULL) {
-        SkPath      tmp;
-        SkMatrix    m(scaledMatrix);
+    while (iter.next(&iterPath, &xpos)) {
+        if (iterPath) {
+            SkPath      tmp;
+            SkMatrix    m(scaledMatrix);
 
-        m.postTranslate(xpos + hOffset, 0);
-        if (matrix) {
-            m.postConcat(*matrix);
-        }
-        morphpath(&tmp, *iterPath, meas, m);
-        if (fDevice) {
-            fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true);
-        } else {
-            this->drawPath(tmp, iter.getPaint(), NULL, true);
+            m.postTranslate(xpos + hOffset, 0);
+            if (matrix) {
+                m.postConcat(*matrix);
+            }
+            morphpath(&tmp, *iterPath, meas, m);
+            if (fDevice) {
+                fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true);
+            } else {
+                this->drawPath(tmp, iter.getPaint(), NULL, true);
+            }
         }
     }
 }
index 5fd4288..ae5d0b2 100644 (file)
@@ -1353,9 +1353,11 @@ void SkPaint::getTextPath(const void* textData, size_t length,
 
     SkScalar        xpos;
     const SkPath*   iterPath;
-    while ((iterPath = iter.next(&xpos)) != NULL) {
+    while (iter.next(&iterPath, &xpos)) {
         matrix.postTranslate(xpos - prevXPos, 0);
-        path->addPath(*iterPath, matrix);
+        if (iterPath) {
+            path->addPath(*iterPath, matrix);
+        }
         prevXPos = xpos;
     }
 }
@@ -1379,9 +1381,11 @@ void SkPaint::getPosTextPath(const void* textData, size_t length,
 
     unsigned int    i = 0;
     const SkPath*   iterPath;
-    while ((iterPath = iter.next(NULL)) != NULL) {
+    while (iter.next(&iterPath, NULL)) {
         matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
-        path->addPath(*iterPath, matrix);
+        if (iterPath) {
+            path->addPath(*iterPath, matrix);
+        }
         prevPos = pos[i];
         i++;
     }
@@ -2202,7 +2206,7 @@ SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
 
     fText = text;
     fStop = text + length;
-    
+
     fXYIndex = paint.isVerticalText() ? 1 : 0;
 }
 
@@ -2210,21 +2214,28 @@ SkTextToPathIter::~SkTextToPathIter() {
     SkGlyphCache::AttachCache(fCache);
 }
 
-const SkPath* SkTextToPathIter::next(SkScalar* xpos) {
-    while (fText < fStop) {
+bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) {
+    if (fText < fStop) {
         const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
 
         fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
         fPrevAdvance = advance(glyph, fXYIndex);   // + fPaint.getTextTracking();
 
         if (glyph.fWidth) {
-            if (xpos) {
-                *xpos = fXPos;
+            if (path) {
+                *path = fCache->findPath(glyph);
+            }
+        } else {
+            if (path) {
+                *path = NULL;
             }
-            return fCache->findPath(glyph);
         }
+        if (xpos) {
+            *xpos = fXPos;
+        }
+        return true;
     }
-    return NULL;
+    return false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 0d8c4b2..73f27ed 100644 (file)
@@ -22,7 +22,15 @@ public:
     const SkPaint&  getPaint() const { return fPaint; }
     SkScalar        getPathScale() const { return fScale; }
 
-    const SkPath*   next(SkScalar* xpos);   //!< returns nil when there are no more paths
+    struct Rec {
+        const SkPath*   fPath;  // may be null for "whitespace" glyphs
+        SkScalar        fXPos;
+    };
+
+    /**
+     *  Returns false when all of the text has been consumed
+     */
+    bool next(const SkPath** path, SkScalar* xpos);
 
 private:
     SkGlyphCache*   fCache;