• 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/SkGlyphBuffer.h"
14 #include "src/core/SkGlyphRun.h"
15 #include "src/core/SkScalerContext.h"
16 #include "src/core/SkTextBlobPriv.h"
17 
18 #if SK_SUPPORT_GPU
19 #include "src/gpu/text/GrSDFTControl.h"
20 class GrColorInfo;
21 namespace skgpu { namespace v1 { class SurfaceDrawContext; }}
22 #endif
23 
24 class SkGlyphRunPainterInterface;
25 class SkStrikeSpec;
26 class GrSDFTMatrixRange;
27 
28 // round and ignorePositionMask are used to calculate the subpixel position of a glyph.
29 // The per component (x or y) calculation is:
30 //
31 //   subpixelOffset = (floor((viewportPosition + rounding) & mask) >> 14) & 3
32 //
33 // where mask is either 0 or ~0, and rounding is either
34 // 1/2 for non-subpixel or 1/8 for subpixel.
35 struct SkGlyphPositionRoundingSpec {
36     SkGlyphPositionRoundingSpec(bool isSubpixel, SkAxisAlignment axisAlignment);
37     const SkVector halfAxisSampleFreq;
38     const SkIPoint ignorePositionMask;
39     const SkIPoint ignorePositionFieldMask;
40 
41 private:
42     static SkVector HalfAxisSampleFreq(bool isSubpixel, SkAxisAlignment axisAlignment);
43     static SkIPoint IgnorePositionMask(bool isSubpixel, SkAxisAlignment axisAlignment);
44     static SkIPoint IgnorePositionFieldMask(bool isSubpixel, SkAxisAlignment axisAlignment);
45 };
46 
47 class SkStrikeCommon {
48 public:
49     // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256.
50     // This means that the maximum size a glyph can be is 256x256.
51     inline static constexpr uint16_t kSkSideTooBigForAtlas = 256;
52 };
53 
54 class SkGlyphRunListPainter {
55 public:
56     // Constructor for SkBitmpapDevice.
57     SkGlyphRunListPainter(const SkSurfaceProps& props,
58                           SkColorType colorType,
59                           SkColorSpace* cs,
60                           SkStrikeForGPUCacheInterface* strikeCache);
61 
62 #if SK_SUPPORT_GPU
63     // The following two ctors are used exclusively by the GPU, and will always use the global
64     // strike cache.
65     SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorInfo&);
66     explicit SkGlyphRunListPainter(const skgpu::v1::SurfaceDrawContext&);
67 #endif  // SK_SUPPORT_GPU
68 
69     class BitmapDevicePainter {
70     public:
71         BitmapDevicePainter() = default;
72         BitmapDevicePainter(const BitmapDevicePainter&) = default;
73         virtual ~BitmapDevicePainter() = default;
74 
75         virtual void paintMasks(SkDrawableGlyphBuffer* accepted, const SkPaint& paint) const = 0;
76         virtual void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
77                                 const SkSamplingOptions&, const SkPaint&) const = 0;
78     };
79 
80     void drawForBitmapDevice(
81             SkCanvas* canvas, const BitmapDevicePainter* bitmapDevice,
82             const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix);
83 
84 #if SK_SUPPORT_GPU
85     // A nullptr for process means that the calls to the cache will be performed, but none of the
86     // callbacks will be called.
87     void processGlyphRun(SkGlyphRunPainterInterface* process,
88                          const SkGlyphRun& glyphRun,
89                          const SkMatrix& drawMatrix,
90                          const SkPaint& drawPaint,
91                          const GrSDFTControl& control,
92                          const char* tag = nullptr,
93                          uint64_t blobID = SK_InvalidUniqueID);
94 #endif  // SK_SUPPORT_GPU
95 
96 private:
97     SkGlyphRunListPainter(const SkSurfaceProps& props, SkColorType colorType,
98                           SkScalerContextFlags flags, SkStrikeForGPUCacheInterface* strikeCache);
99 
100     struct ScopedBuffers {
101         ScopedBuffers(SkGlyphRunListPainter* painter, size_t size);
102         ~ScopedBuffers();
103         SkGlyphRunListPainter* fPainter;
104     };
105 
106     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList);
107     ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun);
108 
109     // The props as on the actual device.
110     const SkSurfaceProps fDeviceProps;
111     // The props for when the bitmap device can't draw LCD text.
112     const SkSurfaceProps fBitmapFallbackProps;
113     const SkColorType fColorType;
114     const SkScalerContextFlags fScalerContextFlags;
115 
116     SkStrikeForGPUCacheInterface* const fStrikeCache;
117 
118     SkDrawableGlyphBuffer fAccepted;
119     SkSourceGlyphBuffer fRejected;
120 };
121 
122 // SkGlyphRunPainterInterface are all the ways that Ganesh generates glyphs. The first
123 // distinction is between Device and Source.
124 // * Device - the data in the cache is scaled to the device. There is no transformation from the
125 //   cache to the screen.
126 // * Source - the data in the cache needs to be scaled from the cache to source space using the
127 //   factor cacheToSourceScale. When drawn the system must combine cacheToSourceScale and the
128 //   deviceView matrix to transform the cache data onto the screen. This allows zooming and
129 //   simple animation to reuse the same glyph data by just changing the transform.
130 //
131 // In addition to transformation type above, Masks, Paths, SDFT, and Fallback (or really the
132 // rendering method of last resort) are the different
133 // formats of data used from the cache.
134 class SkGlyphRunPainterInterface {
135 public:
136     virtual ~SkGlyphRunPainterInterface() = default;
137 
138     virtual void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted,
139                                     sk_sp<SkStrike>&& strike) = 0;
140 
141     virtual void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted,
142                                     sk_sp<SkStrike>&& strike,
143                                     SkScalar strikeToSourceScale) = 0;
144 
145     virtual void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& accepted,
146                                     const SkFont& runFont,
147                                     SkScalar strikeToSourceScale) = 0;
148 
149     virtual void processSourceDrawables(const SkZip<SkGlyphVariant, SkPoint>& accepted,
150                                         const SkFont& runFont,
151                                         SkScalar strikeToSourceScale) = 0;
152 
153     virtual void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& accepted,
154                                    sk_sp<SkStrike>&& strike,
155                                    SkScalar strikeToSourceScale,
156                                    const SkFont& runFont,
157                                    const GrSDFTMatrixRange& matrixRange) = 0;
158 };
159 
160 #endif  // SkGlyphRunPainter_DEFINED
161