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