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 GrTextUtils_DEFINED
9 #define GrTextUtils_DEFINED
10 
11 #include "GrColor.h"
12 #include "SkColorFilter.h"
13 #include "SkGr.h"
14 #include "SkPaint.h"
15 #include "SkScalar.h"
16 #include "SkTLazy.h"
17 
18 class GrAtlasGlyphCache;
19 class GrAtlasTextBlob;
20 class GrAtlasTextStrike;
21 class GrClip;
22 class GrContext;
23 class GrPaint;
24 class GrRenderTargetContext;
25 class GrShaderCaps;
26 class SkDrawFilter;
27 class SkGlyph;
28 class SkMatrix;
29 struct SkIRect;
30 struct SkPoint;
31 class SkGlyphCache;
32 class SkTextBlobRunIterator;
33 class SkSurfaceProps;
34 
35 /**
36  * A class to house a bunch of common text utilities.  This class should *ONLY* have static
37  * functions.  It is not a namespace only because we wish to friend SkPaint
38  */
39 class GrTextUtils {
40 public:
41     /**
42      *  This is used to wrap a SkPaint and its post-color filter color. It is also used by RunPaint
43      *  (below). This keeps a pointer to the SkPaint it is initialized with and expects it to remain
44      *  const. It is also used to transform to GrPaint.
45      */
46     class Paint {
47     public:
Paint(const SkPaint * paint)48         explicit Paint(const SkPaint* paint) : fPaint(paint) { this->initFilteredColor(); }
49 
50         // These expose the paint's color run through its color filter (if any). This is only valid
51         // when drawing grayscale/lcd glyph masks and not when drawing color glyphs.
filteredSkColor()52         SkColor filteredSkColor() const { return fFilteredSkColor; }
filteredPremulGrColor()53         GrColor filteredPremulGrColor() const { return fFilteredGrColor; }
54 
skPaint()55         const SkPaint& skPaint() const { return *fPaint; }
56         operator const SkPaint&() const { return this->skPaint(); }
57 
58         bool toGrPaint(GrMaskFormat, GrRenderTargetContext*, const SkMatrix& viewMatrix,
59                        GrPaint*) const;
60 
61     protected:
initFilteredColor()62         void initFilteredColor() {
63             fFilteredSkColor = fPaint->getColor();
64             if (fPaint->getColorFilter()) {
65                 fFilteredSkColor = fPaint->getColorFilter()->filterColor(fFilteredSkColor);
66             }
67             fFilteredGrColor = SkColorToPremulGrColor(fFilteredSkColor);
68         }
69         Paint() = default;
70         const SkPaint* fPaint;
71         // This is the paint's color run through its color filter, if present. This color should
72         // be used except when rendering bitmap text, in which case the bitmap must be filtered in
73         // the fragment shader.
74         SkColor fFilteredSkColor;
75         SkColor fFilteredGrColor;
76     };
77 
78     /**
79      *  An extension of Paint that incorporated per-run modifications to the paint text settings and
80      *  application of a draw filter. It expects its constructor arguments to remain alive and const
81      *  during its lifetime.
82      */
83     class RunPaint : public Paint {
84     public:
RunPaint(const Paint * paint,SkDrawFilter * filter,const SkSurfaceProps & props)85         RunPaint(const Paint* paint, SkDrawFilter* filter, const SkSurfaceProps& props)
86                 : fOriginalPaint(paint), fFilter(filter), fProps(props) {
87             // Initially we represent the original paint.
88             fPaint = &fOriginalPaint->skPaint();
89             fFilteredSkColor = fOriginalPaint->filteredSkColor();
90             fFilteredGrColor = fOriginalPaint->filteredPremulGrColor();
91         }
92 
93         bool modifyForRun(const SkTextBlobRunIterator&);
94 
95     private:
96         SkTLazy<SkPaint> fModifiedPaint;
97         const Paint* fOriginalPaint;
98         SkDrawFilter* fFilter;
99         const SkSurfaceProps& fProps;
100     };
101 
102     // Functions for appending BMP text to GrAtlasTextBlob
103     static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
104                             const SkSurfaceProps&, const Paint& paint, uint32_t scalerContextFlags,
105                             const SkMatrix& viewMatrix, const char text[], size_t byteLength,
106                             SkScalar x, SkScalar y);
107 
108     static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
109                                const SkSurfaceProps&, const Paint& paint,
110                                uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
111                                const char text[], size_t byteLength, const SkScalar pos[],
112                                int scalarsPerPosition, const SkPoint& offset);
113 
114     // functions for appending distance field text
115     static bool CanDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
116                                         const SkSurfaceProps& props, const GrShaderCaps& caps);
117 
118     static void DrawDFText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
119                            const SkSurfaceProps&, const Paint& paint, uint32_t scalerContextFlags,
120                            const SkMatrix& viewMatrix, const char text[], size_t byteLength,
121                            SkScalar x, SkScalar y);
122 
123     static void DrawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
124                               const SkSurfaceProps&, const Paint& paint,
125                               uint32_t scalerContextFlags, const SkMatrix& viewMatrix,
126                               const char text[], size_t byteLength, const SkScalar pos[],
127                               int scalarsPerPosition, const SkPoint& offset);
128 
129     // Functions for drawing text as paths
130     static void DrawTextAsPath(GrContext*, GrRenderTargetContext*, const GrClip& clip,
131                                const SkPaint& paint, const SkMatrix& viewMatrix, const char text[],
132                                size_t byteLength, SkScalar x, SkScalar y,
133                                const SkIRect& clipBounds);
134 
135     static void DrawPosTextAsPath(GrContext* context, GrRenderTargetContext* rtc,
136                                   const SkSurfaceProps& props, const GrClip& clip,
137                                   const SkPaint& paint, const SkMatrix& viewMatrix,
138                                   const char text[], size_t byteLength, const SkScalar pos[],
139                                   int scalarsPerPosition, const SkPoint& offset,
140                                   const SkIRect& clipBounds);
141 
142     static bool ShouldDisableLCD(const SkPaint& paint);
143 
144 
145 private:
146     static uint32_t FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint);
147 
148     static void InitDistanceFieldPaint(GrAtlasTextBlob* blob,
149                                        SkPaint* skPaint,
150                                        SkScalar* textRatio,
151                                        const SkMatrix& viewMatrix);
152 
153     static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
154                                GrAtlasTextStrike**, const SkGlyph&, int left, int top,
155                                GrColor color, SkGlyphCache*);
156 
157     static bool DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
158                               GrAtlasTextStrike**, const SkGlyph&,
159                               SkScalar sx, SkScalar sy, GrColor color,
160                               SkGlyphCache* cache,
161                               SkScalar textRatio, const SkMatrix& viewMatrix);
162 };
163 
164 #endif
165