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