• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
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 SkGlyphRunPainter_DEFINED
9 #define SkGlyphRunPainter_DEFINED
10 
11 #include "SkDistanceFieldGen.h"
12 #include "SkGlyphRun.h"
13 #include "SkScalerContext.h"
14 #include "SkSurfaceProps.h"
15 #include "SkTextBlobPriv.h"
16 
17 #if SK_SUPPORT_GPU
18 #include "text/GrTextContext.h"
19 class GrColorSpaceInfo;
20 class GrRenderTargetContext;
21 #endif
22 
23 class SkGlyphRunPainterInterface;
24 
25 class SkStrikeCommon {
26 public:
27     static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment);
28 
29     // This assumes that position has the appropriate rounding term applied.
30     static SkIPoint SubpixelLookup(SkAxisAlignment axisAlignment, SkPoint position);
31 
32     // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256.
33     // This means that the maximum size a glyph can be is 256x256.
34     static constexpr uint16_t kSkSideTooBigForAtlas = 256;
35 
36     static bool GlyphTooBigForAtlas(const SkGlyph& glyph);
37 };
38 
39 class SkGlyphRunListPainter {
40 public:
41     // Constructor for SkBitmpapDevice.
42     SkGlyphRunListPainter(const SkSurfaceProps& props,
43                           SkColorType colorType,
44                           SkColorSpace* cs,
45                           SkStrikeCacheInterface* strikeCache);
46 
47 #if SK_SUPPORT_GPU
48     // The following two ctors are used exclusively by the GPU, and will always use the global
49     // strike cache.
50     SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorSpaceInfo&);
51     explicit SkGlyphRunListPainter(const GrRenderTargetContext& renderTargetContext);
52 #endif  // SK_SUPPORT_GPU
53 
54     class BitmapDevicePainter {
55     public:
56         virtual ~BitmapDevicePainter() = default;
57 
58         virtual void paintPaths(SkSpan<const SkPathPos> pathsAndPositions,
59                                 SkScalar scale,
60                                 const SkPaint& paint) const = 0;
61 
62         virtual void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const = 0;
63     };
64 
65     void drawForBitmapDevice(
66             const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix,
67             const BitmapDevicePainter* bitmapDevice);
68 
69 #if SK_SUPPORT_GPU
70     // A nullptr for process means that the calls to the cache will be performed, but none of the
71     // callbacks will be called.
72     void processGlyphRunList(const SkGlyphRunList& glyphRunList,
73                              const SkMatrix& viewMatrix,
74                              const SkSurfaceProps& props,
75                              bool contextSupportsDistanceFieldText,
76                              const GrTextContext::Options& options,
77                              SkGlyphRunPainterInterface* process);
78 #endif  // SK_SUPPORT_GPU
79 
80     // TODO: Make this the canonical check for Skia.
81     static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix);
82 
83 private:
84     SkGlyphRunListPainter(const SkSurfaceProps& props, SkColorType colorType,
85                           SkScalerContextFlags flags, SkStrikeCacheInterface* strikeCache);
86 
87     struct ScopedBuffers {
88         ScopedBuffers(SkGlyphRunListPainter* painter, int size);
89         ~ScopedBuffers();
90         SkGlyphRunListPainter* fPainter;
91     };
92 
93     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList);
94 
95     // TODO: Remove once I can hoist ensureBuffers above the list for loop in all cases.
96     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun);
97 
98     /**
99      *  @param fARGBPositions in source space
100      *  @param fARGBGlyphsIDs the glyphs to process
101      *  @param fGlyphPos used as scratch space
102      *  @param maxSourceGlyphDimension the longest dimension of any glyph as if all fARGBGlyphsIDs
103      *                                 were drawn in source space (as if viewMatrix were identity)
104      */
105     void processARGBFallback(SkScalar maxSourceGlyphDimension,
106                              const SkPaint& runPaint,
107                              const SkFont& runFont,
108                              const SkMatrix& viewMatrix,
109                              SkGlyphRunPainterInterface* process);
110 
111     // The props as on the actual device.
112     const SkSurfaceProps fDeviceProps;
113     // The props for when the bitmap device can't draw LCD text.
114     const SkSurfaceProps fBitmapFallbackProps;
115     const SkColorType fColorType;
116     const SkScalerContextFlags fScalerContextFlags;
117 
118     SkStrikeCacheInterface* const fStrikeCache;
119 
120     int fMaxRunSize{0};
121     SkAutoTMalloc<SkPoint> fPositions;
122     SkAutoTMalloc<SkGlyphPos> fGlyphPos;
123 
124     std::vector<SkGlyphPos> fPaths;
125 
126     // Vectors for tracking ARGB fallback information.
127     std::vector<SkGlyphID> fARGBGlyphsIDs;
128     std::vector<SkPoint>   fARGBPositions;
129 };
130 
131 // SkGlyphRunPainterInterface are all the ways that Ganesh generates glyphs. The first
132 // distinction is between Device and Source.
133 // * Device - the data in the cache is scaled to the device. There is no transformation from the
134 //   cache to the screen.
135 // * Source - the data in the cache needs to be scaled from the cache to source space using the
136 //   factor cacheToSourceScale. When drawn the system must combine cacheToSourceScale and the
137 //   deviceView matrix to transform the cache data onto the screen. This allows zooming and
138 //   simple animation to reuse the same glyph data by just changing the transform.
139 //
140 // In addition to transformation type above, Masks, Paths, SDFT, and Fallback (or really the
141 // rendering method of last resort) are the different
142 // formats of data used from the cache.
143 class SkGlyphRunPainterInterface {
144 public:
145     virtual ~SkGlyphRunPainterInterface() = default;
146 
147     virtual void startRun(const SkGlyphRun& glyphRun, bool useSDFT) = 0;
148 
149     virtual void processDeviceMasks(SkSpan<const SkGlyphPos> masks,
150                                     SkStrikeInterface* strike) = 0;
151 
152     virtual void processSourcePaths(SkSpan<const SkGlyphPos> paths,
153                                     SkStrikeInterface* strike, SkScalar cacheToSourceScale) = 0;
154 
155     virtual void processDevicePaths(SkSpan<const SkGlyphPos> paths) = 0;
156 
157     virtual void processSourceSDFT(SkSpan<const SkGlyphPos> masks,
158                                    SkStrikeInterface* strike,
159                                    const SkFont& runFont,
160                                    SkScalar cacheToSourceScale,
161                                    SkScalar minScale,
162                                    SkScalar maxScale,
163                                    bool hasWCoord) = 0;
164 
165     virtual void processSourceFallback(SkSpan<const SkGlyphPos> masks,
166                                        SkStrikeInterface* strike,
167                                        SkScalar cacheToSourceScale,
168                                        bool hasW) = 0;
169 
170     virtual void processDeviceFallback(SkSpan<const SkGlyphPos> masks,
171                                        SkStrikeInterface* strike) = 0;
172 
173 };
174 
175 #endif  // SkGlyphRunPainter_DEFINED
176