• 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 
8 
9 #ifndef SkPDFFont_DEFINED
10 #define SkPDFFont_DEFINED
11 
12 #include "SkAdvancedTypefaceMetrics.h"
13 #include "SkBitSet.h"
14 #include "SkPDFTypes.h"
15 #include "SkTDArray.h"
16 #include "SkTypeface.h"
17 
18 class SkAutoGlyphCache;
19 class SkPDFCanon;
20 class SkPDFFont;
21 
22 /** \class SkPDFFont
23     A PDF Object class representing a font.  The font may have resources
24     attached to it in order to embed the font.  SkPDFFonts are canonicalized
25     so that resource deduplication will only include one copy of a font.
26     This class uses the same pattern as SkPDFGraphicState, a static weak
27     reference to each instantiated class.
28 */
29 class SkPDFFont : public SkPDFDict {
30 
31 public:
32     ~SkPDFFont() override;
33 
34     /** Returns the typeface represented by this class. Returns nullptr for the
35      *  default typeface.
36      */
typeface()37     SkTypeface* typeface() const { return fTypeface.get(); }
38 
39     /** Returns the font type represented in this font.  For Type0 fonts,
40      *  returns the type of the decendant font.
41      */
getType()42     SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
43 
44     static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&);
45 
IsMultiByte(SkAdvancedTypefaceMetrics::FontType type)46     static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
47         return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
48                type == SkAdvancedTypefaceMetrics::kTrueType_Font;
49     }
50 
51     static SkAutoGlyphCache MakeVectorCache(SkTypeface*, int* sizeOut);
52 
53     /** Returns true if this font encoding supports glyph IDs above 255.
54      */
multiByteGlyphs()55     bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }
56 
57     /** Return true if this font has an encoding for the passed glyph id.
58      */
hasGlyph(SkGlyphID gid)59     bool hasGlyph(SkGlyphID gid) {
60         return (gid >= fFirstGlyphID && gid <= fLastGlyphID) || gid == 0;
61     }
62 
63     /** Convert the input glyph ID into the font encoding.  */
glyphToPDFFontEncoding(SkGlyphID gid)64     SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
65         if (this->multiByteGlyphs() || gid == 0) {
66             return gid;
67         }
68         SkASSERT(gid >= fFirstGlyphID && gid <= fLastGlyphID);
69         SkASSERT(fFirstGlyphID > 0);
70         return gid - fFirstGlyphID + 1;
71     }
72 
noteGlyphUsage(SkGlyphID glyph)73     void noteGlyphUsage(SkGlyphID glyph) {
74         SkASSERT(this->hasGlyph(glyph));
75         fGlyphUsage.set(glyph);
76     }
77 
78     /** Get the font resource for the passed typeface and glyphID. The
79      *  reference count of the object is incremented and it is the caller's
80      *  responsibility to unreference it when done.  This is needed to
81      *  accommodate the weak reference pattern used when the returned object
82      *  is new and has no other references.
83      *  @param typeface  The typeface to find, not nullptr.
84      *  @param glyphID   Specify which section of a large font is of interest.
85      */
86     static sk_sp<SkPDFFont> GetFontResource(SkPDFCanon* canon,
87                                             SkTypeface* typeface,
88                                             SkGlyphID glyphID);
89 
90     /** Gets SkAdvancedTypefaceMetrics, and caches the result.
91      *  @param typeface can not be nullptr.
92      *  @return nullptr only when typeface is bad.
93      */
94     static const SkAdvancedTypefaceMetrics* GetMetrics(SkTypeface* typeface,
95                                                        SkPDFCanon* canon);
96 
97     /** Subset the font based on current usage.
98      *  Must be called before emitObject().
99      */
100     virtual void getFontSubset(SkPDFCanon*) = 0;
101 
102     /**
103      *  Return false iff the typeface has its NotEmbeddable flag set.
104      *  typeface is not nullptr
105      */
106     static bool CanEmbedTypeface(SkTypeface*, SkPDFCanon*);
107 
108 protected:
109     // Common constructor to handle common members.
110     struct Info {
111         sk_sp<SkTypeface> fTypeface;
112         SkGlyphID fFirstGlyphID;
113         SkGlyphID fLastGlyphID;
114         SkAdvancedTypefaceMetrics::FontType fFontType;
115     };
116     SkPDFFont(Info);
117 
firstGlyphID()118     SkGlyphID firstGlyphID() const { return fFirstGlyphID; }
lastGlyphID()119     SkGlyphID lastGlyphID() const { return fLastGlyphID; }
glyphUsage()120     const SkBitSet& glyphUsage() const { return fGlyphUsage; }
refTypeface()121     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
122 
123     void drop() override;
124 
125 private:
126     sk_sp<SkTypeface> fTypeface;
127     SkBitSet fGlyphUsage;
128 
129     // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
130     // this will be a subset if the font has more than 255 glyphs.
131     const SkGlyphID fFirstGlyphID;
132     const SkGlyphID fLastGlyphID;
133     const SkAdvancedTypefaceMetrics::FontType fFontType;
134 
135     typedef SkPDFDict INHERITED;
136 };
137 
138 #endif
139