michael@0: # HG changeset patch michael@0: # User Nicholas Cameron michael@0: # Date 1337146927 -43200 michael@0: # Node ID 310209abef2c2667e5de41dd2a1f071e8cd42821 michael@0: # Parent 93f3ca4d5707b2aae9c6ae52d5d29c2c802e7ef8 michael@0: Bug 746883; changes to the Skia library. r=gw280 michael@0: michael@0: diff --git a/gfx/skia/include/core/SkDraw.h b/gfx/skia/include/core/SkDraw.h michael@0: --- a/gfx/skia/include/core/SkDraw.h michael@0: +++ b/gfx/skia/include/core/SkDraw.h michael@0: @@ -125,23 +125,24 @@ public: michael@0: #endif michael@0: }; michael@0: michael@0: class SkGlyphCache; michael@0: michael@0: class SkTextToPathIter { michael@0: public: michael@0: SkTextToPathIter(const char text[], size_t length, const SkPaint& paint, michael@0: - bool applyStrokeAndPathEffects); michael@0: + bool applyStrokeAndPathEffects, bool useCanonicalTextSize = true); michael@0: ~SkTextToPathIter(); michael@0: michael@0: const SkPaint& getPaint() const { return fPaint; } michael@0: SkScalar getPathScale() const { return fScale; } michael@0: michael@0: const SkPath* next(SkScalar* xpos); //!< returns nil when there are no more paths michael@0: + bool nextWithWhitespace(const SkPath** path, SkScalar* xpos); //!< returns false when there are no more paths michael@0: michael@0: private: michael@0: SkGlyphCache* fCache; michael@0: SkPaint fPaint; michael@0: SkScalar fScale; michael@0: SkFixed fPrevAdvance; michael@0: const char* fText; michael@0: const char* fStop; michael@0: diff --git a/gfx/skia/src/core/SkPaint.cpp b/gfx/skia/src/core/SkPaint.cpp michael@0: --- a/gfx/skia/src/core/SkPaint.cpp michael@0: +++ b/gfx/skia/src/core/SkPaint.cpp michael@0: @@ -1359,30 +1359,32 @@ void SkPaint::getPosTextPath(const void* michael@0: const SkPoint pos[], SkPath* path) const { michael@0: SkASSERT(length == 0 || textData != NULL); michael@0: michael@0: const char* text = (const char*)textData; michael@0: if (text == NULL || length == 0 || path == NULL) { michael@0: return; michael@0: } michael@0: michael@0: - SkTextToPathIter iter(text, length, *this, false); michael@0: + SkTextToPathIter iter(text, length, *this, false, false); michael@0: SkMatrix matrix; michael@0: SkPoint prevPos; michael@0: prevPos.set(0, 0); michael@0: michael@0: matrix.setScale(iter.getPathScale(), iter.getPathScale()); michael@0: path->reset(); michael@0: michael@0: unsigned int i = 0; michael@0: const SkPath* iterPath; michael@0: - while ((iterPath = iter.next(NULL)) != NULL) { michael@0: - matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); michael@0: - path->addPath(*iterPath, matrix); michael@0: - prevPos = pos[i]; michael@0: + while (iter.nextWithWhitespace(&iterPath, NULL)) { michael@0: + if (iterPath) { michael@0: + matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); michael@0: + path->addPath(*iterPath, matrix); michael@0: + prevPos = pos[i]; michael@0: + } michael@0: i++; michael@0: } michael@0: } michael@0: michael@0: static void add_flattenable(SkDescriptor* desc, uint32_t tag, michael@0: SkFlattenableWriteBuffer* buffer) { michael@0: buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); michael@0: } michael@0: @@ -2118,30 +2120,31 @@ const SkRect& SkPaint::doComputeFastBoun michael@0: michael@0: static bool has_thick_frame(const SkPaint& paint) { michael@0: return paint.getStrokeWidth() > 0 && michael@0: paint.getStyle() != SkPaint::kFill_Style; michael@0: } michael@0: michael@0: SkTextToPathIter::SkTextToPathIter( const char text[], size_t length, michael@0: const SkPaint& paint, michael@0: - bool applyStrokeAndPathEffects) michael@0: + bool applyStrokeAndPathEffects, michael@0: + bool useCanonicalTextSize) michael@0: : fPaint(paint) { michael@0: fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, michael@0: true); michael@0: michael@0: fPaint.setLinearText(true); michael@0: fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup michael@0: michael@0: if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { michael@0: applyStrokeAndPathEffects = false; michael@0: } michael@0: michael@0: // can't use our canonical size if we need to apply patheffects michael@0: - if (fPaint.getPathEffect() == NULL) { michael@0: + if (useCanonicalTextSize && fPaint.getPathEffect() == NULL) { michael@0: fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); michael@0: fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; michael@0: if (has_thick_frame(fPaint)) { michael@0: fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); michael@0: } michael@0: } else { michael@0: fScale = SK_Scalar1; michael@0: } michael@0: @@ -2185,30 +2188,47 @@ SkTextToPathIter::SkTextToPathIter( cons michael@0: fXYIndex = paint.isVerticalText() ? 1 : 0; michael@0: } michael@0: michael@0: SkTextToPathIter::~SkTextToPathIter() { michael@0: SkGlyphCache::AttachCache(fCache); michael@0: } michael@0: michael@0: const SkPath* SkTextToPathIter::next(SkScalar* xpos) { michael@0: - while (fText < fStop) { michael@0: + const SkPath* result; michael@0: + while (nextWithWhitespace(&result, xpos)) { michael@0: + if (result) { michael@0: + if (xpos) { michael@0: + *xpos = fXPos; michael@0: + } michael@0: + return result; michael@0: + } michael@0: + } michael@0: + return NULL; michael@0: +} michael@0: + michael@0: +bool SkTextToPathIter::nextWithWhitespace(const SkPath** path, SkScalar* xpos) { michael@0: + if (fText < fStop) { michael@0: const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); michael@0: michael@0: fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); michael@0: fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); michael@0: michael@0: if (glyph.fWidth) { michael@0: if (xpos) { michael@0: *xpos = fXPos; michael@0: } michael@0: - return fCache->findPath(glyph); michael@0: + *path = fCache->findPath(glyph); michael@0: + return true; michael@0: + } else { michael@0: + *path = NULL; michael@0: + return true; michael@0: } michael@0: } michael@0: - return NULL; michael@0: + return false; michael@0: } michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: bool SkPaint::nothingToDraw() const { michael@0: if (fLooper) { michael@0: return false; michael@0: }