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 // Make a strike spec for PDF Vector strikes 82 static SkStrikeSpec MakePDFVector(const SkTypeface& typeface, int* size); 83 84 sk_sp<sktext::StrikeForGPU> findOrCreateScopedStrike( 85 sktext::StrikeForGPUCacheInterface* cache) const; 86 87 sk_sp<SkStrike> findOrCreateStrike() const; 88 89 sk_sp<SkStrike> findOrCreateStrike(SkStrikeCache* cache) const; 90 createScalerContext()91 std::unique_ptr<SkScalerContext> createScalerContext() const { 92 SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()}; 93 return fTypeface->createScalerContext(effects, fAutoDescriptor.getDesc()); 94 } 95 descriptor()96 const SkDescriptor& descriptor() const { return *fAutoDescriptor.getDesc(); } typeface()97 const SkTypeface& typeface() const { return *fTypeface; } 98 static bool ShouldDrawAsPath(const SkPaint& paint, const SkFont& font, const SkMatrix& matrix); 99 SkString dump() const; 100 101 private: 102 SkStrikeSpec( 103 const SkFont& font, 104 const SkPaint& paint, 105 const SkSurfaceProps& surfaceProps, 106 SkScalerContextFlags scalerContextFlags, 107 const SkMatrix& deviceMatrix); 108 109 SkAutoDescriptor fAutoDescriptor; 110 sk_sp<SkMaskFilter> fMaskFilter{nullptr}; 111 sk_sp<SkPathEffect> fPathEffect{nullptr}; 112 sk_sp<SkTypeface> fTypeface; 113 }; 114 115 class SkBulkGlyphMetrics { 116 public: 117 explicit SkBulkGlyphMetrics(const SkStrikeSpec& spec); 118 ~SkBulkGlyphMetrics(); 119 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 120 const SkGlyph* glyph(SkGlyphID glyphID); 121 122 private: 123 inline static constexpr int kTypicalGlyphCount = 20; 124 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 125 sk_sp<SkStrike> fStrike; 126 }; 127 128 class SkBulkGlyphMetricsAndPaths { 129 public: 130 explicit SkBulkGlyphMetricsAndPaths(const SkStrikeSpec& spec); 131 explicit SkBulkGlyphMetricsAndPaths(sk_sp<SkStrike>&& strike); 132 ~SkBulkGlyphMetricsAndPaths(); 133 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 134 const SkGlyph* glyph(SkGlyphID glyphID); 135 void findIntercepts(const SkScalar bounds[2], SkScalar scale, SkScalar xPos, 136 const SkGlyph* glyph, SkScalar* array, int* count); 137 138 private: 139 inline static constexpr int kTypicalGlyphCount = 20; 140 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 141 sk_sp<SkStrike> fStrike; 142 }; 143 144 class SkBulkGlyphMetricsAndDrawables { 145 public: 146 explicit SkBulkGlyphMetricsAndDrawables(const SkStrikeSpec& spec); 147 explicit SkBulkGlyphMetricsAndDrawables(sk_sp<SkStrike>&& strike); 148 ~SkBulkGlyphMetricsAndDrawables(); 149 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs); 150 const SkGlyph* glyph(SkGlyphID glyphID); 151 152 private: 153 inline static constexpr int kTypicalGlyphCount = 20; 154 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 155 sk_sp<SkStrike> fStrike; 156 }; 157 158 class SkBulkGlyphMetricsAndImages { 159 public: 160 explicit SkBulkGlyphMetricsAndImages(const SkStrikeSpec& spec); 161 explicit SkBulkGlyphMetricsAndImages(sk_sp<SkStrike>&& strike); 162 ~SkBulkGlyphMetricsAndImages(); 163 SkSpan<const SkGlyph*> glyphs(SkSpan<const SkPackedGlyphID> packedIDs); 164 const SkGlyph* glyph(SkPackedGlyphID packedID); 165 const SkDescriptor& descriptor() const; 166 167 private: 168 inline static constexpr int kTypicalGlyphCount = 64; 169 skia_private::AutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs; 170 sk_sp<SkStrike> fStrike; 171 }; 172 173 #endif // SkStrikeSpec_DEFINED 174