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 | |
| 11 | #include "GrTextContext.h" |
cdalton | b2808cd | 2014-07-25 14:13:57 -0700 | [diff] [blame] | 12 | #include "GrDrawTarget.h" |
kkinnunen | 50b58e6 | 2015-05-18 23:02:07 -0700 | [diff] [blame] | 13 | #include "GrStrokeInfo.h" |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 14 | #include "SkTHash.h" |
| 15 | #include "SkTInternalLList.h" |
| 16 | #include "SkTLList.h" |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 17 | |
| 18 | class GrTextStrike; |
| 19 | class GrPath; |
robertphillips | fcf7829 | 2015-06-19 11:49:52 -0700 | [diff] [blame] | 20 | class SkSurfaceProps; |
cdalton | 8ff8d24 | 2015-12-08 10:20:32 -0800 | [diff] [blame^] | 21 | class GrPathRangeDraw; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 22 | |
| 23 | /* |
| 24 | * This class implements text rendering using stencil and cover path rendering |
| 25 | * (by the means of GrDrawTarget::drawPath). |
| 26 | * This class exposes the functionality through GrTextContext interface. |
| 27 | */ |
| 28 | class GrStencilAndCoverTextContext : public GrTextContext { |
| 29 | public: |
robertphillips | f6703fa | 2015-09-01 05:36:47 -0700 | [diff] [blame] | 30 | static GrStencilAndCoverTextContext* Create(GrContext*, const SkSurfaceProps&); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 31 | |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 32 | virtual ~GrStencilAndCoverTextContext(); |
| 33 | |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 34 | private: |
robertphillips | f6703fa | 2015-09-01 05:36:47 -0700 | [diff] [blame] | 35 | GrStencilAndCoverTextContext(GrContext*, const SkSurfaceProps&); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 36 | |
robertphillips | 6ee690e | 2015-12-02 08:57:50 -0800 | [diff] [blame] | 37 | bool canDraw(const SkPaint& skPaint, const SkMatrix&) override { |
| 38 | return this->internalCanDraw(skPaint); |
| 39 | } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 40 | |
| 41 | bool internalCanDraw(const SkPaint&); |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 42 | |
robertphillips | 433625e | 2015-12-04 06:58:16 -0800 | [diff] [blame] | 43 | void onDrawText(GrDrawContext*, const GrClip&, const GrPaint&, const SkPaint&, |
cdalton | e68f736 | 2015-03-25 14:02:37 -0700 | [diff] [blame] | 44 | const SkMatrix& viewMatrix, |
| 45 | const char text[], size_t byteLength, |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 46 | SkScalar x, SkScalar y, const SkIRect& clipBounds) override; |
robertphillips | 433625e | 2015-12-04 06:58:16 -0800 | [diff] [blame] | 47 | void onDrawPosText(GrDrawContext*, |
robertphillips | f6703fa | 2015-09-01 05:36:47 -0700 | [diff] [blame] | 48 | const GrClip&, const GrPaint&, const SkPaint&, |
cdalton | e68f736 | 2015-03-25 14:02:37 -0700 | [diff] [blame] | 49 | const SkMatrix& viewMatrix, |
| 50 | const char text[], size_t byteLength, |
| 51 | const SkScalar pos[], int scalarsPerPosition, |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 52 | const SkPoint& offset, const SkIRect& clipBounds) override; |
robertphillips | 433625e | 2015-12-04 06:58:16 -0800 | [diff] [blame] | 53 | void drawTextBlob(GrDrawContext*, const GrClip&, const SkPaint&, |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 54 | const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y, |
| 55 | SkDrawFilter*, const SkIRect& clipBounds) override; |
jvanverth | 8c27a18 | 2014-10-14 08:45:50 -0700 | [diff] [blame] | 56 | |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 57 | class FallbackBlobBuilder; |
| 58 | |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 59 | class TextRun { |
| 60 | public: |
| 61 | TextRun(const SkPaint& fontAndStroke); |
| 62 | ~TextRun(); |
| 63 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 64 | void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 65 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 66 | void setPosText(const char text[], size_t byteLength, const SkScalar pos[], |
| 67 | int scalarsPerPosition, const SkPoint& offset); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 68 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 69 | void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&, |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 70 | SkScalar x, SkScalar y, const SkIRect& clipBounds, |
| 71 | GrTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const; |
| 72 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 73 | void releaseGlyphCache() const; |
| 74 | |
| 75 | size_t computeSizeInCache() const; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 76 | |
| 77 | private: |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 78 | SkGlyphCache* getGlyphCache() const; |
| 79 | GrPathRange* createGlyphs(GrContext*) const; |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 80 | void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*); |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 81 | |
| 82 | GrStrokeInfo fStroke; |
| 83 | SkPaint fFont; |
| 84 | SkScalar fTextRatio; |
| 85 | float fTextInverseRatio; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 86 | bool fUsingRawGlyphPaths; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 87 | GrUniqueKey fGlyphPathsKey; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 88 | int fTotalGlyphCount; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 89 | SkAutoTUnref<GrPathRangeDraw> fDraw; |
cdalton | 02015e5 | 2015-10-05 15:28:20 -0700 | [diff] [blame] | 90 | SkAutoTUnref<const SkTextBlob> fFallbackTextBlob; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 91 | mutable SkGlyphCache* fDetachedGlyphCache; |
| 92 | mutable uint32_t fLastDrawnGlyphsID; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 93 | mutable SkMatrix fLocalMatrixTemplate; |
cdalton | 3bd909a | 2015-10-05 14:57:20 -0700 | [diff] [blame] | 94 | }; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 95 | |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 96 | // Text blobs/caches. |
| 97 | |
bsalomon | f045d60 | 2015-11-18 19:01:12 -0800 | [diff] [blame] | 98 | class TextBlob : public SkTLList<TextRun, 1> { |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 99 | public: |
| 100 | typedef SkTArray<uint32_t, true> Key; |
| 101 | |
| 102 | static const Key& GetKey(const TextBlob* blob) { return blob->key(); } |
| 103 | |
| 104 | static uint32_t Hash(const Key& key) { |
| 105 | SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map. |
| 106 | return SkChecksum::Murmur3(key.begin(), sizeof(uint32_t) * key.count()); |
| 107 | } |
| 108 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 109 | TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint) |
| 110 | : fKey(&blobId, 1) { this->init(skBlob, skPaint); } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 111 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 112 | TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint) |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 113 | : fKey(key) { |
| 114 | // 1-length keys are unterstood to be the blob id and must use the other constructor. |
| 115 | SkASSERT(fKey.count() > 1); |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 116 | this->init(skBlob, skPaint); |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | const Key& key() const { return fKey; } |
| 120 | |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 121 | size_t cpuMemorySize() const { return fCpuMemorySize; } |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 122 | |
| 123 | private: |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 124 | void init(const SkTextBlob*, const SkPaint&); |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 125 | |
| 126 | const SkSTArray<1, uint32_t, true> fKey; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 127 | size_t fCpuMemorySize; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 128 | |
| 129 | SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); |
| 130 | }; |
| 131 | |
| 132 | const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&); |
| 133 | void purgeToFit(const TextBlob&); |
| 134 | |
| 135 | SkTHashMap<uint32_t, TextBlob*> fBlobIdCache; |
| 136 | SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob> fBlobKeyCache; |
| 137 | SkTInternalLList<TextBlob> fLRUList; |
cdalton | 8585dd2 | 2015-10-08 08:04:09 -0700 | [diff] [blame] | 138 | size_t fCacheSize; |
cdalton | cdd7907 | 2015-10-05 15:37:35 -0700 | [diff] [blame] | 139 | |
bsalomon | 1fcc01c | 2015-09-09 09:48:06 -0700 | [diff] [blame] | 140 | typedef GrTextContext INHERITED; |
kkinnunen | c6cb56f | 2014-06-24 00:12:27 -0700 | [diff] [blame] | 141 | }; |
| 142 | |
| 143 | #endif |