change SkTextToPathIter to allow continuation even when there is no path for
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
diff --git a/gm/getpostextpath.cpp b/gm/getpostextpath.cpp
index f1b810c..4f32a41 100644
--- a/gm/getpostextpath.cpp
+++ b/gm/getpostextpath.cpp
@@ -22,13 +22,30 @@
 
     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 @@
             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);
 
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 83cec4b..9e8e9ef 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1321,13 +1321,15 @@
     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 @@
 
     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);
+            }
         }
     }
 }
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 5fd4288..ae5d0b2 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1353,9 +1353,11 @@
 
     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 @@
 
     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 @@
 
     fText = text;
     fStop = text + length;
-    
+
     fXYIndex = paint.isVerticalText() ? 1 : 0;
 }
 
@@ -2210,21 +2214,28 @@
     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);
             }
-            return fCache->findPath(glyph);
+        } else {
+            if (path) {
+                *path = NULL;
+            }
         }
+        if (xpos) {
+            *xpos = fXPos;
+        }
+        return true;
     }
-    return NULL;
+    return false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkTextToPathIter.h b/src/core/SkTextToPathIter.h
index 0d8c4b2..73f27ed 100644
--- a/src/core/SkTextToPathIter.h
+++ b/src/core/SkTextToPathIter.h
@@ -22,7 +22,15 @@
     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;