1 /*
2  * Copyright 2014 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 TestSVGTypeface_DEFINED
9 #define TestSVGTypeface_DEFINED
10 
11 #include "include/core/SkFontArguments.h"
12 #include "include/core/SkFontMetrics.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkRefCnt.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkSpan.h"
19 #include "include/core/SkStream.h"
20 #include "include/core/SkString.h"
21 #include "include/core/SkTypeface.h"
22 #include "include/core/SkTypes.h"
23 #include "include/pathops/SkPathOps.h"
24 #include "include/private/SkMutex.h"
25 #include "include/private/SkTArray.h"
26 #include "include/private/SkTHash.h"
27 
28 #include <memory>
29 
30 class SkCanvas;
31 class SkDescriptor;
32 class SkFontDescriptor;
33 class SkFontStyle;
34 class SkGlyph;
35 class SkPath;
36 class SkScalerContext;
37 class SkSVGDOM;
38 class SkWStream;
39 struct SkAdvancedTypefaceMetrics;
40 struct SkScalerContextEffects;
41 struct SkScalerContextRec;
42 
43 struct SkSVGTestTypefaceGlyphData {
44     const char* fSvgResourcePath;
45     SkPoint     fOrigin;  // y-down
46     SkScalar    fAdvance;
47     SkUnichar   fUnicode;  // TODO: this limits to 1:1
48 };
49 
50 class TestSVGTypeface : public SkTypeface {
51 public:
52     TestSVGTypeface(const char*                              name,
53                     int                                      upem,
54                     const SkFontMetrics&                     metrics,
55                     SkSpan<const SkSVGTestTypefaceGlyphData> data,
56                     const SkFontStyle&                       style);
57     ~TestSVGTypeface() override;
58     void getAdvance(SkGlyph* glyph) const;
59     void getFontMetrics(SkFontMetrics* metrics) const;
60 
61     static sk_sp<TestSVGTypeface> Default();
62     static sk_sp<TestSVGTypeface> Planets();
63     void                          exportTtxCbdt(SkWStream*, SkSpan<unsigned> strikeSizes) const;
64     void                          exportTtxSbix(SkWStream*, SkSpan<unsigned> strikeSizes) const;
65     void                          exportTtxColr(SkWStream*) const;
66     virtual bool                  getPathOp(SkColor, SkPathOp*) const = 0;
67 
68     struct GlyfLayerInfo {
GlyfLayerInfoGlyfLayerInfo69         GlyfLayerInfo(int layerColorIndex, SkIRect bounds)
70                 : fLayerColorIndex(layerColorIndex), fBounds(bounds) {}
71         int     fLayerColorIndex;
72         SkIRect fBounds;
73     };
74     struct GlyfInfo {
GlyfInfoGlyfInfo75         GlyfInfo() : fBounds(SkIRect::MakeEmpty()) {}
76         SkIRect                 fBounds;
77         SkTArray<GlyfLayerInfo> fLayers;
78     };
79 
80 protected:
81     void exportTtxCommon(SkWStream*, const char* type, const SkTArray<GlyfInfo>* = nullptr) const;
82 
83     std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&,
84                                                            const SkDescriptor* desc) const override;
85     void onFilterRec(SkScalerContextRec* rec) const override;
86     void getGlyphToUnicodeMap(SkUnichar*) const override;
87     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
88 
onOpenStream(int * ttcIndex)89     std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override { return nullptr; }
90 
onMakeClone(const SkFontArguments & args)91     sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
92         return sk_ref_sp(this);
93     }
94 
95     void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
96 
97     void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
98 
getPostScriptGlyphNames(SkString *)99     void getPostScriptGlyphNames(SkString*) const override {}
100 
onCountGlyphs()101     int onCountGlyphs() const override { return fGlyphCount; }
102 
onGetUPEM()103     int onGetUPEM() const override { return fUpem; }
104 
105     void onGetFamilyName(SkString* familyName) const override;
106     bool onGetPostScriptName(SkString*) const override;
107     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
108 
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount)109     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
110                                      int coordinateCount) const override {
111         return 0;
112     }
113 
onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount)114     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
115                                        int parameterCount) const override {
116         return 0;
117     }
118 
onGetTableTags(SkFontTableTag tags[])119     int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
120 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data)121     size_t onGetTableData(SkFontTableTag tag,
122                           size_t         offset,
123                           size_t         length,
124                           void*          data) const override {
125         return 0;
126     }
127 
128 private:
129     struct Glyph {
130         Glyph();
131         ~Glyph();
132         SkPoint     fOrigin;
133         SkScalar    fAdvance;
134         const char* fResourcePath;
135 
136         SkSize size() const;
137         void render(SkCanvas*) const;
138 
139     private:
140         // Lazily parses the SVG from fResourcePath, and manages mutex locking.
141         template <typename Fn> void withSVG(Fn&&) const;
142 
143         // The mutex guards lazy parsing of the SVG, but also predates that.
144         // Must be SkSVGDOM::render() is not thread safe?
145         // If not, an SkOnce is enough here.
146         mutable SkMutex         fSvgMutex;
147         mutable bool            fParsedSvg = false;
148         mutable sk_sp<SkSVGDOM> fSvg;
149     };
150 
151     SkString                         fName;
152     int                              fUpem;
153     const SkFontMetrics              fFontMetrics;
154     std::unique_ptr<Glyph[]>         fGlyphs;
155     int                              fGlyphCount;
156     SkTHashMap<SkUnichar, SkGlyphID> fCMap;
157     friend class SkTestSVGScalerContext;
158 };
159 
160 #endif
161