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