• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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