# HG changeset patch # User Nicholas Cameron # Date 1337146927 -43200 # Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821 # Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8 Bug 746883; changes to the Skia library. r=gw280 diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h --- 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; diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp --- 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; }