| Index: src/core/SkTextBlob.cpp
|
| diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
|
| index 3ffc41e9ba6677b5eb1904da834a4281b26800f4..3d396deba5cb4ce8fe84daeff52b64e369ddb0f4 100644
|
| --- a/src/core/SkTextBlob.cpp
|
| +++ b/src/core/SkTextBlob.cpp
|
| @@ -11,6 +11,84 @@
|
| #include "SkTypeface.h"
|
| #include "SkWriteBuffer.h"
|
|
|
| +namespace {
|
| +
|
| +// TODO(fmalita): replace with SkFont.
|
| +class RunFont : SkNoncopyable {
|
| +public:
|
| + RunFont(const SkPaint& paint)
|
| + : fSize(paint.getTextSize())
|
| + , fScaleX(paint.getTextScaleX())
|
| + , fTypeface(SkSafeRef(paint.getTypeface()))
|
| + , fSkewX(paint.getTextSkewX())
|
| + , fHinting(paint.getHinting())
|
| + , fFlags(paint.getFlags() & kFlagsMask) { }
|
| +
|
| + void applyToPaint(SkPaint* paint) const {
|
| + paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
| + paint->setTypeface(fTypeface.get());
|
| + paint->setTextSize(fSize);
|
| + paint->setTextScaleX(fScaleX);
|
| + paint->setTextSkewX(fSkewX);
|
| + paint->setHinting(static_cast<SkPaint::Hinting>(fHinting));
|
| +
|
| + paint->setFlags((paint->getFlags() & ~kFlagsMask) | fFlags);
|
| + }
|
| +
|
| + bool operator==(const RunFont& other) const {
|
| + return fTypeface == other.fTypeface
|
| + && fSize == other.fSize
|
| + && fScaleX == other.fScaleX
|
| + && fSkewX == other.fSkewX
|
| + && fHinting == other.fHinting
|
| + && fFlags == other.fFlags;
|
| + }
|
| +
|
| + bool operator!=(const RunFont& other) const {
|
| + return !(*this == other);
|
| + }
|
| +private:
|
| + const static uint32_t kFlagsMask =
|
| + SkPaint::kAntiAlias_Flag |
|
| + SkPaint::kUnderlineText_Flag |
|
| + SkPaint::kStrikeThruText_Flag |
|
| + SkPaint::kFakeBoldText_Flag |
|
| + SkPaint::kLinearText_Flag |
|
| + SkPaint::kSubpixelText_Flag |
|
| + SkPaint::kDevKernText_Flag |
|
| + SkPaint::kLCDRenderText_Flag |
|
| + SkPaint::kEmbeddedBitmapText_Flag |
|
| + SkPaint::kAutoHinting_Flag |
|
| + SkPaint::kVerticalText_Flag |
|
| + SkPaint::kGenA8FromLCD_Flag |
|
| + SkPaint::kDistanceFieldTextTEMP_Flag;
|
| +
|
| + SkScalar fSize;
|
| + SkScalar fScaleX;
|
| +
|
| + // Keep this SkAutoTUnref off the first position, to avoid interfering with SkNoncopyable
|
| + // empty baseclass optimization (http://code.google.com/p/skia/issues/detail?id=3694).
|
| + SkAutoTUnref<SkTypeface> fTypeface;
|
| + SkScalar fSkewX;
|
| +
|
| + SK_COMPILE_ASSERT(SkPaint::kFull_Hinting < 4, insufficient_hinting_bits);
|
| + uint32_t fHinting : 2;
|
| + SK_COMPILE_ASSERT((kFlagsMask & 0xffff) == kFlagsMask, insufficient_flags_bits);
|
| + uint32_t fFlags : 16;
|
| +
|
| + typedef SkNoncopyable INHERITED;
|
| +};
|
| +
|
| +struct RunFontStorageEquivalent {
|
| + SkScalar fSize, fScaleX;
|
| + void* fTypeface;
|
| + SkScalar fSkewX;
|
| + uint32_t fFlags;
|
| +};
|
| +SK_COMPILE_ASSERT(sizeof(RunFont) == sizeof(RunFontStorageEquivalent), runfont_should_stay_packed);
|
| +
|
| +} // anonymous namespace
|
| +
|
| //
|
| // Textblob data is laid out into externally-managed storage as follows:
|
| //
|
| @@ -26,9 +104,9 @@ SkDEBUGCODE(static const unsigned kRunRecordMagic = 0xb10bcafe;)
|
| class SkTextBlob::RunRecord {
|
| public:
|
| RunRecord(uint32_t count, const SkPoint& offset, const SkPaint& font, GlyphPositioning pos)
|
| - : fCount(count)
|
| + : fFont(font)
|
| + , fCount(count)
|
| , fOffset(offset)
|
| - , fFont(font)
|
| , fPositioning(pos) {
|
| SkDEBUGCODE(fMagic = kRunRecordMagic);
|
| }
|
| @@ -41,7 +119,7 @@ public:
|
| return fOffset;
|
| }
|
|
|
| - const SkPaint& font() const {
|
| + const RunFont& font() const {
|
| return fFont;
|
| }
|
|
|
| @@ -100,9 +178,9 @@ private:
|
| memmove(posBuffer(), initialPosBuffer, copySize);
|
| }
|
|
|
| + RunFont fFont;
|
| uint32_t fCount;
|
| SkPoint fOffset;
|
| - SkPaint fFont;
|
| GlyphPositioning fPositioning;
|
|
|
| SkDEBUGCODE(unsigned fMagic;)
|
| @@ -262,29 +340,7 @@ SkTextBlob::GlyphPositioning SkTextBlob::RunIterator::positioning() const {
|
| void SkTextBlob::RunIterator::applyFontToPaint(SkPaint* paint) const {
|
| SkASSERT(!this->done());
|
|
|
| - const SkPaint& font = fCurrentRun->font();
|
| -
|
| - paint->setTypeface(font.getTypeface());
|
| - paint->setTextEncoding(font.getTextEncoding());
|
| - paint->setTextSize(font.getTextSize());
|
| - paint->setTextScaleX(font.getTextScaleX());
|
| - paint->setTextSkewX(font.getTextSkewX());
|
| - paint->setHinting(font.getHinting());
|
| -
|
| - uint32_t flagsMask = SkPaint::kAntiAlias_Flag
|
| - | SkPaint::kUnderlineText_Flag
|
| - | SkPaint::kStrikeThruText_Flag
|
| - | SkPaint::kFakeBoldText_Flag
|
| - | SkPaint::kLinearText_Flag
|
| - | SkPaint::kSubpixelText_Flag
|
| - | SkPaint::kDevKernText_Flag
|
| - | SkPaint::kLCDRenderText_Flag
|
| - | SkPaint::kEmbeddedBitmapText_Flag
|
| - | SkPaint::kAutoHinting_Flag
|
| - | SkPaint::kVerticalText_Flag
|
| - | SkPaint::kGenA8FromLCD_Flag
|
| - | SkPaint::kDistanceFieldTextTEMP_Flag;
|
| - paint->setFlags((paint->getFlags() & ~flagsMask) | (font.getFlags() & flagsMask));
|
| + fCurrentRun->font().applyToPaint(paint);
|
| }
|
|
|
| SkTextBlobBuilder::SkTextBlobBuilder()
|
| @@ -308,7 +364,9 @@ SkRect SkTextBlobBuilder::TightRunBounds(const SkTextBlob::RunRecord& run) {
|
| SkASSERT(SkTextBlob::kDefault_Positioning == run.positioning());
|
|
|
| SkRect bounds;
|
| - run.font().measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint16_t), &bounds);
|
| + SkPaint paint;
|
| + run.font().applyToPaint(&paint);
|
| + paint.measureText(run.glyphBuffer(), run.glyphCount() * sizeof(uint16_t), &bounds);
|
|
|
| return bounds.makeOffset(run.offset().x(), run.offset().y());
|
| }
|
| @@ -346,7 +404,9 @@ SkRect SkTextBlobBuilder::ConservativeRunBounds(const SkTextBlob::RunRecord& run
|
| }
|
|
|
| // Expand by typeface glyph bounds.
|
| - const SkRect fontBounds = run.font().getFontBounds();
|
| + SkPaint paint;
|
| + run.font().applyToPaint(&paint);
|
| + const SkRect fontBounds = paint.getFontBounds();
|
| bounds.fLeft += fontBounds.left();
|
| bounds.fTop += fontBounds.top();
|
| bounds.fRight += fontBounds.right();
|
| @@ -366,7 +426,6 @@ void SkTextBlobBuilder::updateDeferredBounds() {
|
| SkASSERT(fLastRun >= sizeof(SkTextBlob));
|
| SkTextBlob::RunRecord* run = reinterpret_cast<SkTextBlob::RunRecord*>(fStorage.get() +
|
| fLastRun);
|
| - SkASSERT(SkPaint::kGlyphID_TextEncoding == run->font().getTextEncoding());
|
|
|
| // FIXME: we should also use conservative bounds for kDefault_Positioning.
|
| SkRect runBounds = SkTextBlob::kDefault_Positioning == run->positioning() ?
|
|
|