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
18class SkAutoGlyphCache;
19class SkPDFCanon;
20class 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*/
29class SkPDFFont : public SkPDFDict {
30
31public:
32    ~SkPDFFont() override;
33
34    /** Returns the typeface represented by this class. Returns nullptr for the
35     *  default typeface.
36     */
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     */
42    SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
43
44    static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&);
45
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     */
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     */
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.  */
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
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
108protected:
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
118    SkGlyphID firstGlyphID() const { return fFirstGlyphID; }
119    SkGlyphID lastGlyphID() const { return fLastGlyphID; }
120    const SkBitSet& glyphUsage() const { return fGlyphUsage; }
121    sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
122
123    void drop() override;
124
125private:
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