| Index: src/utils/SkTextBox.cpp
|
| diff --git a/src/utils/SkTextBox.cpp b/src/utils/SkTextBox.cpp
|
| index 55d75a64dac74e1f3e3f5aa5005ef9ab69be31ec..0bb7a6bf5a2b5794c4bc2e7987f3aee02e8562f9 100644
|
| --- a/src/utils/SkTextBox.cpp
|
| +++ b/src/utils/SkTextBox.cpp
|
| @@ -165,14 +165,13 @@ void SkTextBox::setSpacing(SkScalar mul, SkScalar add)
|
|
|
| /////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
| -void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint)
|
| -{
|
| - SkASSERT(canvas && (text || len == 0));
|
| -
|
| +SkScalar SkTextBox::visit(Visitor& visitor, const char text[], size_t len,
|
| + const SkPaint& paint) const {
|
| SkScalar marginWidth = fBox.width();
|
|
|
| - if (marginWidth <= 0 || len == 0)
|
| - return;
|
| + if (marginWidth <= 0 || len == 0) {
|
| + return fBox.top();
|
| + }
|
|
|
| const char* textStop = text + len;
|
|
|
| @@ -200,8 +199,7 @@ void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPa
|
| {
|
| SkScalar textHeight = fontHeight;
|
|
|
| - if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign)
|
| - {
|
| + if (fMode == kLineBreak_Mode && fSpacingAlign != kStart_SpacingAlign) {
|
| int count = SkTextLineBreaker::CountLines(text, textStop - text, paint, marginWidth);
|
| SkASSERT(count > 0);
|
| textHeight += scaledSpacing * (count - 1);
|
| @@ -222,29 +220,48 @@ void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPa
|
| y += fBox.fTop - metrics.fAscent;
|
| }
|
|
|
| - for (;;)
|
| - {
|
| + for (;;) {
|
| size_t trailing;
|
| len = linebreak(text, textStop, paint, marginWidth, &trailing);
|
| - if (y + metrics.fDescent + metrics.fLeading > 0)
|
| - canvas->drawText(text, len - trailing, x, y, paint);
|
| + if (y + metrics.fDescent + metrics.fLeading > 0) {
|
| + visitor(text, len - trailing, x, y, paint);
|
| + }
|
| text += len;
|
| - if (text >= textStop)
|
| + if (text >= textStop) {
|
| break;
|
| + }
|
| y += scaledSpacing;
|
| - if (y + metrics.fAscent >= fBox.fBottom)
|
| + if (y + metrics.fAscent >= fBox.fBottom) {
|
| break;
|
| + }
|
| }
|
| + return y + metrics.fDescent + metrics.fLeading;
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| +class CanvasVisitor : public SkTextBox::Visitor {
|
| + SkCanvas* fCanvas;
|
| +public:
|
| + CanvasVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
|
| +
|
| + virtual void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + fCanvas->drawText(text, length, x, y, paint);
|
| + }
|
| +};
|
| +
|
| void SkTextBox::setText(const char text[], size_t len, const SkPaint& paint) {
|
| fText = text;
|
| fLen = len;
|
| fPaint = &paint;
|
| }
|
|
|
| +void SkTextBox::draw(SkCanvas* canvas, const char text[], size_t len, const SkPaint& paint) {
|
| + CanvasVisitor sink(canvas);
|
| + this->visit(sink, text, len, paint);
|
| +}
|
| +
|
| void SkTextBox::draw(SkCanvas* canvas) {
|
| this->draw(canvas, fText, fLen, *fPaint);
|
| }
|
| @@ -257,3 +274,30 @@ SkScalar SkTextBox::getTextHeight() const {
|
| SkScalar spacing = SkScalarMul(fPaint->getTextSize(), fSpacingMul) + fSpacingAdd;
|
| return this->countLines() * spacing;
|
| }
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#include "SkTextBlob.h"
|
| +
|
| +class TextBlobVisitor : public SkTextBox::Visitor {
|
| +public:
|
| + SkTextBlobBuilder fBuilder;
|
| +
|
| + virtual void operator()(const char text[], size_t length, SkScalar x, SkScalar y,
|
| + const SkPaint& paint) SK_OVERRIDE {
|
| + SkPaint p(paint);
|
| + p.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| + const int count = paint.countText(text, length);
|
| + paint.textToGlyphs(text, length, fBuilder.allocRun(p, count, x, y).glyphs);
|
| + }
|
| +};
|
| +
|
| +SkTextBlob* SkTextBox::snapshotTextBlob(SkScalar* computedBottom) const {
|
| + TextBlobVisitor visitor;
|
| + SkScalar newB = this->visit(visitor, fText, fLen, *fPaint);
|
| + if (computedBottom) {
|
| + *computedBottom = newB;
|
| + }
|
| + return (SkTextBlob*)visitor.fBuilder.build();
|
| +}
|
| +
|
|
|