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