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