kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 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 | |
cdalton | b2808cd | 2014-07-25 14:13:57 -0700 | [diff] [blame] | 11 | #include "GrDrawTarget.h" |
kkinnunen | 50b58e6 | 2015-05-18 23:02:07 -0700 | [diff] [blame] | 12 | #include "GrStrokeInfo.h" |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 13 | #include "SkDrawFilter.h" |
| 14 | #include "SkTextBlob.h" |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 15 | #include "SkTHash.h" |
| 16 | #include "SkTInternalLList.h" |
| 17 | #include "SkTLList.h" |
cdalton | cdd4682 | 2015-12-08 10:48:31 -0800 | [diff] [blame] | 18 | #include "batches/GrDrawPathBatch.h" |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 19 | |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 20 | class GrAtlasTextContext; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 21 | class GrTextStrike; |
| 22 | class GrPath; |
robertphillips | fcf7829 | 2015-06-19 11:49:52 -0700 | [diff] [blame] | 23 | class SkSurfaceProps; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 24 | |
| 25 | /* |
| 26 | * This class implements text rendering using stencil and cover path rendering |
| 27 | * (by the means of GrDrawTarget::drawPath). |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 28 | */ |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 29 | class GrStencilAndCoverTextContext { |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 30 | public: |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 31 | static GrStencilAndCoverTextContext* Create(); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 32 | |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 33 | void drawText(GrContext*, GrDrawContext* dc, |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 34 | const GrClip&, const GrPaint&, const SkPaint&, |
joshualitt | 2c89bc1 | 2016-02-11 05:42:30 -0800 | [diff] [blame] | 35 | const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], |
| 36 | size_t byteLength, SkScalar x, |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 37 | SkScalar y, const SkIRect& clipBounds); |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 38 | void drawPosText(GrContext*, GrDrawContext*, |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 39 | const GrClip&, const GrPaint&, const SkPaint&, |
joshualitt | 2c89bc1 | 2016-02-11 05:42:30 -0800 | [diff] [blame] | 40 | const SkMatrix& viewMatrix, const SkSurfaceProps&, |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 41 | const char text[], size_t byteLength, |
| 42 | const SkScalar pos[], int scalarsPerPosition, |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 43 | const SkPoint& offset, const SkIRect& clipBounds); |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 44 | void drawTextBlob(GrContext*, GrDrawContext*, const GrClip&, const SkPaint&, |
joshualitt | 2c89bc1 | 2016-02-11 05:42:30 -0800 | [diff] [blame] | 45 | const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*, |
| 46 | SkScalar x, SkScalar y, |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 47 | SkDrawFilter*, const SkIRect& clipBounds); |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 48 | |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 49 | virtual ~GrStencilAndCoverTextContext(); |
| 50 | |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 51 | private: |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 52 | GrStencilAndCoverTextContext(); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 53 | |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 54 | bool canDraw(const SkPaint& skPaint, const SkMatrix&) { |
robertphillips | 6ee690e | 2015-12-02 08:57:50 -0800 | [diff] [blame] | 55 | return this->internalCanDraw(skPaint); |
| 56 | } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 57 | |
| 58 | bool internalCanDraw(const SkPaint&); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 59 | |
joshualitt | 27004b7 | 2016-02-11 12:00:33 -0800 | [diff] [blame] | 60 | void uncachedDrawTextBlob(GrContext*, GrDrawContext* dc, |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 61 | const GrClip& clip, const SkPaint& skPaint, |
| 62 | const SkMatrix& viewMatrix, |
joshualitt | 2c89bc1 | 2016-02-11 05:42:30 -0800 | [diff] [blame] | 63 | const SkSurfaceProps&, |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 64 | const SkTextBlob* blob, |
| 65 | SkScalar x, SkScalar y, |
| 66 | SkDrawFilter* drawFilter, |
| 67 | const SkIRect& clipBounds); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 68 | |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 69 | class FallbackBlobBuilder; |
| 70 | |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 71 | class TextRun { |
| 72 | public: |
| 73 | TextRun(const SkPaint& fontAndStroke); |
| 74 | ~TextRun(); |
| 75 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 76 | void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 77 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 78 | void setPosText(const char text[], size_t byteLength, const SkScalar pos[], |
| 79 | int scalarsPerPosition, const SkPoint& offset); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 80 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 81 | void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&, |
joshualitt | 2c89bc1 | 2016-02-11 05:42:30 -0800 | [diff] [blame] | 82 | const SkSurfaceProps&, |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 83 | SkScalar x, SkScalar y, const SkIRect& clipBounds, |
joshualitt | 8e84a1e | 2016-02-16 11:09:25 -0800 | [diff] [blame] | 84 | GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 85 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 86 | void releaseGlyphCache() const; |
| 87 | |
| 88 | size_t computeSizeInCache() const; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 89 | |
| 90 | private: |
cdalton | cdd4682 | 2015-12-08 10:48:31 -0800 | [diff] [blame] | 91 | typedef GrDrawPathRangeBatch::InstanceData InstanceData; |
| 92 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 93 | SkGlyphCache* getGlyphCache() const; |
| 94 | GrPathRange* createGlyphs(GrContext*) const; |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 95 | void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 96 | |
| 97 | GrStrokeInfo fStroke; |
| 98 | SkPaint fFont; |
| 99 | SkScalar fTextRatio; |
| 100 | float fTextInverseRatio; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 101 | bool fUsingRawGlyphPaths; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 102 | GrUniqueKey fGlyphPathsKey; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 103 | int fTotalGlyphCount; |
cdalton | cdd4682 | 2015-12-08 10:48:31 -0800 | [diff] [blame] | 104 | SkAutoTUnref<InstanceData> fInstanceData; |
| 105 | int fFallbackGlyphCount; |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 106 | SkAutoTUnref<const SkTextBlob> fFallbackTextBlob; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 107 | mutable SkGlyphCache* fDetachedGlyphCache; |
| 108 | mutable uint32_t fLastDrawnGlyphsID; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 109 | }; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 110 | |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 111 | // Text blobs/caches. |
| 112 | |
bsalomon | f045d60 | 2015-11-18 19:01:12 -0800 | [diff] [blame] | 113 | class TextBlob : public SkTLList<TextRun, 1> { |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 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 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 124 | TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint) |
| 125 | : fKey(&blobId, 1) { this->init(skBlob, skPaint); } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 126 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 127 | TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint) |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 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); |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 131 | this->init(skBlob, skPaint); |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | const Key& key() const { return fKey; } |
| 135 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 136 | size_t cpuMemorySize() const { return fCpuMemorySize; } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 137 | |
| 138 | private: |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 139 | void init(const SkTextBlob*, const SkPaint&); |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 140 | |
| 141 | const SkSTArray<1, uint32_t, true> fKey; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 142 | size_t fCpuMemorySize; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 143 | |
| 144 | SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); |
| 145 | }; |
| 146 | |
| 147 | const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&); |
| 148 | void purgeToFit(const TextBlob&); |
| 149 | |
joshualitt | e55750e | 2016-02-10 12:52:21 -0800 | [diff] [blame] | 150 | GrAtlasTextContext* fFallbackTextContext; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 151 | SkTHashMap<uint32_t, TextBlob*> fBlobIdCache; |
| 152 | SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob> fBlobKeyCache; |
| 153 | SkTInternalLList<TextBlob> fLRUList; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 154 | size_t fCacheSize; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 155 | }; |
| 156 | |
| 157 | #endif |