• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/SkTypeface.h"
12 #include "include/core/SkTypes.h"
13 #include "src/base/SkUTF.h"
14 #include "src/core/SkAdvancedTypefaceMetrics.h"
15 #include "src/pdf/SkPDFGlyphUse.h"
16 #include "src/pdf/SkPDFTypes.h"
17 
18 #include <cstdint>
19 #include <vector>
20 
21 class SkGlyph;
22 class SkPDFDocument;
23 class SkString;
24 
25 /** \class SkPDFFont
26     A PDF Object class representing a font.  The font may have resources
27     attached to it in order to embed the font.  SkPDFFonts are canonicalized
28     so that resource deduplication will only include one copy of a font.
29     This class uses the same pattern as SkPDFGraphicState, a static weak
30     reference to each instantiated class.
31 */
32 class SkPDFFont {
33 public:
34     ~SkPDFFont();
35     SkPDFFont(SkPDFFont&&);
36     SkPDFFont& operator=(SkPDFFont&&);
37 
38     /** Returns the typeface represented by this class. Returns nullptr for the
39      *  default typeface.
40      */
typeface()41     SkTypeface* typeface() const { return fTypeface.get(); }
42 
43     /** Returns the font type represented in this font.  For Type0 fonts,
44      *  returns the type of the descendant font.
45      */
getType()46     SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
47 
48     static SkAdvancedTypefaceMetrics::FontType FontType(const SkTypeface&,
49                                                         const SkAdvancedTypefaceMetrics&);
50     static void GetType1GlyphNames(const SkTypeface&, SkString*);
51 
IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)52     static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
53         return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
54                type == SkAdvancedTypefaceMetrics::kTrueType_Font ||
55                type == SkAdvancedTypefaceMetrics::kCFF_Font;
56     }
57 
58     /** Returns true if this font encoding supports glyph IDs above 255.
59      */
multiByteGlyphs()60     bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }
61 
62     /** Return true if this font has an encoding for the passed glyph id.
63      */
hasGlyph(SkGlyphID gid)64     bool hasGlyph(SkGlyphID gid) {
65         return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0;
66     }
67 
68     /** Convert the input glyph ID into the font encoding.  */
glyphToPDFFontEncoding(SkGlyphID gid)69     SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
70         if (this->multiByteGlyphs() || gid == 0) {
71             return gid;
72         }
73         SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID());
74         SkASSERT(this->firstGlyphID() > 0);
75         return gid - this->firstGlyphID() + 1;
76     }
77 
noteGlyphUsage(SkGlyphID glyph)78     void noteGlyphUsage(SkGlyphID glyph) {
79         SkASSERT(this->hasGlyph(glyph));
80         fGlyphUsage.set(glyph);
81     }
82 
indirectReference()83     SkPDFIndirectReference indirectReference() const { return fIndirectReference; }
84 
85     /** Get the font resource for the passed typeface and glyphID. The
86      *  reference count of the object is incremented and it is the caller's
87      *  responsibility to unreference it when done.  This is needed to
88      *  accommodate the weak reference pattern used when the returned object
89      *  is new and has no other references.
90      *  @param typeface  The typeface to find, not nullptr.
91      *  @param glyphID   Specify which section of a large font is of interest.
92      */
93     static SkPDFFont* GetFontResource(SkPDFDocument* doc,
94                                       const SkGlyph* glyphs,
95                                       SkTypeface* typeface);
96 
97     /** Gets SkAdvancedTypefaceMetrics, and caches the result.
98      *  @param typeface can not be nullptr.
99      *  @return nullptr only when typeface is bad.
100      */
101     static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface* typeface,
102                                                        SkPDFDocument* canon);
103 
104     static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface* typeface,
105                                                        SkPDFDocument* canon);
106 
107     static void PopulateCommonFontDescriptor(SkPDFDict* descriptor,
108                                              const SkAdvancedTypefaceMetrics&,
109                                              uint16_t emSize,
110                                              int16_t defaultWidth);
111 
112     void emitSubset(SkPDFDocument*) const;
113 
114     /**
115      *  Return false iff the typeface has its NotEmbeddable flag set.
116      *  typeface is not nullptr
117      */
118     static bool CanEmbedTypeface(SkTypeface*, SkPDFDocument*);
119 
firstGlyphID()120     SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); }
lastGlyphID()121     SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); }
glyphUsage()122     const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; }
refTypeface()123     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
124 
125 private:
126     sk_sp<SkTypeface> fTypeface;
127     SkPDFGlyphUse fGlyphUsage;
128     SkPDFIndirectReference fIndirectReference;
129     SkAdvancedTypefaceMetrics::FontType fFontType;
130 
131     SkPDFFont(sk_sp<SkTypeface>,
132               SkGlyphID firstGlyphID,
133               SkGlyphID lastGlyphID,
134               SkAdvancedTypefaceMetrics::FontType fontType,
135               SkPDFIndirectReference indirectReference);
136     // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
137     // this will be a subset if the font has more than 255 glyphs.
138 
139     SkPDFFont() = delete;
140     SkPDFFont(const SkPDFFont&) = delete;
141     SkPDFFont& operator=(const SkPDFFont&) = delete;
142 };
143 
144 #endif
145