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