Expose drawTextBlob to devices.

Instead of unrolling blobs in SkCanvas, perform the equivalent ops in
SkBaseDevice.

This depends on https://codereview.chromium.org/511783005/.

R=jvanverth@google.com, reed@google.com, robertphillips@google.com, bsalomon@google.com

Author: fmalita@chromium.org

Review URL: https://codereview.chromium.org/517663003
This commit is contained in:
fmalita 2014-08-28 14:32:24 -07:00 committed by Commit bot
parent d73c169637
commit aa1b912046
4 changed files with 48 additions and 36 deletions

View File

@ -242,6 +242,9 @@ protected:
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) = 0;
// default implementation unrolls the blob runs.
virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
const SkPaint& paint);
// default implementation calls drawVertices
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);

View File

@ -86,7 +86,7 @@ private:
static unsigned ScalarsPerGlyph(GlyphPositioning pos);
friend class SkCanvas;
friend class SkBaseDevice;
friend class SkTextBlobBuilder;
friend class TextBlobTester;

View File

@ -22,7 +22,6 @@
#include "SkSmallAllocator.h"
#include "SkSurface_Base.h"
#include "SkTemplates.h"
#include "SkTextBlob.h"
#include "SkTextFormatParams.h"
#include "SkTLazy.h"
#include "SkUtils.h"
@ -2218,43 +2217,14 @@ void SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPat
void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint) {
SkASSERT(blob);
LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, NULL)
// FIXME: dispatch to the device instead
if (x || y) {
this->translate(x, y);
while (iter.next()) {
SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint());
}
SkPaint runPaint = paint;
SkTextBlob::RunIterator it(blob);
while (!it.done()) {
size_t textLen = it.glyphCount() * sizeof(uint16_t);
const SkPoint& offset = it.offset();
// applyFontToPaint() always overwrites the exact same attributes,
// so it is safe to not re-seed the paint.
it.applyFontToPaint(&runPaint);
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
this->drawText(it.glyphs(), textLen, offset.x(), offset.y(), runPaint);
break;
case SkTextBlob::kHorizontal_Positioning:
this->drawPosTextH(it.glyphs(), textLen, it.pos(), offset.y(), runPaint);
break;
case SkTextBlob::kFull_Positioning:
this->drawPosText(it.glyphs(), textLen, (const SkPoint*)it.pos(), runPaint);
break;
default:
SkFAIL("unhandled positioning mode");
}
it.next();
}
if (x || y) {
this->translate(-x, -y);
}
LOOPER_END
}
// These will become non-virtual, so they always call the (virtual) onDraw... method

View File

@ -9,6 +9,7 @@
#include "SkDraw.h"
#include "SkMetaData.h"
#include "SkPatchUtils.h"
#include "SkTextBlob.h"
SkBaseDevice::SkBaseDevice()
: fLeakyProperties(SkDeviceProperties::MakeDefault())
@ -94,6 +95,44 @@ void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const
}
}
void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint &paint) {
SkMatrix localMatrix;
SkDraw localDraw(draw);
if (x || y) {
localMatrix = *draw.fMatrix;
localMatrix.preTranslate(x, y);
localDraw.fMatrix = &localMatrix;
}
SkPaint runPaint = paint;
SkTextBlob::RunIterator it(blob);
while (!it.done()) {
size_t textLen = it.glyphCount() * sizeof(uint16_t);
const SkPoint& offset = it.offset();
// applyFontToPaint() always overwrites the exact same attributes,
// so it is safe to not re-seed the paint.
it.applyFontToPaint(&runPaint);
switch (it.positioning()) {
case SkTextBlob::kDefault_Positioning:
this->drawText(localDraw, it.glyphs(), textLen, offset.x(), offset.y(), runPaint);
break;
case SkTextBlob::kHorizontal_Positioning:
case SkTextBlob::kFull_Positioning:
this->drawPosText(localDraw, it.glyphs(), textLen, it.pos(), offset.y(),
SkTextBlob::ScalarsPerGlyph(it.positioning()), runPaint);
break;
default:
SkFAIL("unhandled positioning mode");
}
it.next();
}
}
bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
#ifdef SK_DEBUG
SkASSERT(info.width() > 0 && info.height() > 0);