aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-22 17:19:52 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-22 17:19:52 +0000
commitcf7be95b19f283e3c5410f977474f433a1e10dad (patch)
tree915cc093af756b276f398eed232703712fcccdc0
parent73613c16e154f08d01de98f03a3b10c474d5c9fb (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.cpp60
-rw-r--r--src/core/SkPictureRecord.cpp43
-rw-r--r--src/core/SkPictureRecord.h21
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.