• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 class GrAtlasTextContext;
21 class GrTextStrike;
22 class GrPath;
23 class SkSurfaceProps;
24 
25 /*
26  * This class implements text rendering using stencil and cover path rendering
27  * (by the means of GrDrawTarget::drawPath).
28  */
29 class GrStencilAndCoverTextContext {
30 public:
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 
51 private:
52     GrStencilAndCoverTextContext();
53 
canDraw(const SkPaint & skPaint,const SkMatrix &)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 
GetKey(const TextBlob * blob)117         static const Key& GetKey(const TextBlob* blob) { return blob->key(); }
118 
Hash(const Key & key)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 
TextBlob(uint32_t blobId,const SkTextBlob * skBlob,const SkPaint & skPaint)124         TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint)
125             : fKey(&blobId, 1) { this->init(skBlob, skPaint); }
126 
TextBlob(const Key & key,const SkTextBlob * skBlob,const SkPaint & skPaint)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 
key()134         const Key& key() const { return fKey; }
135 
cpuMemorySize()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