1 /* 2 * Copyright 2019 Google Inc. 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 SkStrikeSpec_DEFINED 9 #define SkStrikeSpec_DEFINED 10 11 #include "include/core/SkMaskFilter.h" 12 #include "include/core/SkPathEffect.h" 13 #include "include/core/SkSpan.h" 14 #include "src/core/SkDescriptor.h" 15 #include "src/text/StrikeForGPU.h" 16 17 #include <tuple> 18 19 #if defined(SK_GANESH) || defined(SK_GRAPHITE) 20 #include "src/text/gpu/SDFTControl.h" 21 22 namespace sktext::gpu { 23 class StrikeCache; 24 class TextStrike; 25 } 26 #endif 27 28 class SkFont; 29 class SkPaint; 30 class SkStrike; 31 class SkStrikeCache; 32 class SkSurfaceProps; 33 34 class SkStrikeSpec { 35 public: 36 SkStrikeSpec(const SkDescriptor& descriptor, sk_sp<SkTypeface> typeface); 37 SkStrikeSpec(const SkStrikeSpec&); 38 SkStrikeSpec& operator=(const SkStrikeSpec&) = delete; 39 40 SkStrikeSpec(SkStrikeSpec&&); 41 SkStrikeSpec& operator=(SkStrikeSpec&&) = delete; 42 43 ~SkStrikeSpec(); 44 45 // Create a strike spec for mask style cache entries. 46 static SkStrikeSpec MakeMask( 47 const SkFont& font, 48 const SkPaint& paint, 49 const SkSurfaceProps& surfaceProps, 50 SkScalerContextFlags scalerContextFlags, 51 const SkMatrix& deviceMatrix); 52 53 // A strike for finding the max size for transforming masks. This is used to calculate the 54 // maximum dimension of a SubRun of text. 55 static SkStrikeSpec MakeTransformMask( 56 const SkFont& font, 57 const SkPaint& paint, 58 const SkSurfaceProps& surfaceProps, 59 SkScalerContextFlags scalerContextFlags, 60 const SkMatrix& deviceMatrix); 61 62 // Create a strike spec for path style cache entries. 63 static std::tuple<SkStrikeSpec, SkScalar> MakePath( 64 const SkFont& font, 65 const SkPaint& paint, 66 const SkSurfaceProps& surfaceProps, 67 SkScalerContextFlags scalerContextFlags); 68 69 // Create a canonical strike spec for device-less measurements. 70 static std::tuple<SkStrikeSpec, SkScalar> MakeCanonicalized( 71 const SkFont& font, const SkPaint* paint = nullptr); 72 73 // Create a strike spec without a device, and does not switch over to path for large sizes. 74 static SkStrikeSpec MakeWithNoDevice(const SkFont& font, const SkPaint* paint = nullptr); 75 76 // Make a strike spec for PDF Vector strikes 77 static SkStrikeSpec MakePDFVector(const SkTypeface& typeface, int* size); 78 79 #if (defined(SK_GANESH) || defined(SK_GRAPHITE)) && !defined(SK_DISABLE_SDF_TEXT) 80 // Create a strike spec for scaled distance field text. 81 static std::tuple<SkStrikeSpec, SkScalar, sktext::gpu::SDFTMatrixRange> MakeSDFT( 82 const SkFont& font, 83 const SkPaint& paint, 84 const SkSurfaceProps& surfaceProps, 85 const SkMatrix& deviceMatrix, 86 const SkPoint& textLocation, 87 const sktext::gpu::SDFTControl& control); 88 #endif 89 90 sk_sp<sktext::StrikeForGPU> findOrCreateScopedStrike( 91 sktext::StrikeForGPUCacheInterface* cache) const; 92 93 sk_sp<SkStrike> findOrCreateStrike() const; 94 95 sk_sp<SkStrike> findOrCreateStrike(SkStrikeCache* cache) const; 96 createScalerContext()97 std::unique_ptr<SkScalerContext> createScalerContext() const { 98 SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()}; 99 return fTypeface->createScalerContext(effects, fAutoDescriptor.getDesc()); 100 } 101 descriptor()102 const SkDescriptor& descriptor() const { return *fAutoDescriptor.getDesc(); } typeface()103 const SkTypeface& typeface() const { return *fTypeface; } 104 static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix); 105 SkString dump() const; 106 107 private: 108 SkStrikeSpec( 109 const SkFont& font, 110 const SkPaint& paint, 111 const SkSurfaceProps& surfaceProps, 112 SkScalerContextFlags scalerContextFlags, 113 const SkMatrix& deviceMatrix); 114 115 SkAutoDescriptor fAutoDescriptor; 116 sk_sp<SkMaskFilter> fMaskFilter{nullptr}; 117 sk_sp<SkPathEffect> fPathEffect{nullptr}; 118 sk_sp<SkTypeface> fTypeface; 119 }; 120 121 class SkBulkGlyphMetrics { 122 public: 123 explicit SkBulkGlyphMetrics(const SkStrikeSpec& spec); 124 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 125 const SkGlyph* glyph(SkGlyphID glyphID); 126 127 private: 128 inline static constexpr int kTypicalGlyphCount = 20; 129 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 130 sk_sp<SkStrike> fStrike; 131 }; 132 133 class SkBulkGlyphMetricsAndPaths { 134 public: 135 explicit SkBulkGlyphMetricsAndPaths(const SkStrikeSpec& spec); 136 explicit SkBulkGlyphMetricsAndPaths(sk_sp<SkStrike>&& strike); 137 ~SkBulkGlyphMetricsAndPaths(); 138 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 139 const SkGlyph* glyph(SkGlyphID glyphID); 140 void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos, 141 const SkGlyph* glyph, SkScalar* array, int* count); 142 143 private: 144 inline static constexpr int kTypicalGlyphCount = 20; 145 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 146 sk_sp<SkStrike> fStrike; 147 }; 148 149 class SkBulkGlyphMetricsAndDrawables { 150 public: 151 explicit SkBulkGlyphMetricsAndDrawables(const SkStrikeSpec& spec); 152 explicit SkBulkGlyphMetricsAndDrawables(sk_sp<SkStrike>&& strike); 153 ~SkBulkGlyphMetricsAndDrawables(); 154 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 155 const SkGlyph* glyph(SkGlyphID glyphID); 156 157 private: 158 inline static constexpr int kTypicalGlyphCount = 20; 159 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 160 sk_sp<SkStrike> fStrike; 161 }; 162 163 class SkBulkGlyphMetricsAndImages { 164 public: 165 explicit SkBulkGlyphMetricsAndImages(const SkStrikeSpec& spec); 166 explicit SkBulkGlyphMetricsAndImages(sk_sp<SkStrike>&& strike); 167 ~SkBulkGlyphMetricsAndImages(); 168 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkPackedGlyphID> packedIDs); 169 const SkGlyph* glyph(SkPackedGlyphID packedID); 170 const SkDescriptor& descriptor() const; 171 172 private: 173 inline static constexpr int kTypicalGlyphCount = 64; 174 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 175 sk_sp<SkStrike> fStrike; 176 }; 177 178 #endif // SkStrikeSpec_DEFINED 179