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