blob: 7716c784052a9ef4e01b2a928537e02dd6a8a9ba [file] [log] [blame]
kkinnunenc6cb56f2014-06-24 00:12:27 -07001/*
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"
cdaltonb2808cd2014-07-25 14:13:57 -070012#include "GrDrawTarget.h"
kkinnunen50b58e62015-05-18 23:02:07 -070013#include "GrStrokeInfo.h"
cdaltoncdd79072015-10-05 15:37:35 -070014#include "SkTHash.h"
15#include "SkTInternalLList.h"
16#include "SkTLList.h"
kkinnunenc6cb56f2014-06-24 00:12:27 -070017
18class GrTextStrike;
19class GrPath;
robertphillipsfcf78292015-06-19 11:49:52 -070020class SkSurfaceProps;
cdalton8ff8d242015-12-08 10:20:32 -080021class GrPathRangeDraw;
kkinnunenc6cb56f2014-06-24 00:12:27 -070022
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 */
28class GrStencilAndCoverTextContext : public GrTextContext {
29public:
robertphillipsf6703fa2015-09-01 05:36:47 -070030 static GrStencilAndCoverTextContext* Create(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070031
kkinnunenc6cb56f2014-06-24 00:12:27 -070032 virtual ~GrStencilAndCoverTextContext();
33
kkinnunenc6cb56f2014-06-24 00:12:27 -070034private:
robertphillipsf6703fa2015-09-01 05:36:47 -070035 GrStencilAndCoverTextContext(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070036
robertphillips6ee690e2015-12-02 08:57:50 -080037 bool canDraw(const SkPaint& skPaint, const SkMatrix&) override {
38 return this->internalCanDraw(skPaint);
39 }
cdaltoncdd79072015-10-05 15:37:35 -070040
41 bool internalCanDraw(const SkPaint&);
jvanverth8c27a182014-10-14 08:45:50 -070042
robertphillips433625e2015-12-04 06:58:16 -080043 void onDrawText(GrDrawContext*, const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070044 const SkMatrix& viewMatrix,
45 const char text[], size_t byteLength,
cdaltoncdd79072015-10-05 15:37:35 -070046 SkScalar x, SkScalar y, const SkIRect& clipBounds) override;
robertphillips433625e2015-12-04 06:58:16 -080047 void onDrawPosText(GrDrawContext*,
robertphillipsf6703fa2015-09-01 05:36:47 -070048 const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070049 const SkMatrix& viewMatrix,
50 const char text[], size_t byteLength,
51 const SkScalar pos[], int scalarsPerPosition,
cdaltoncdd79072015-10-05 15:37:35 -070052 const SkPoint& offset, const SkIRect& clipBounds) override;
robertphillips433625e2015-12-04 06:58:16 -080053 void drawTextBlob(GrDrawContext*, const GrClip&, const SkPaint&,
cdaltoncdd79072015-10-05 15:37:35 -070054 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
55 SkDrawFilter*, const SkIRect& clipBounds) override;
jvanverth8c27a182014-10-14 08:45:50 -070056
cdalton02015e52015-10-05 15:28:20 -070057 class FallbackBlobBuilder;
58
cdalton3bd909a2015-10-05 14:57:20 -070059 class TextRun {
60 public:
61 TextRun(const SkPaint& fontAndStroke);
62 ~TextRun();
63
cdalton8585dd22015-10-08 08:04:09 -070064 void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y);
cdalton3bd909a2015-10-05 14:57:20 -070065
cdalton8585dd22015-10-08 08:04:09 -070066 void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
67 int scalarsPerPosition, const SkPoint& offset);
cdalton3bd909a2015-10-05 14:57:20 -070068
cdalton8585dd22015-10-08 08:04:09 -070069 void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&,
cdaltoncdd79072015-10-05 15:37:35 -070070 SkScalar x, SkScalar y, const SkIRect& clipBounds,
71 GrTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
72
cdalton8585dd22015-10-08 08:04:09 -070073 void releaseGlyphCache() const;
74
75 size_t computeSizeInCache() const;
cdalton3bd909a2015-10-05 14:57:20 -070076
77 private:
cdalton8585dd22015-10-08 08:04:09 -070078 SkGlyphCache* getGlyphCache() const;
79 GrPathRange* createGlyphs(GrContext*) const;
cdalton02015e52015-10-05 15:28:20 -070080 void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*);
cdalton3bd909a2015-10-05 14:57:20 -070081
82 GrStrokeInfo fStroke;
83 SkPaint fFont;
84 SkScalar fTextRatio;
85 float fTextInverseRatio;
cdalton3bd909a2015-10-05 14:57:20 -070086 bool fUsingRawGlyphPaths;
cdalton8585dd22015-10-08 08:04:09 -070087 GrUniqueKey fGlyphPathsKey;
cdaltoncdd79072015-10-05 15:37:35 -070088 int fTotalGlyphCount;
cdalton3bd909a2015-10-05 14:57:20 -070089 SkAutoTUnref<GrPathRangeDraw> fDraw;
cdalton02015e52015-10-05 15:28:20 -070090 SkAutoTUnref<const SkTextBlob> fFallbackTextBlob;
cdalton8585dd22015-10-08 08:04:09 -070091 mutable SkGlyphCache* fDetachedGlyphCache;
92 mutable uint32_t fLastDrawnGlyphsID;
cdaltoncdd79072015-10-05 15:37:35 -070093 mutable SkMatrix fLocalMatrixTemplate;
cdalton3bd909a2015-10-05 14:57:20 -070094 };
kkinnunenc6cb56f2014-06-24 00:12:27 -070095
cdaltoncdd79072015-10-05 15:37:35 -070096 // Text blobs/caches.
97
bsalomonf045d602015-11-18 19:01:12 -080098 class TextBlob : public SkTLList<TextRun, 1> {
cdaltoncdd79072015-10-05 15:37:35 -070099 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
cdalton8585dd22015-10-08 08:04:09 -0700109 TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint)
110 : fKey(&blobId, 1) { this->init(skBlob, skPaint); }
cdaltoncdd79072015-10-05 15:37:35 -0700111
cdalton8585dd22015-10-08 08:04:09 -0700112 TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint)
cdaltoncdd79072015-10-05 15:37:35 -0700113 : fKey(key) {
114 // 1-length keys are unterstood to be the blob id and must use the other constructor.
115 SkASSERT(fKey.count() > 1);
cdalton8585dd22015-10-08 08:04:09 -0700116 this->init(skBlob, skPaint);
cdaltoncdd79072015-10-05 15:37:35 -0700117 }
118
119 const Key& key() const { return fKey; }
120
cdalton8585dd22015-10-08 08:04:09 -0700121 size_t cpuMemorySize() const { return fCpuMemorySize; }
cdaltoncdd79072015-10-05 15:37:35 -0700122
123 private:
cdalton8585dd22015-10-08 08:04:09 -0700124 void init(const SkTextBlob*, const SkPaint&);
cdaltoncdd79072015-10-05 15:37:35 -0700125
126 const SkSTArray<1, uint32_t, true> fKey;
cdalton8585dd22015-10-08 08:04:09 -0700127 size_t fCpuMemorySize;
cdaltoncdd79072015-10-05 15:37:35 -0700128
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;
cdalton8585dd22015-10-08 08:04:09 -0700138 size_t fCacheSize;
cdaltoncdd79072015-10-05 15:37:35 -0700139
bsalomon1fcc01c2015-09-09 09:48:06 -0700140 typedef GrTextContext INHERITED;
kkinnunenc6cb56f2014-06-24 00:12:27 -0700141};
142
143#endif