xref: /aosp_15_r20/external/skia/src/pdf/SkPDFFont.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2011 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 #ifndef SkPDFFont_DEFINED
8 #define SkPDFFont_DEFINED
9 
10 #include "include/core/SkRefCnt.h"
11 #include "include/core/SkScalar.h"
12 #include "include/core/SkTypes.h"
13 #include "src/base/SkUTF.h"
14 #include "src/core/SkAdvancedTypefaceMetrics.h"
15 #include "src/core/SkStrikeSpec.h"
16 #include "src/core/SkTHash.h"
17 #include "src/pdf/SkPDFGlyphUse.h"
18 #include "src/pdf/SkPDFTypes.h"
19 
20 #include <cstdint>
21 #include <vector>
22 
23 class SkDescriptor;
24 class SkFont;
25 class SkGlyph;
26 class SkPaint;
27 class SkPDFDocument;
28 class SkPDFFont;
29 class SkString;
30 class SkTypeface;
31 
32 class SkPDFStrikeSpec {
33 public:
34     SkPDFStrikeSpec(SkStrikeSpec, SkScalar em);
35 
36     const SkStrikeSpec fStrikeSpec;
37     const SkScalar fUnitsPerEM;
38 };
39 
40 class SkPDFStrike : public SkRefCnt {
41 public:
42     /** Make or return an existing SkPDFStrike, canonicalizing for resource de-duplication.
43      *  The SkPDFStrike is owned by the SkPDFDocument.
44      */
45     static sk_sp<SkPDFStrike> Make(SkPDFDocument* doc, const SkFont&, const SkPaint&);
46 
47     const SkPDFStrikeSpec fPath;
48     const SkPDFStrikeSpec fImage;
49     const bool fHasMaskFilter;
50     SkPDFDocument* fDoc;
51     skia_private::THashMap<SkGlyphID, SkPDFFont> fFontMap;
52 
53     /** Get the font resource for the glyph.
54      *  The returned SkPDFFont is owned by the SkPDFStrike.
55      *  @param glyph  The glyph of interest
56      */
57     SkPDFFont* getFontResource(const SkGlyph* glyph);
58 
59     struct Traits {
60         static const SkDescriptor& GetKey(const sk_sp<SkPDFStrike>& strike);
61         static uint32_t Hash(const SkDescriptor& descriptor);
62     };
63 private:
64     SkPDFStrike(SkPDFStrikeSpec path, SkPDFStrikeSpec image, bool hasMaskFilter, SkPDFDocument*);
65 };
66 
67 /** \class SkPDFFont
68     A PDF Object class representing a PDF Font. SkPDFFont are owned by an SkPDFStrike.
69 */
70 class SkPDFFont {
71 public:
72     ~SkPDFFont();
73     SkPDFFont(SkPDFFont&&);
74     SkPDFFont& operator=(SkPDFFont&&) = delete;
75 
76     /** Returns the font type represented in this font.  For Type0 fonts,
77      *  returns the type of the descendant font.
78      */
getType()79     SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
80 
81     static SkAdvancedTypefaceMetrics::FontType FontType(const SkPDFStrike&,
82                                                         const SkAdvancedTypefaceMetrics&);
83     static void GetType1GlyphNames(const SkTypeface&, SkString*);
84 
IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)85     static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
86         return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
87                type == SkAdvancedTypefaceMetrics::kTrueType_Font ||
88                type == SkAdvancedTypefaceMetrics::kCFF_Font;
89     }
90 
91     /** Returns true if this font encoding supports glyph IDs above 255.
92      */
multiByteGlyphs()93     bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }
94 
95     /** Return true if this font has an encoding for the passed glyph id.
96      */
hasGlyph(SkGlyphID gid)97     bool hasGlyph(SkGlyphID gid) {
98         return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0;
99     }
100 
101     /** Convert the input glyph ID into the font encoding.  */
glyphToPDFFontEncoding(SkGlyphID gid)102     SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
103         if (this->multiByteGlyphs() || gid == 0) {
104             return gid;
105         }
106         SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID());
107         SkASSERT(this->firstGlyphID() > 0);
108         return gid - this->firstGlyphID() + 1;
109     }
110 
noteGlyphUsage(SkGlyphID glyph)111     void noteGlyphUsage(SkGlyphID glyph) {
112         SkASSERT(this->hasGlyph(glyph));
113         fGlyphUsage.set(glyph);
114     }
115 
indirectReference()116     SkPDFIndirectReference indirectReference() const { return fIndirectReference; }
117 
118     /** Gets SkAdvancedTypefaceMetrics, and caches the result.
119      *  @param typeface can not be nullptr.
120      *  @return nullptr only when typeface is bad.
121      */
122     static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface& typeface,
123                                                        SkPDFDocument* canon);
124 
125     static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface& typeface,
126                                                        SkPDFDocument* canon);
127     static skia_private::THashMap<SkGlyphID, SkString>& GetUnicodeMapEx(
128             const SkTypeface& typeface, SkPDFDocument* canon);
129 
130     static void PopulateCommonFontDescriptor(SkPDFDict* descriptor,
131                                              const SkAdvancedTypefaceMetrics&,
132                                              uint16_t emSize,
133                                              int16_t defaultWidth);
134 
135     void emitSubset(SkPDFDocument*) const;
136 
137     /** Return false iff the typeface has its NotEmbeddable flag set. */
138     static bool CanEmbedTypeface(const SkTypeface&, SkPDFDocument*);
139 
firstGlyphID()140     SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); }
lastGlyphID()141     SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); }
glyphUsage()142     const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; }
143 
strike()144     const SkPDFStrike& strike() const { return *fStrike; }
145 
146 private:
147     const SkPDFStrike* fStrike;
148     SkPDFGlyphUse fGlyphUsage;
149     SkPDFIndirectReference fIndirectReference;
150     SkAdvancedTypefaceMetrics::FontType fFontType;
151 
152     SkPDFFont(const SkPDFStrike*,
153               SkGlyphID firstGlyphID,
154               SkGlyphID lastGlyphID,
155               SkAdvancedTypefaceMetrics::FontType fontType,
156               SkPDFIndirectReference indirectReference);
157     // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
158     // this will be a subset if the font has more than 255 glyphs.
159 
160     SkPDFFont() = delete;
161     SkPDFFont(const SkPDFFont&) = delete;
162     SkPDFFont& operator=(const SkPDFFont&) = delete;
163     friend class SkPDFStrike;
164 };
165 
166 #endif
167