| Index: src/core/SkTextBlob.cpp
|
| diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
|
| index a49ff251016a90768e52b77bf1d5847bc916e096..2ccf26b1c6fdd1f50009cc0f7950268f335f618d 100644
|
| --- a/src/core/SkTextBlob.cpp
|
| +++ b/src/core/SkTextBlob.cpp
|
| @@ -367,12 +367,44 @@ SkTextBlobBuilder::~SkTextBlobBuilder() {
|
| }
|
|
|
| SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) {
|
| - SkASSERT(SkTextBlob::kDefault_Positioning == run.positioning());
|
| -
|
| SkRect bounds;
|
| SkPaint paint;
|
| run.font().applyToPaint(&paint);
|
| - paint.measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint16_t), &bounds);
|
| +
|
| + if (SkTextBlob::kDefault_Positioning == run.positioning()) {
|
| + paint.measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint16_t), &bounds);
|
| + return bounds.makeOffset(run.offset().x(), run.offset().y());
|
| + }
|
| +
|
| + SkAutoSTArray<16, SkRect> glyphBounds(run.glyphCount());
|
| + paint.getTextWidths(run.glyphBuffer(),
|
| + run.glyphCount() * sizeof(uint16_t),
|
| + NULL,
|
| + glyphBounds.get());
|
| +
|
| + SkASSERT(SkTextBlob::kFull_Positioning == run.positioning() ||
|
| + SkTextBlob::kHorizontal_Positioning == run.positioning());
|
| + // kFull_Positioning => [ x, y, x, y... ]
|
| + // kHorizontal_Positioning => [ x, x, x... ]
|
| + // (const y applied by runBounds.offset(run->offset()) later)
|
| + const SkScalar horizontalConstY = 0;
|
| + const SkScalar* glyphPosX = run.posBuffer();
|
| + const SkScalar* glyphPosY = (run.positioning() == SkTextBlob::kFull_Positioning) ?
|
| + glyphPosX + 1 : &horizontalConstY;
|
| + const unsigned posXInc = SkTextBlob::ScalarsPerGlyph(run.positioning());
|
| + const unsigned posYInc = (run.positioning() == SkTextBlob::kFull_Positioning) ?
|
| + posXInc : 0;
|
| +
|
| + bounds.setEmpty();
|
| + for (unsigned i = 0; i < run.glyphCount(); ++i) {
|
| + bounds.join(glyphBounds[i].makeOffset(*glyphPosX, *glyphPosY));
|
| + glyphPosX += posXInc;
|
| + glyphPosY += posYInc;
|
| + }
|
| +
|
| + SkASSERT((void*)glyphPosX <= SkTextBlob::RunRecord::Next(&run));
|
| + SkASSERT(run.positioning() == SkTextBlob::kHorizontal_Positioning ||
|
| + (void*)glyphPosY <= SkTextBlob::RunRecord::Next(&run));
|
|
|
| return bounds.makeOffset(run.offset().x(), run.offset().y());
|
| }
|
| @@ -382,7 +414,16 @@ SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run
|
| SkASSERT(SkTextBlob::kFull_Positioning == run.positioning() ||
|
| SkTextBlob::kHorizontal_Positioning == run.positioning());
|
|
|
| - // First, compute the glyph position bbox.
|
| + SkPaint paint;
|
| + run.font().applyToPaint(&paint);
|
| + const SkRect fontBounds = paint.getFontBounds();
|
| + if (fontBounds.isEmpty()) {
|
| + // Empty font bounds are likely a font bug. TightBounds has a better chance of
|
| + // producing useful results in this case.
|
| + return TightRunBounds(run);
|
| + }
|
| +
|
| + // Compute the glyph position bbox.
|
| SkRect bounds;
|
| switch (run.positioning()) {
|
| case SkTextBlob::kHorizontal_Positioning: {
|
| @@ -410,9 +451,6 @@ SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run
|
| }
|
|
|
| // Expand by typeface glyph bounds.
|
| - SkPaint paint;
|
| - run.font().applyToPaint(&paint);
|
| - const SkRect fontBounds = paint.getFontBounds();
|
| bounds.fLeft += fontBounds.left();
|
| bounds.fTop += fontBounds.top();
|
| bounds.fRight += fontBounds.right();
|
|
|