128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org */
728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#ifndef SkPDFFont_DEFINED
1028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#define SkPDFFont_DEFINED
1128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
129db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org#include "SkAdvancedTypefaceMetrics.h"
139859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org#include "SkBitSet.h"
1428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkPDFTypes.h"
1528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkTDArray.h"
169859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org#include "SkTypeface.h"
1728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
18aa3af7b4692932c4fab4109b2d9f29ae40e49ad5Hal Canaryclass SkAutoGlyphCache;
19792c80f5a7b66e75d42664ccb298f31962c6654chalcanaryclass SkPDFCanon;
209859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgclass SkPDFFont;
219859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
2228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org/** \class SkPDFFont
2328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    A PDF Object class representing a font.  The font may have resources
2428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    attached to it in order to embed the font.  SkPDFFonts are canonicalized
2528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    so that resource deduplication will only include one copy of a font.
2628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    This class uses the same pattern as SkPDFGraphicState, a static weak
2728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org    reference to each instantiated class.
2828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org*/
2928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgclass SkPDFFont : public SkPDFDict {
309d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
3128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgpublic:
32d3b65972aad96453ff4510caa3e25a2b847c6d1eBrian Salomon    ~SkPDFFont() override;
3328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
3496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    /** Returns the typeface represented by this class. Returns nullptr for the
359db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org     *  default typeface.
3628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org     */
37cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    SkTypeface* typeface() const { return fTypeface.get(); }
3828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
39f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org    /** Returns the font type represented in this font.  For Type0 fonts,
40f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org     *  returns the type of the decendant font.
41f0ec2666d9a3f0f1662f0d63b5147628c49648aavandebo@chromium.org     */
42cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }
43671fec43e51533b9969502c072cd29d88ebef6earobertphillips
44c2f9ec1f5e4e8e98489cd5ea9356771cf4d8ce13halcanary    static SkAdvancedTypefaceMetrics::FontType FontType(const SkAdvancedTypefaceMetrics&);
45c2f9ec1f5e4e8e98489cd5ea9356771cf4d8ce13halcanary
46cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
47cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary        return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
48cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary               type == SkAdvancedTypefaceMetrics::kTrueType_Font;
49cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    }
50671fec43e51533b9969502c072cd29d88ebef6earobertphillips
51aa3af7b4692932c4fab4109b2d9f29ae40e49ad5Hal Canary    static SkAutoGlyphCache MakeVectorCache(SkTypeface*, int* sizeOut);
52aa3af7b4692932c4fab4109b2d9f29ae40e49ad5Hal Canary
53cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    /** Returns true if this font encoding supports glyph IDs above 255.
54671fec43e51533b9969502c072cd29d88ebef6earobertphillips     */
55cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }
560f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo
579859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    /** Return true if this font has an encoding for the passed glyph id.
5831dcee7b84ac8a50fe8269a39ac0431b01da48d1vandebo@chromium.org     */
59cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    bool hasGlyph(SkGlyphID gid) {
60cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary        return (gid >= fFirstGlyphID && gid <= fLastGlyphID) || gid == 0;
61cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    }
6231dcee7b84ac8a50fe8269a39ac0431b01da48d1vandebo@chromium.org
634871f2277738fa7e9232d25424c008b36dae4711halcanary    /** Convert the input glyph ID into the font encoding.  */
644871f2277738fa7e9232d25424c008b36dae4711halcanary    SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
654871f2277738fa7e9232d25424c008b36dae4711halcanary        if (this->multiByteGlyphs() || gid == 0) {
664871f2277738fa7e9232d25424c008b36dae4711halcanary            return gid;
674871f2277738fa7e9232d25424c008b36dae4711halcanary        }
684871f2277738fa7e9232d25424c008b36dae4711halcanary        SkASSERT(gid >= fFirstGlyphID && gid <= fLastGlyphID);
694871f2277738fa7e9232d25424c008b36dae4711halcanary        SkASSERT(fFirstGlyphID > 0);
704871f2277738fa7e9232d25424c008b36dae4711halcanary        return gid - fFirstGlyphID + 1;
714871f2277738fa7e9232d25424c008b36dae4711halcanary    }
722a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org
734871f2277738fa7e9232d25424c008b36dae4711halcanary    void noteGlyphUsage(SkGlyphID glyph) {
744871f2277738fa7e9232d25424c008b36dae4711halcanary        SkASSERT(this->hasGlyph(glyph));
754871f2277738fa7e9232d25424c008b36dae4711halcanary        fGlyphUsage.set(glyph);
76530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    }
77530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary
789db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org    /** Get the font resource for the passed typeface and glyphID. The
792a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org     *  reference count of the object is incremented and it is the caller's
802a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org     *  responsibility to unreference it when done.  This is needed to
812a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org     *  accommodate the weak reference pattern used when the returned object
822a22e10ab2946c5590cd2a258427ce3ccfca9bfavandebo@chromium.org     *  is new and has no other references.
834871f2277738fa7e9232d25424c008b36dae4711halcanary     *  @param typeface  The typeface to find, not nullptr.
849db86bb9cd1b77be0afc504ccc07026e4282d7e7ctguil@chromium.org     *  @param glyphID   Specify which section of a large font is of interest.
8528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org     */
865c1b360a89f85accd7dc446670f6f062c73e7e77Hal Canary    static sk_sp<SkPDFFont> GetFontResource(SkPDFCanon* canon,
875c1b360a89f85accd7dc446670f6f062c73e7e77Hal Canary                                            SkTypeface* typeface,
885c1b360a89f85accd7dc446670f6f062c73e7e77Hal Canary                                            SkGlyphID glyphID);
8928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
90209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    /** Gets SkAdvancedTypefaceMetrics, and caches the result.
914871f2277738fa7e9232d25424c008b36dae4711halcanary     *  @param typeface can not be nullptr.
924871f2277738fa7e9232d25424c008b36dae4711halcanary     *  @return nullptr only when typeface is bad.
934871f2277738fa7e9232d25424c008b36dae4711halcanary     */
94cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary    static const SkAdvancedTypefaceMetrics* GetMetrics(SkTypeface* typeface,
95cee13425b5cd862189d1e5d7cf8f258bccae5f5dhalcanary                                                       SkPDFCanon* canon);
968eccc308c8adcdf26ffc7c4dd538b71f33c6f22bhalcanary
97530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    /** Subset the font based on current usage.
98530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary     *  Must be called before emitObject().
999859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org     */
100530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    virtual void getFontSubset(SkPDFCanon*) = 0;
101fb62b3d423fa34c672df42f47017dbef087d19e9halcanary
10266a82f3872abf4ebb98b3915b2a9ecc73ad352c5halcanary    /**
10366a82f3872abf4ebb98b3915b2a9ecc73ad352c5halcanary     *  Return false iff the typeface has its NotEmbeddable flag set.
1044871f2277738fa7e9232d25424c008b36dae4711halcanary     *  typeface is not nullptr
10566a82f3872abf4ebb98b3915b2a9ecc73ad352c5halcanary     */
10666a82f3872abf4ebb98b3915b2a9ecc73ad352c5halcanary    static bool CanEmbedTypeface(SkTypeface*, SkPDFCanon*);
10766a82f3872abf4ebb98b3915b2a9ecc73ad352c5halcanary
1089859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.orgprotected:
1099859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org    // Common constructor to handle common members.
110530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    struct Info {
111530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        sk_sp<SkTypeface> fTypeface;
112530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        SkGlyphID fFirstGlyphID;
113530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        SkGlyphID fLastGlyphID;
114530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary        SkAdvancedTypefaceMetrics::FontType fFontType;
115530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    };
116530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    SkPDFFont(Info);
1173287588a467ee579c3947fe13c6add5048b14aa9halcanary
1183287588a467ee579c3947fe13c6add5048b14aa9halcanary    SkGlyphID firstGlyphID() const { return fFirstGlyphID; }
1193287588a467ee579c3947fe13c6add5048b14aa9halcanary    SkGlyphID lastGlyphID() const { return fLastGlyphID; }
120530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    const SkBitSet& glyphUsage() const { return fGlyphUsage; }
1213287588a467ee579c3947fe13c6add5048b14aa9halcanary    sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
1229859428e71c6041928e6dd741ae3284017e78e81vandebo@chromium.org
123bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary    void drop() override;
124bae235eb07cdfeb6dd92efa2b2143fa9e91d9d04halcanary
12528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.orgprivate:
12648810a023705ffac466adb93efdb3861cf2e197ahalcanary    sk_sp<SkTypeface> fTypeface;
127530032a18e373ee673ae96fdbfa1fae6292f8f08halcanary    SkBitSet fGlyphUsage;
12828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
1293287588a467ee579c3947fe13c6add5048b14aa9halcanary    // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
1303287588a467ee579c3947fe13c6add5048b14aa9halcanary    // this will be a subset if the font has more than 255 glyphs.
1314871f2277738fa7e9232d25424c008b36dae4711halcanary    const SkGlyphID fFirstGlyphID;
1324871f2277738fa7e9232d25424c008b36dae4711halcanary    const SkGlyphID fLastGlyphID;
1334871f2277738fa7e9232d25424c008b36dae4711halcanary    const SkAdvancedTypefaceMetrics::FontType fFontType;
13428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
135ab1c13864df34aecfd4840ea7d1e4f8730b44f4ecommit-bot@chromium.org    typedef SkPDFDict INHERITED;
13628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org};
13728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org
13828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#endif
139