• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 GrAtlasTextContext_DEFINED
9 #define GrAtlasTextContext_DEFINED
10 
11 #include "GrAtlasTextBlob.h"
12 #include "GrDistanceFieldAdjustTable.h"
13 #include "GrGeometryProcessor.h"
14 #include "GrTextUtils.h"
15 #include "SkTextBlobRunIterator.h"
16 
17 #if GR_TEST_UTILS
18 #include "GrDrawOpTest.h"
19 #endif
20 
21 class GrDrawOp;
22 class GrTextBlobCache;
23 class SkGlyph;
24 
25 /*
26  * Renders text using some kind of an atlas, ie BitmapText or DistanceField text
27  */
28 class GrAtlasTextContext {
29 public:
30     struct Options {
31         /**
32          * Below this size (in device space) distance field text will not be used. Negative means
33          * use a default value.
34          */
35         SkScalar fMinDistanceFieldFontSize = -1.f;
36         /**
37          * Above this size (in device space) distance field text will not be used and glyphs will
38          * be rendered from outline as individual paths. Negative means use a default value.
39          */
40         SkScalar fMaxDistanceFieldFontSize = -1.f;
41         /** Forces all distance field vertices to use 3 components, not just when in perspective. */
42         bool fDistanceFieldVerticesAlwaysHaveW = false;
43     };
44 
45     static std::unique_ptr<GrAtlasTextContext> Make(const Options& options);
46 
47     void drawText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
48                   const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
49                   size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds);
50     void drawPosText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
51                      const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
52                      size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
53                      const SkPoint& offset, const SkIRect& regionClipBounds);
54     void drawTextBlob(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
55                       const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*,
56                       SkScalar x, SkScalar y, SkDrawFilter*, const SkIRect& clipBounds);
57 
58 private:
59     GrAtlasTextContext(const Options& options);
60 
61     class FallbackTextHelper {
62     public:
FallbackTextHelper(const SkMatrix & viewMatrix,const SkPaint & pathPaint,const GrGlyphCache * glyphCache,SkScalar textRatio)63         FallbackTextHelper(const SkMatrix& viewMatrix,
64                            const SkPaint& pathPaint,
65                            const GrGlyphCache* glyphCache,
66                            SkScalar textRatio)
67             : fViewMatrix(viewMatrix)
68             , fTextSize(pathPaint.getTextSize())
69             , fMaxTextSize(glyphCache->getGlyphSizeLimit())
70             , fTextRatio(textRatio)
71             , fScaledFallbackTextSize(fMaxTextSize)
72             , fUseScaledFallback(false) {
73             fMaxScale = viewMatrix.getMaxScale();
74         }
75 
76         void appendText(const SkGlyph& glyph, int count, const char* text, SkPoint glyphPos);
77         void drawText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&,
78                       const GrTextUtils::Paint&, SkScalerContextFlags);
79 
80     private:
81         SkTDArray<char> fFallbackTxt;
82         SkTDArray<SkPoint> fFallbackPos;
83 
84         const SkMatrix& fViewMatrix;
85         SkScalar fTextSize;
86         SkScalar fMaxTextSize;
87         SkScalar fTextRatio;
88         SkScalar fScaledFallbackTextSize;
89         SkScalar fMaxScale;
90         bool fUseScaledFallback;
91     };
92 
93     // sets up the descriptor on the blob and returns a detached cache.  Client must attach
94     static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd);
95     // Determines if we need to use fake gamma (and contrast boost):
96     static SkScalerContextFlags ComputeScalerContextFlags(const GrColorSpaceInfo&);
97     void regenerateTextBlob(GrAtlasTextBlob* bmp,
98                             GrGlyphCache*,
99                             const GrShaderCaps&,
100                             const GrTextUtils::Paint&,
101                             SkScalerContextFlags scalerContextFlags,
102                             const SkMatrix& viewMatrix,
103                             const SkSurfaceProps&,
104                             const SkTextBlob* blob, SkScalar x, SkScalar y,
105                             SkDrawFilter* drawFilter) const;
106 
107     static bool HasLCD(const SkTextBlob*);
108 
109     sk_sp<GrAtlasTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrGlyphCache*,
110                                             const GrShaderCaps&,
111                                             const GrTextUtils::Paint&,
112                                             SkScalerContextFlags scalerContextFlags,
113                                             const SkMatrix& viewMatrix,
114                                             const SkSurfaceProps&,
115                                             const char text[], size_t byteLength,
116                                             SkScalar x, SkScalar y) const;
117 
118     sk_sp<GrAtlasTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*,
119                                                const GrShaderCaps&,
120                                                const GrTextUtils::Paint&,
121                                                SkScalerContextFlags scalerContextFlags,
122                                                const SkMatrix& viewMatrix,
123                                                const SkSurfaceProps&,
124                                                const char text[], size_t byteLength,
125                                                const SkScalar pos[],
126                                                int scalarsPerPosition,
127                                                const SkPoint& offset) const;
128 
129     // Functions for appending BMP text to GrAtlasTextBlob
130     static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
131                             const SkSurfaceProps&, const GrTextUtils::Paint& paint,
132                             SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
133                             const char text[], size_t byteLength, SkScalar x, SkScalar y);
134 
135     static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
136                                const SkSurfaceProps&, const GrTextUtils::Paint& paint,
137                                SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
138                                const char text[], size_t byteLength, const SkScalar pos[],
139                                int scalarsPerPosition, const SkPoint& offset);
140 
141     static void DrawBmpTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
142                                    const SkSurfaceProps&, const GrTextUtils::Paint& paint,
143                                    SkScalerContextFlags scalerContextFlags,
144                                    const SkMatrix& viewMatrix, const char text[],
145                                    size_t byteLength, SkScalar x, SkScalar y);
146 
147     static void DrawBmpPosTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
148                                       const SkSurfaceProps&, const GrTextUtils::Paint& paint,
149                                       SkScalerContextFlags scalerContextFlags,
150                                       const SkMatrix& viewMatrix,
151                                       const char text[], size_t byteLength,
152                                       const SkScalar pos[], int scalarsPerPosition,
153                                       const SkPoint& offset);
154 
155     // functions for appending distance field text
156     bool canDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
157                                  const SkSurfaceProps& props, const GrShaderCaps& caps) const;
158 
159     void drawDFText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&,
160                     const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags,
161                     const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
162                     SkScalar y) const;
163 
164     void drawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*,
165                        const SkSurfaceProps&, const GrTextUtils::Paint& paint,
166                        SkScalerContextFlags scalerContextFlags,
167                        const SkMatrix& viewMatrix, const char text[],
168                        size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
169                        const SkPoint& offset) const;
170 
171     void initDistanceFieldPaint(GrAtlasTextBlob* blob,
172                                 SkPaint* skPaint,
173                                 SkScalar* textRatio,
174                                 const SkMatrix& viewMatrix) const;
175 
176     static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
177                                sk_sp<GrTextStrike>*, const SkGlyph&, SkScalar sx, SkScalar sy,
178                                GrColor color, SkGlyphCache*, SkScalar textRatio);
179 
180     static void DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*,
181                               sk_sp<GrTextStrike>*, const SkGlyph&, SkScalar sx, SkScalar sy,
182                               GrColor color, SkGlyphCache* cache, SkScalar textRatio);
183 
dfAdjustTable()184     const GrDistanceFieldAdjustTable* dfAdjustTable() const { return fDistanceAdjustTable.get(); }
185 
186     sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
187 
188     SkScalar fMinDistanceFieldFontSize;
189     SkScalar fMaxDistanceFieldFontSize;
190     bool fDistanceFieldVerticesAlwaysHaveW;
191 
192 #if GR_TEST_UTILS
193     static const SkScalerContextFlags kTextBlobOpScalerContextFlags =
194             SkScalerContextFlags::kFakeGammaAndBoostContrast;
195     GR_DRAW_OP_TEST_FRIEND(GrAtlasTextOp);
196 #endif
197 };
198 
199 #endif
200