• 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/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