xref: /third_party/skia/src/core/SkStrikeSpec.h (revision cb93a386)
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"
20class GrStrikeCache;
21class GrTextStrike;
22#endif
23
24class SkFont;
25class SkPaint;
26class SkStrikeCache;
27class SkSurfaceProps;
28
29class SkStrikeSpec {
30public:
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
90    std::unique_ptr<SkScalerContext> createScalerContext() const {
91        SkScalerContextEffects effects{fPathEffect.get(), fMaskFilter.get()};
92        return fTypeface->createScalerContext(effects, fAutoDescriptor.getDesc());
93    }
94
95    const SkDescriptor& descriptor() const { return *fAutoDescriptor.getDesc(); }
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
100private:
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
114class SkBulkGlyphMetrics {
115public:
116    explicit SkBulkGlyphMetrics(const SkStrikeSpec& spec);
117    SkSpan<const SkGlyph*> glyphs(SkSpan<const SkGlyphID> glyphIDs);
118    const SkGlyph* glyph(SkGlyphID glyphID);
119
120private:
121    inline static constexpr int kTypicalGlyphCount = 20;
122    SkAutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs;
123    sk_sp<SkStrike> fStrike;
124};
125
126class SkBulkGlyphMetricsAndPaths {
127public:
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
136private:
137    inline static constexpr int kTypicalGlyphCount = 20;
138    SkAutoSTArray<kTypicalGlyphCount, const SkGlyph*> fGlyphs;
139    sk_sp<SkStrike> fStrike;
140};
141
142class SkBulkGlyphMetricsAndImages {
143public:
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
151private:
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