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