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