diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-22 17:19:52 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-22 17:19:52 +0000 |
commit | cf7be95b19f283e3c5410f977474f433a1e10dad (patch) | |
tree | 915cc093af756b276f398eed232703712fcccdc0 | |
parent | 73613c16e154f08d01de98f03a3b10c474d5c9fb (diff) |
Remove the call to getFontMetrics from SkBBoxRecord
R=reed@google.com, caryclark@google.com
Author: sglez@google.com
Review URL: https://chromiumcodereview.appspot.com/23001007
git-svn-id: http://skia.googlecode.com/svn/trunk@10876 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkBBoxRecord.cpp | 60 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 43 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 21 |
3 files changed, 84 insertions, 40 deletions
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp index 366808703f..1e6c69ba09 100644 --- a/src/core/SkBBoxRecord.cpp +++ b/src/core/SkBBoxRecord.cpp @@ -179,35 +179,45 @@ void SkBBoxRecord::drawPosText(const void* text, size_t byteLength, void SkBBoxRecord::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { - SkRect bbox; size_t numChars = paint.countText(text, byteLength); - if (numChars > 0) { - bbox.fLeft = xpos[0]; - bbox.fRight = xpos[numChars - 1]; - // if we had a guarantee that these will be monotonically increasing, this could be sped up - for (size_t i = 1; i < numChars; ++i) { - if (xpos[i] < bbox.fLeft) { - bbox.fLeft = xpos[i]; - } - if (xpos[i] > bbox.fRight) { - bbox.fRight = xpos[i]; - } + if (numChars == 0) { + return; + } + + const SkFlatData* flatPaintData = this->getFlatPaintData(paint); + WriteTopBot(paint, *flatPaintData); + + SkScalar top = flatPaintData->topBot()[0]; + SkScalar bottom = flatPaintData->topBot()[1]; + SkScalar pad = top - bottom; + + SkRect bbox; + bbox.fLeft = SK_ScalarMax; + bbox.fRight = SK_ScalarMin; + + for (size_t i = 0; i < numChars; ++i) { + if (xpos[i] < bbox.fLeft) { + bbox.fLeft = xpos[i]; } - SkPaint::FontMetrics metrics; - paint.getFontMetrics(&metrics); - - // pad horizontally by max glyph height - SkScalar pad = (metrics.fTop - metrics.fBottom); - bbox.fLeft += pad; - bbox.fRight -= pad; - - bbox.fTop = metrics.fTop + constY; - bbox.fBottom = metrics.fBottom + constY; - if (!this->transformBounds(bbox, &paint)) { - return; + if (xpos[i] > bbox.fRight) { + bbox.fRight = xpos[i]; } } - INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); + + // pad horizontally by max glyph height + bbox.fLeft += pad; + bbox.fRight -= pad; + + bbox.fTop = top + constY; + bbox.fBottom = bottom + constY; + + if (!this->transformBounds(bbox, &paint)) { + return; + } + // This is the equivalent of calling: + // INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); + // but we filled our flat paint beforehand so that we could get font metrics. + drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData); } void SkBBoxRecord::drawSprite(const SkBitmap& bitmap, int left, int top, diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 309b8a883f..01478bb844 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -401,13 +401,16 @@ static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, SkColorGetA(saveLayerPaint->getColor())); dbmPaint->setColor(newColor); - const int paintIndex = paintDict->find(*dbmPaint); + const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); + if (NULL == data) { + return false; + } // kill the saveLayer and alter the DBMR2R's paint to be the modified one convert_command_to_noop(writer, saveLayerInfo.fOffset); uint32_t* ptr = writer->peek32(dbmInfo.fOffset+dbmPaintOffset); SkASSERT(dbmPaintId == *ptr); - *ptr = paintIndex; + *ptr = data->index(); return true; } @@ -967,10 +970,7 @@ void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, validate(initialOffset, size); } -// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been -// tweaked by paint.computeFastBounds(). -// -static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { +void SkPictureRecord::ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); SkRect bounds; @@ -984,10 +984,7 @@ static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2] void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData& flat, SkScalar minY, SkScalar maxY) { - if (!flat.isTopBotWritten()) { - computeFontMetricsTopBottom(paint, flat.writableTopBot()); - SkASSERT(flat.isTopBotWritten()); - } + WriteTopBot(paint, flat); addScalar(flat.topBot()[0] + minY); addScalar(flat.topBot()[1] + maxY); } @@ -1103,6 +1100,14 @@ void SkPictureRecord::drawPosText(const void* text, size_t byteLength, void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { + + const SkFlatData* flatPaintData = this->getFlatPaintData(paint); + drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData); +} + +void SkPictureRecord::drawPosTextHImpl(const void* text, size_t byteLength, + const SkScalar xpos[], SkScalar constY, + const SkPaint& paint, const SkFlatData* flatPaintData) { size_t points = paint.countText(text, byteLength); if (0 == points) return; @@ -1116,11 +1121,11 @@ void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, } // + y + the actual points size += 1 * kUInt32Size + points * sizeof(SkScalar); - uint32_t initialOffset = this->addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H, &size); - const SkFlatData* flatPaintData = addPaint(paint); SkASSERT(flatPaintData); + addFlatPaint(flatPaintData); + addText(text, byteLength); addInt(points); @@ -1265,13 +1270,21 @@ void SkPictureRecord::addMatrixPtr(const SkMatrix* matrix) { this->addInt(matrix ? fMatrices.find(*matrix) : 0); } +const SkFlatData* SkPictureRecord::getFlatPaintData(const SkPaint& paint) { + return fPaints.findAndReturnFlat(paint); +} + const SkFlatData* SkPictureRecord::addPaintPtr(const SkPaint* paint) { - const SkFlatData* data = paint ? fPaints.findAndReturnFlat(*paint) : NULL; - int index = data ? data->index() : 0; - this->addInt(index); + const SkFlatData* data = paint ? getFlatPaintData(*paint) : NULL; + this->addFlatPaint(data); return data; } +void SkPictureRecord::addFlatPaint(const SkFlatData* flatPaint) { + int index = flatPaint ? flatPaint->index() : 0; + this->addInt(index); +} + void SkPictureRecord::addPath(const SkPath& path) { if (NULL == fPathHeap) { fPathHeap = SkNEW(SkPathHeap); diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h index 51547a4741..b900f4f574 100644 --- a/src/core/SkPictureRecord.h +++ b/src/core/SkPictureRecord.h @@ -165,6 +165,7 @@ private: void addMatrixPtr(const SkMatrix* matrix); const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } const SkFlatData* addPaintPtr(const SkPaint* paint); + void addFlatPaint(const SkFlatData* flatPaint); void addPath(const SkPath& path); void addPicture(SkPicture& picture); void addPoint(const SkPoint& point); @@ -216,6 +217,26 @@ public: #endif protected: + // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been + // tweaked by paint.computeFastBounds(). + static void ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]); + + // Make sure that flat has fTopBot written. + static void WriteTopBot(const SkPaint& paint, const SkFlatData& flat) { + if (!flat.isTopBotWritten()) { + ComputeFontMetricsTopBottom(paint, flat.writableTopBot()); + SkASSERT(flat.isTopBotWritten()); + } + } + // Will return a cached version when possible. + const SkFlatData* getFlatPaintData(const SkPaint& paint); + /** + * SkBBoxRecord::drawPosTextH gets a flat paint and uses it, + * then it calls this, using the extra parameter, to avoid duplication. + */ + void drawPosTextHImpl(const void* text, size_t byteLength, + const SkScalar xpos[], SkScalar constY, + const SkPaint& paint, const SkFlatData* flatPaintData); // These are set to NULL in our constructor, but may be changed by // subclasses, in which case they will be SkSafeUnref'd in our destructor. |