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 "SkDistanceFieldGen.h" 12 #include "SkGlyphRun.h" 13 #include "SkScalerContext.h" 14 #include "SkSurfaceProps.h" 15 #include "SkTextBlobPriv.h" 16 17 #if SK_SUPPORT_GPU 18 class GrColorSpaceInfo; 19 class GrRenderTargetContext; 20 #endif 21 22 class SkStrikeInterface { 23 public: 24 virtual ~SkStrikeInterface() = default; 25 virtual SkVector rounding() const = 0; 26 virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0; 27 virtual bool hasImage(const SkGlyph& glyph) = 0; 28 virtual bool hasPath(const SkGlyph& glyph) = 0; 29 }; 30 31 class SkStrikeCommon { 32 public: 33 static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment); 34 35 // This assumes that position has the appropriate rounding term applied. 36 static SkIPoint SubpixelLookup(SkAxisAlignment axisAlignment, SkPoint position); 37 38 // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256. 39 // This means that the maximum size a glyph can be is 256x256. 40 static constexpr uint16_t kSkSideTooBigForAtlas = 256; 41 42 static bool GlyphTooBigForAtlas(const SkGlyph& glyph); 43 }; 44 45 class SkGlyphRunListPainter { 46 public: 47 // Constructor for SkBitmpapDevice. 48 SkGlyphRunListPainter( 49 const SkSurfaceProps& props, SkColorType colorType, SkScalerContextFlags flags); 50 51 #if SK_SUPPORT_GPU 52 SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorSpaceInfo&); 53 explicit SkGlyphRunListPainter(const GrRenderTargetContext& renderTargetContext); 54 #endif 55 56 struct PathAndPos { 57 const SkPath* path; 58 SkPoint position; 59 }; 60 61 struct GlyphAndPos { 62 const SkGlyph* glyph; 63 SkPoint position; 64 }; 65 66 class BitmapDevicePainter { 67 public: 68 virtual ~BitmapDevicePainter() = default; 69 70 virtual void paintPaths(SkSpan<const PathAndPos> pathsAndPositions, 71 SkScalar scale, 72 const SkPaint& paint) const = 0; 73 74 virtual void paintMasks(SkSpan<const SkMask> masks, const SkPaint& paint) const = 0; 75 }; 76 77 void drawForBitmapDevice( 78 const SkGlyphRunList& glyphRunList, const SkMatrix& deviceMatrix, 79 const BitmapDevicePainter* bitmapDevice); 80 81 template <typename EmptiesT, typename MasksT, typename PathsT> 82 void drawGlyphRunAsBMPWithPathFallback( 83 SkStrikeInterface* cache, const SkGlyphRun& glyphRun, 84 SkPoint origin, const SkMatrix& deviceMatrix, 85 EmptiesT&& processEmpties, MasksT&& processMasks, PathsT&& processPaths); 86 87 enum NeedsTransform : bool { kTransformDone = false, kDoTransform = true }; 88 89 using ARGBFallback = 90 std::function<void(const SkPaint& fallbackPaint, // The run paint maybe with a new text size 91 const SkFont& fallbackFont, 92 SkSpan<const SkGlyphID> fallbackGlyphIDs, // Colored glyphs 93 SkSpan<const SkPoint> fallbackPositions, // Positions of above glyphs 94 SkScalar fallbackTextScale, // Scale factor for glyph 95 const SkMatrix& glyphCacheMatrix, // Matrix of glyph cache 96 NeedsTransform handleTransformLater)>; // Positions / glyph transformed 97 98 // Draw glyphs as paths with fallback to scaled ARGB glyphs if color is needed. 99 // PerPath - perPath(const SkGlyph&, SkPoint position) 100 // FallbackARGB - fallbackARGB(SkSpan<const SkGlyphID>, SkSpan<const SkPoint>) 101 // For each glyph that is not ARGB call perPath. If the glyph is ARGB then store the glyphID 102 // and the position in fallback vectors. After all the glyphs are processed, pass the 103 // fallback glyphIDs and positions to fallbackARGB. 104 template <typename PerEmptyT, typename PerPath> 105 void drawGlyphRunAsPathWithARGBFallback( 106 SkStrikeInterface* cache, const SkGlyphRun& glyphRun, 107 SkPoint origin, const SkPaint& paint, const SkMatrix& viewMatrix, SkScalar textScale, 108 PerEmptyT&& perEmpty, PerPath&& perPath, ARGBFallback&& fallbackARGB); 109 110 template <typename PerEmptyT, typename PerSDFT, typename PerPathT> 111 void drawGlyphRunAsSDFWithARGBFallback( 112 SkStrikeInterface* cache, const SkGlyphRun& glyphRun, 113 SkPoint origin, const SkPaint& runPaint, const SkMatrix& viewMatrix, SkScalar textRatio, 114 PerEmptyT&& perEmpty, PerSDFT&& perSDF, PerPathT&& perPath, ARGBFallback&& perFallback); 115 116 // TODO: Make this the canonical check for Skia. 117 static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix); 118 119 private: 120 struct ScopedBuffers { 121 ScopedBuffers(SkGlyphRunListPainter* painter, int size); 122 ~ScopedBuffers(); 123 SkGlyphRunListPainter* fPainter; 124 }; 125 126 ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList); 127 128 // TODO: Remove once I can hoist ensureBuffers above the list for loop in all cases. 129 ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun); 130 131 void processARGBFallback( 132 SkScalar maxGlyphDimension, const SkPaint& fallbackPaint, const SkFont& fallbackFont, 133 const SkMatrix& viewMatrix, SkScalar textScale, ARGBFallback argbFallback); 134 135 // The props as on the actual device. 136 const SkSurfaceProps fDeviceProps; 137 // The props for when the bitmap device can't draw LCD text. 138 const SkSurfaceProps fBitmapFallbackProps; 139 const SkColorType fColorType; 140 const SkScalerContextFlags fScalerContextFlags; 141 142 int fMaxRunSize{0}; 143 SkAutoTMalloc<SkPoint> fPositions; 144 SkAutoTMalloc<GlyphAndPos> fMasks; 145 146 std::vector<GlyphAndPos> fPaths; 147 148 // Vectors for tracking ARGB fallback information. 149 std::vector<SkGlyphID> fARGBGlyphsIDs; 150 std::vector<SkPoint> fARGBPositions; 151 }; 152 153 #endif // SkGlyphRunPainter_DEFINED 154