• 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 class GrSurfaceDrawContext;
22 #endif
23 
24 class SkGlyphRunPainterInterface;
25 class SkStrikeSpec;
26 
27 // round and ignorePositionMask are used to calculate the subpixel position of a glyph.
28 // The per component (x or y) calculation is:
29 //
30 //   subpixelOffset = (floor((viewportPosition + rounding) & mask) >> 14) & 3
31 //
32 // where mask is either 0 or ~0, and rounding is either
33 // 1/2 for non-subpixel or 1/8 for subpixel.
34 struct SkGlyphPositionRoundingSpec {
35     SkGlyphPositionRoundingSpec(bool isSubpixel, SkAxisAlignment axisAlignment);
36     const SkVector halfAxisSampleFreq;
37     const SkIPoint ignorePositionMask;
38     const SkIPoint ignorePositionFieldMask;
39 
40 private:
41     static SkVector HalfAxisSampleFreq(bool isSubpixel, SkAxisAlignment axisAlignment);
42     static SkIPoint IgnorePositionMask(bool isSubpixel, SkAxisAlignment axisAlignment);
43     static SkIPoint IgnorePositionFieldMask(bool isSubpixel, SkAxisAlignment axisAlignment);
44 };
45 
46 class SkStrikeCommon {
47 public:
48     // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256.
49     // This means that the maximum size a glyph can be is 256x256.
50     static constexpr uint16_t kSkSideTooBigForAtlas = 256;
51 };
52 
53 class SkGlyphRunListPainter {
54 public:
55     // Constructor for SkBitmpapDevice.
56     SkGlyphRunListPainter(const SkSurfaceProps& props,
57                           SkColorType colorType,
58                           SkColorSpace* cs,
59                           SkStrikeForGPUCacheInterface* strikeCache);
60 
61 #if SK_SUPPORT_GPU
62     // The following two ctors are used exclusively by the GPU, and will always use the global
63     // strike cache.
64     SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorInfo&);
65     explicit SkGlyphRunListPainter(const GrSurfaceDrawContext& surfaceDrawContext);
66 #endif  // SK_SUPPORT_GPU
67 
68     class BitmapDevicePainter {
69     public:
70         virtual ~BitmapDevicePainter() = default;
71 
72         virtual void paintPaths(
73                 SkDrawableGlyphBuffer* drawables, SkScalar scale, SkPoint origin,
74                 const SkPaint& paint) const = 0;
75 
76         virtual void paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint) const = 0;
77         virtual void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
78                                 const SkSamplingOptions&, const SkPaint&) const = 0;
79     };
80 
81     void drawForBitmapDevice(
82             const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix,
83             const BitmapDevicePainter* bitmapDevice);
84 
85 #if SK_SUPPORT_GPU
86     // A nullptr for process means that the calls to the cache will be performed, but none of the
87     // callbacks will be called.
88     void processGlyphRun(const SkGlyphRun& glyphRun,
89                          const SkMatrix& drawMatrix,
90                          const SkPaint& drawPaint,
91                          const GrSDFTControl& control,
92                          SkGlyphRunPainterInterface* process,
93                          const char* tag = nullptr);
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 fDrawable;
119     SkSourceGlyphBuffer fRejects;
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>& drawables,
139                                     const SkStrikeSpec& strikeSpec) = 0;
140 
141     virtual void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables,
142                                     const SkStrikeSpec& strikeSpec) = 0;
143 
144     virtual void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables,
145                                     const SkFont& runFont,
146                                     const SkStrikeSpec& strikeSpec) = 0;
147 
148     virtual void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
149                                    const SkStrikeSpec& strikeSpec,
150                                    const SkFont& runFont,
151                                    SkScalar minScale,
152                                    SkScalar maxScale) = 0;
153 };
154 
155 #endif  // SkGlyphRunPainter_DEFINED
156