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 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 GrRenderTargetContext& renderTargetContext); 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, const SkPaint& paint) const = 0; 74 75 virtual void paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint) const = 0; 76 }; 77 78 void drawForBitmapDevice( 79 const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix, 80 const BitmapDevicePainter* bitmapDevice); 81 82 #if SK_SUPPORT_GPU 83 // A nullptr for process means that the calls to the cache will be performed, but none of the 84 // callbacks will be called. 85 void processGlyphRunList(const SkGlyphRunList& glyphRunList, 86 const SkMatrix& drawMatrix, 87 const SkSurfaceProps& props, 88 bool contextSupportsDistanceFieldText, 89 const GrTextContext::Options& options, 90 SkGlyphRunPainterInterface* process); 91 #endif // SK_SUPPORT_GPU 92 93 private: 94 SkGlyphRunListPainter(const SkSurfaceProps& props, SkColorType colorType, 95 SkScalerContextFlags flags, SkStrikeForGPUCacheInterface* strikeCache); 96 97 struct ScopedBuffers { 98 ScopedBuffers(SkGlyphRunListPainter* painter, size_t size); 99 ~ScopedBuffers(); 100 SkGlyphRunListPainter* fPainter; 101 }; 102 103 ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList); 104 105 // The props as on the actual device. 106 const SkSurfaceProps fDeviceProps; 107 // The props for when the bitmap device can't draw LCD text. 108 const SkSurfaceProps fBitmapFallbackProps; 109 const SkColorType fColorType; 110 const SkScalerContextFlags fScalerContextFlags; 111 112 SkStrikeForGPUCacheInterface* const fStrikeCache; 113 114 SkDrawableGlyphBuffer fDrawable; 115 SkSourceGlyphBuffer fRejects; 116 }; 117 118 // SkGlyphRunPainterInterface are all the ways that Ganesh generates glyphs. The first 119 // distinction is between Device and Source. 120 // * Device - the data in the cache is scaled to the device. There is no transformation from the 121 // cache to the screen. 122 // * Source - the data in the cache needs to be scaled from the cache to source space using the 123 // factor cacheToSourceScale. When drawn the system must combine cacheToSourceScale and the 124 // deviceView matrix to transform the cache data onto the screen. This allows zooming and 125 // simple animation to reuse the same glyph data by just changing the transform. 126 // 127 // In addition to transformation type above, Masks, Paths, SDFT, and Fallback (or really the 128 // rendering method of last resort) are the different 129 // formats of data used from the cache. 130 class SkGlyphRunPainterInterface { 131 public: 132 virtual ~SkGlyphRunPainterInterface() = default; 133 134 virtual void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 135 const SkStrikeSpec& strikeSpec) = 0; 136 137 virtual void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 138 const SkStrikeSpec& strikeSpec) = 0; 139 140 virtual void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables, 141 const SkFont& runFont, 142 const SkStrikeSpec& strikeSpec) = 0; 143 144 virtual void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables, 145 const SkStrikeSpec& strikeSpec, 146 const SkFont& runFont, 147 SkScalar minScale, 148 SkScalar maxScale) = 0; 149 }; 150 151 #endif // SkGlyphRunPainter_DEFINED 152