/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrStencilAndCoverTextContext_DEFINED #define GrStencilAndCoverTextContext_DEFINED #include "GrRenderTargetContext.h" #include "GrStyle.h" #include "SkDrawFilter.h" #include "SkOpts.h" #include "SkTextBlob.h" #include "SkTHash.h" #include "SkTInternalLList.h" #include "SkTLList.h" #include "batches/GrDrawPathBatch.h" class GrAtlasTextContext; class GrTextStrike; class GrPath; class SkSurfaceProps; /* * This class implements text rendering using stencil and cover path rendering * (by the means of GrOpList::drawPath). */ class GrStencilAndCoverTextContext { public: static GrStencilAndCoverTextContext* Create(GrAtlasTextContext* fallbackTextContext); void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds); void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset, const SkIRect& clipBounds); void drawTextBlob(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&, const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*, SkScalar x, SkScalar y, SkDrawFilter*, const SkIRect& clipBounds); virtual ~GrStencilAndCoverTextContext(); private: GrStencilAndCoverTextContext(GrAtlasTextContext* fallbackTextContext); bool canDraw(const SkPaint& skPaint, const SkMatrix&) { return this->internalCanDraw(skPaint); } bool internalCanDraw(const SkPaint&); void uncachedDrawTextBlob(GrContext*, GrRenderTargetContext* rtc, const GrClip& clip, const SkPaint& skPaint, const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob* blob, SkScalar x, SkScalar y, SkDrawFilter* drawFilter, const SkIRect& clipBounds); class FallbackBlobBuilder; class TextRun { public: TextRun(const SkPaint& fontAndStroke); ~TextRun(); void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y); void setPosText(const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset); void draw(GrContext*, GrRenderTargetContext*, const GrPaint&, const GrClip&, const SkMatrix&, const SkSurfaceProps&, SkScalar x, SkScalar y, const SkIRect& clipBounds, GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const; void releaseGlyphCache() const; size_t computeSizeInCache() const; GrAA isAntiAlias() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; } private: typedef GrDrawPathRangeBatch::InstanceData InstanceData; SkGlyphCache* getGlyphCache() const; GrPathRange* createGlyphs(GrContext*) const; void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*); GrStyle fStyle; SkPaint fFont; SkScalar fTextRatio; float fTextInverseRatio; bool fUsingRawGlyphPaths; GrUniqueKey fGlyphPathsKey; int fTotalGlyphCount; sk_sp fInstanceData; int fFallbackGlyphCount; sk_sp fFallbackTextBlob; mutable SkGlyphCache* fDetachedGlyphCache; mutable GrGpuResource::UniqueID fLastDrawnGlyphsID; }; // Text blobs/caches. class TextBlob : public SkTLList { public: typedef SkTArray Key; static const Key& GetKey(const TextBlob* blob) { return blob->key(); } static uint32_t Hash(const Key& key) { SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map. return SkOpts::hash(key.begin(), sizeof(uint32_t) * key.count()); } TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint) : fKey(&blobId, 1) { this->init(skBlob, skPaint); } TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint) : fKey(key) { // 1-length keys are unterstood to be the blob id and must use the other constructor. SkASSERT(fKey.count() > 1); this->init(skBlob, skPaint); } const Key& key() const { return fKey; } size_t cpuMemorySize() const { return fCpuMemorySize; } private: void init(const SkTextBlob*, const SkPaint&); const SkSTArray<1, uint32_t, true> fKey; size_t fCpuMemorySize; SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); }; const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&); void purgeToFit(const TextBlob&); GrAtlasTextContext* fFallbackTextContext; SkTHashMap fBlobIdCache; SkTHashTable fBlobKeyCache; SkTInternalLList fLRUList; size_t fCacheSize; }; #endif