Bug 761890 (was 746883); changes to the Skia library. r=gw280
authorNicholas Cameron <ncameron@mozilla.com>
Wed, 16 May 2012 17:42:07 +1200
changeset 101480 c2539605ff4957b9cc6b3210990273da44885978
parent 101479 a24de192b216ea4c1688cb5f8434cc42407f828f
child 101481 856142f345119d90be2e73e127303e5a8c854bcf
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw280
bugs761890, 746883
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 761890 (was 746883); changes to the Skia library. r=gw280
gfx/skia/include/core/SkDraw.h
gfx/skia/src/core/SkPaint.cpp
--- a/gfx/skia/include/core/SkDraw.h
+++ b/gfx/skia/include/core/SkDraw.h
@@ -125,23 +125,24 @@ public:
 #endif
 };
 
 class SkGlyphCache;
 
 class SkTextToPathIter {
 public:
     SkTextToPathIter(const char text[], size_t length, const SkPaint& paint,
-                     bool applyStrokeAndPathEffects);
+                     bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true);
     ~SkTextToPathIter();
 
     const SkPaint&  getPaint() const { return fPaint; }
     SkScalar        getPathScale() const { return fScale; }
 
     const SkPath*   next(SkScalar* xpos);   //!< returns nil when there are no more paths
+    bool            nextWithWhitespace(const SkPath** path, SkScalar* xpos);   //!< returns false when there are no more paths
 
 private:
     SkGlyphCache*   fCache;
     SkPaint         fPaint;
     SkScalar        fScale;
     SkFixed         fPrevAdvance;
     const char*     fText;
     const char*     fStop;
--- a/gfx/skia/src/core/SkPaint.cpp
+++ b/gfx/skia/src/core/SkPaint.cpp
@@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void*
                              const SkPoint pos[], SkPath* path) const {
     SkASSERT(length == 0 || textData != NULL);
 
     const char* text = (const char*)textData;
     if (text == NULL || length == 0 || path == NULL) {
         return;
     }
 
-    SkTextToPathIter    iter(text, length, *this, false);
+    SkTextToPathIter    iter(text, length, *this, false, false);
     SkMatrix            matrix;
     SkPoint             prevPos;
     prevPos.set(0, 0);
 
     matrix.setScale(iter.getPathScale(), iter.getPathScale());
     path->reset();
 
     unsigned int    i = 0;
     const SkPath*   iterPath;
-    while ((iterPath = iter.next(NULL)) != NULL) {
-        matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
-        path->addPath(*iterPath, matrix);
-        prevPos = pos[i];
+    while (iter.nextWithWhitespace(&iterPath, NULL)) {
+        if (iterPath) {
+            matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY);
+            path->addPath(*iterPath, matrix);
+            prevPos = pos[i];
+        }
         i++;
     }
 }
 
 static void add_flattenable(SkDescriptor* desc, uint32_t tag,
                             SkFlattenableWriteBuffer* buffer) {
     buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
 }
@@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun
 
 static bool has_thick_frame(const SkPaint& paint) {
     return  paint.getStrokeWidth() > 0 &&
             paint.getStyle() != SkPaint::kFill_Style;
 }
 
 SkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
                                     const SkPaint& paint,
-                                    bool applyStrokeAndPathEffects)
+                                    bool applyStrokeAndPathEffects,
+                                    bool useCanonicalTextSize)
                                     : fPaint(paint) {
     fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
                                                 true);
 
     fPaint.setLinearText(true);
     fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
 
     if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
         applyStrokeAndPathEffects = false;
     }
 
     // can't use our canonical size if we need to apply patheffects
-    if (fPaint.getPathEffect() == NULL) {
+    if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) {
         fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
         fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
         if (has_thick_frame(fPaint)) {
             fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
         }
     } else {
         fScale = SK_Scalar1;
     }
@@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons
     fXYIndex = paint.isVerticalText() ? 1 : 0;
 }
 
 SkTextToPathIter::~SkTextToPathIter() {
     SkGlyphCache::AttachCache(fCache);
 }
 
 const SkPath* SkTextToPathIter::next(SkScalar* xpos) {
-    while (fText < fStop) {
+    const SkPath* result;
+    while (nextWithWhitespace(&result, xpos)) {
+        if (result) {
+            if (xpos) {
+                *xpos = fXPos;
+            }
+            return result;
+        }
+    }
+    return NULL;
+}
+
+bool SkTextToPathIter::nextWithWhitespace(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;
             }
-            return fCache->findPath(glyph);
+            *path = fCache->findPath(glyph);
+            return true;
+        } else {
+            *path = NULL;
+            return true;
         }
     }
-    return NULL;
+    return false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkPaint::nothingToDraw() const {
     if (fLooper) {
         return false;
     }