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