fVertexBounds.setLargestInverted();
}
+GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context,
+ const SkDeviceProperties& props) {
+ return SkNEW_ARGS(GrBitmapTextContext, (context, props));
+}
+
GrBitmapTextContext::~GrBitmapTextContext() {
this->flush();
}
fMaxVertices = 0;
}
-void GrBitmapTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
+void GrBitmapTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
SkASSERT(byteLength == 0 || text != NULL);
this->finish();
}
-void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
+void GrBitmapTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) {
*/
class GrBitmapTextContext : public GrTextContext {
public:
- GrBitmapTextContext(GrContext*, const SkDeviceProperties&);
- virtual ~GrBitmapTextContext();
+ static GrBitmapTextContext* Create(GrContext*, const SkDeviceProperties&);
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
- virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
- virtual void drawPosText(const GrPaint&, const SkPaint&,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ virtual ~GrBitmapTextContext();
private:
enum {
// Used to check whether fCachedEffect is still valid.
uint32_t fEffectTextureUniqueID;
+ GrBitmapTextContext(GrContext*, const SkDeviceProperties&);
+
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) SK_OVERRIDE;
+ virtual void onDrawPosText(const GrPaint&, const SkPaint&,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) SK_OVERRIDE;
+
void init(const GrPaint&, const SkPaint&);
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
void flush(); // automatically called by destructor
const SkDeviceProperties&
leakyProperties,
bool enableDistanceFieldFonts) {
- if (fGpu->caps()->pathRenderingSupport()) {
- if (renderTarget->getStencilBuffer() && renderTarget->isMultisampled()) {
- return SkNEW_ARGS(GrStencilAndCoverTextContext, (this, leakyProperties));
- }
- }
- return SkNEW_ARGS(GrDistanceFieldTextContext, (this, leakyProperties,
- enableDistanceFieldFonts));
+ if (fGpu->caps()->pathRenderingSupport() && renderTarget->getStencilBuffer() &&
+ renderTarget->isMultisampled()) {
+ return GrStencilAndCoverTextContext::Create(this, leakyProperties);
+ }
+
+ return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
}
////////////////////////////////////////////////////////////////////////////////
#include "GrDistanceFieldTextContext.h"
#include "GrAtlas.h"
+#include "GrBitmapTextContext.h"
#include "GrDrawTarget.h"
#include "GrDrawTargetCaps.h"
#include "GrFontScaler.h"
fVertexBounds.setLargestInverted();
}
+GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* context,
+ const SkDeviceProperties& props,
+ bool enable) {
+ GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextContext,
+ (context, props, enable));
+ textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, props);
+
+ return textContext;
+}
+
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
this->flush();
SkSafeSetNull(fGammaTexture);
}
}
-void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
+void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
SkScalar x, SkScalar y) {
SkASSERT(byteLength == 0 || text != NULL);
this->finish();
}
-void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
+void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset) {
*/
class GrDistanceFieldTextContext : public GrTextContext {
public:
- GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&, bool enable);
- virtual ~GrDistanceFieldTextContext();
+ static GrDistanceFieldTextContext* Create(GrContext*, const SkDeviceProperties&, bool enable);
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
- virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
- virtual void drawPosText(const GrPaint&, const SkPaint&,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ virtual ~GrDistanceFieldTextContext();
private:
enum {
int fCurrVertex;
SkRect fVertexBounds;
+ GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&, bool enable);
+
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) SK_OVERRIDE;
+ virtual void onDrawPosText(const GrPaint&, const SkPaint&,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) SK_OVERRIDE;
+
void init(const GrPaint&, const SkPaint&);
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
void setupCoverageEffect(const SkColor& filteredColor);
*/
#include "GrStencilAndCoverTextContext.h"
+#include "GrBitmapTextContext.h"
#include "GrDrawTarget.h"
#include "GrGpu.h"
#include "GrPath.h"
, fPendingGlyphCount(0) {
}
+GrStencilAndCoverTextContext* GrStencilAndCoverTextContext::Create(GrContext* context,
+ const SkDeviceProperties& props) {
+ GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverTextContext,
+ (context, props));
+ textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, props);
+
+ return textContext;
+}
+
GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
}
return rec.getFormat() != SkMask::kARGB32_Format;
}
-void GrStencilAndCoverTextContext::drawText(const GrPaint& paint,
+void GrStencilAndCoverTextContext::onDrawText(const GrPaint& paint,
const SkPaint& skPaint,
const char text[],
size_t byteLength,
this->finish();
}
-void GrStencilAndCoverTextContext::drawPosText(const GrPaint& paint,
+void GrStencilAndCoverTextContext::onDrawPosText(const GrPaint& paint,
const SkPaint& skPaint,
const char text[],
size_t byteLength,
*/
class GrStencilAndCoverTextContext : public GrTextContext {
public:
- GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);
- virtual ~GrStencilAndCoverTextContext();
+ static GrStencilAndCoverTextContext* Create(GrContext*, const SkDeviceProperties&);
- virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
-
- virtual void drawText(const GrPaint&, const SkPaint&, const char text[],
- size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
- virtual void drawPosText(const GrPaint&, const SkPaint&,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ virtual ~GrStencilAndCoverTextContext();
private:
static const int kGlyphBufferSize = 1024;
SkMatrix fContextInitialMatrix;
bool fNeedsDeviceSpaceGlyphs;
+ GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);
+
+ virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE;
+
+ virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[],
+ size_t byteLength,
+ SkScalar x, SkScalar y) SK_OVERRIDE;
+ virtual void onDrawPosText(const GrPaint&, const SkPaint&,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) SK_OVERRIDE;
+
void init(const GrPaint&, const SkPaint&, size_t textByteLength,
RenderMode, const SkPoint& textTranslate);
void initGlyphs(SkGlyphCache* cache);
#include "GrFontScaler.h"
GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
+ fFallbackTextContext(NULL),
fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
}
+GrTextContext::~GrTextContext() {
+ SkDELETE(fFallbackTextContext);
+}
+
void GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) {
const GrClipData* clipData = fContext->getClip();
fSkPaint = skPaint;
}
+bool GrTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) {
+
+ GrTextContext* textContext = this;
+ do {
+ if (textContext->canDraw(skPaint)) {
+ textContext->onDrawText(paint, skPaint, text, byteLength, x, y);
+ return true;
+ }
+ textContext = textContext->fFallbackTextContext;
+ } while (textContext);
+
+ return false;
+}
+
+bool GrTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) {
+
+ GrTextContext* textContext = this;
+ do {
+ if (textContext->canDraw(skPaint)) {
+ textContext->onDrawPosText(paint, skPaint, text, byteLength, pos, scalarsPerPosition,
+ offset);
+ return true;
+ }
+ textContext = textContext->fFallbackTextContext;
+ } while (textContext);
+
+ return false;
+}
+
+
//*** change to output positions?
void GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
const char text[], size_t byteLength, SkVector* stopVector) {
*/
class GrTextContext {
public:
- virtual ~GrTextContext() {}
+ virtual ~GrTextContext();
- virtual bool canDraw(const SkPaint& paint) = 0;
-
- virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
- SkScalar x, SkScalar y) = 0;
- virtual void drawPosText(const GrPaint&, const SkPaint&,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) = 0;
+ bool drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
+ SkScalar x, SkScalar y);
+ bool drawPosText(const GrPaint&, const SkPaint&,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset);
protected:
+ GrTextContext* fFallbackTextContext;
GrContext* fContext;
SkDeviceProperties fDeviceProperties;
GrTextContext(GrContext*, const SkDeviceProperties&);
+ virtual bool canDraw(const SkPaint& paint) = 0;
+
+ virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) = 0;
+ virtual void onDrawPosText(const GrPaint&, const SkPaint&,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) = 0;
+
void init(const GrPaint&, const SkPaint&);
void finish() { fDrawTarget = NULL; }
this->setPixelGeometry(props.pixelGeometry());
bool useDFFonts = !!(flags & kDFFonts_Flag);
- fMainTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFFonts);
- fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, this->getLeakyProperties()));
+ fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFFonts);
}
SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo,
delete fDrawProcs;
}
- delete fMainTextContext;
- delete fFallbackTextContext;
+ delete fTextContext;
// The GrContext takes a ref on the target. We don't want to cause the render
// target to be unnecessarily kept alive.
CHECK_SHOULD_DRAW(draw, false);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
- if (fMainTextContext->canDraw(paint)) {
- GrPaint grPaint;
- SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-
- SkDEBUGCODE(this->validate();)
-
- fMainTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
- } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
- GrPaint grPaint;
- SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
+ GrPaint grPaint;
+ SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
- SkDEBUGCODE(this->validate();)
+ SkDEBUGCODE(this->validate();)
- fFallbackTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y);
- } else {
- // this guy will just call our drawPath()
+ if (!fTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y)) {
+ // this will just call our drawPath()
draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
}
}
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext);
CHECK_SHOULD_DRAW(draw, false);
- if (fMainTextContext->canDraw(paint)) {
- GrPaint grPaint;
- SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
-
- SkDEBUGCODE(this->validate();)
-
- fMainTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
- scalarsPerPos, offset);
- } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) {
- GrPaint grPaint;
- SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
+ GrPaint grPaint;
+ SkPaint2GrPaintShader(this->context(), paint, true, &grPaint);
- SkDEBUGCODE(this->validate();)
+ SkDEBUGCODE(this->validate();)
- fFallbackTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
- scalarsPerPos, offset);
- } else {
+ if (!fTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos,
+ scalarsPerPos, offset)) {
+ // this will just call our drawPath()
draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerPos, offset, paint);
}
}
GrClipData fClipData;
- GrTextContext* fMainTextContext;
- GrTextContext* fFallbackTextContext;
+ GrTextContext* fTextContext;
// state for our render-target
GrRenderTarget* fRenderTarget;