1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrStencilAndCoverTextContext_DEFINED 9 #define GrStencilAndCoverTextContext_DEFINED 10 11 #include "GrRenderTargetContext.h" 12 #include "GrStyle.h" 13 #include "SkDrawFilter.h" 14 #include "SkOpts.h" 15 #include "SkTHash.h" 16 #include "SkTInternalLList.h" 17 #include "SkTLList.h" 18 #include "SkTextBlob.h" 19 #include "ops/GrDrawPathOp.h" 20 21 class GrAtlasTextContext; 22 class GrTextStrike; 23 class GrPath; 24 class SkSurfaceProps; 25 26 /* 27 * This class implements text rendering using stencil and cover path rendering 28 * (by the means of GrOpList::drawPath). 29 */ 30 class GrStencilAndCoverTextContext { 31 public: 32 static GrStencilAndCoverTextContext* Create(GrAtlasTextContext* fallbackTextContext); 33 34 void drawText(GrContext*, GrRenderTargetContext* rtc, const GrClip&, const SkPaint&, 35 const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], 36 size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds); 37 void drawPosText(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&, 38 const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], 39 size_t byteLength, const SkScalar pos[], int scalarsPerPosition, 40 const SkPoint& offset, const SkIRect& clipBounds); 41 void drawTextBlob(GrContext*, GrRenderTargetContext*, const GrClip&, const SkPaint&, 42 const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*, 43 SkScalar x, SkScalar y, 44 SkDrawFilter*, const SkIRect& clipBounds); 45 46 virtual ~GrStencilAndCoverTextContext(); 47 48 private: 49 GrStencilAndCoverTextContext(GrAtlasTextContext* fallbackTextContext); 50 canDraw(const SkPaint & skPaint,const SkMatrix &)51 bool canDraw(const SkPaint& skPaint, const SkMatrix&) { 52 return this->internalCanDraw(skPaint); 53 } 54 55 bool internalCanDraw(const SkPaint&); 56 57 void uncachedDrawTextBlob(GrContext*, GrRenderTargetContext* rtc, 58 const GrClip& clip, const SkPaint& skPaint, 59 const SkMatrix& viewMatrix, 60 const SkSurfaceProps&, 61 const SkTextBlob* blob, 62 SkScalar x, SkScalar y, 63 SkDrawFilter* drawFilter, 64 const SkIRect& clipBounds); 65 66 class FallbackBlobBuilder; 67 68 class TextRun { 69 public: 70 TextRun(const SkPaint& fontAndStroke); 71 ~TextRun(); 72 73 void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y); 74 75 void setPosText(const char text[], size_t byteLength, const SkScalar pos[], 76 int scalarsPerPosition, const SkPoint& offset); 77 78 void draw(GrContext*, GrRenderTargetContext*, const GrClip&, const SkMatrix&, 79 const SkSurfaceProps&, SkScalar x, SkScalar y, const SkIRect& clipBounds, 80 GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const; 81 82 void releaseGlyphCache() const; 83 84 size_t computeSizeInCache() const; 85 aa()86 GrAA aa() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; } 87 88 private: 89 typedef GrDrawPathRangeOp::InstanceData InstanceData; 90 91 SkGlyphCache* getGlyphCache() const; 92 sk_sp<GrPathRange> createGlyphs(GrResourceProvider*) const; 93 void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*); 94 95 GrStyle fStyle; 96 SkPaint fFont; 97 SkScalar fTextRatio; 98 float fTextInverseRatio; 99 bool fUsingRawGlyphPaths; 100 GrUniqueKey fGlyphPathsKey; 101 int fTotalGlyphCount; 102 sk_sp<InstanceData> fInstanceData; 103 int fFallbackGlyphCount; 104 sk_sp<SkTextBlob> fFallbackTextBlob; 105 mutable SkGlyphCache* fDetachedGlyphCache; 106 mutable GrGpuResource::UniqueID fLastDrawnGlyphsID; 107 }; 108 109 // Text blobs/caches. 110 111 class TextBlob : public SkTLList<TextRun, 1> { 112 public: 113 typedef SkTArray<uint32_t, true> Key; 114 GetKey(const TextBlob * blob)115 static const Key& GetKey(const TextBlob* blob) { return blob->key(); } 116 Hash(const Key & key)117 static uint32_t Hash(const Key& key) { 118 SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map. 119 return SkOpts::hash(key.begin(), sizeof(uint32_t) * key.count()); 120 } 121 TextBlob(uint32_t blobId,const SkTextBlob * skBlob,const SkPaint & skPaint)122 TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint) 123 : fKey(&blobId, 1) { this->init(skBlob, skPaint); } 124 TextBlob(const Key & key,const SkTextBlob * skBlob,const SkPaint & skPaint)125 TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint) 126 : fKey(key) { 127 // 1-length keys are unterstood to be the blob id and must use the other constructor. 128 SkASSERT(fKey.count() > 1); 129 this->init(skBlob, skPaint); 130 } 131 key()132 const Key& key() const { return fKey; } 133 cpuMemorySize()134 size_t cpuMemorySize() const { return fCpuMemorySize; } 135 136 private: 137 void init(const SkTextBlob*, const SkPaint&); 138 139 const SkSTArray<1, uint32_t, true> fKey; 140 size_t fCpuMemorySize; 141 142 SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); 143 }; 144 145 const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&); 146 void purgeToFit(const TextBlob&); 147 148 GrAtlasTextContext* fFallbackTextContext; 149 SkTHashMap<uint32_t, TextBlob*> fBlobIdCache; 150 SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob> fBlobKeyCache; 151 SkTInternalLList<TextBlob> fLRUList; 152 size_t fCacheSize; 153 }; 154 155 #endif 156