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