michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkPDFFont_DEFINED michael@0: #define SkPDFFont_DEFINED michael@0: michael@0: #include "SkAdvancedTypefaceMetrics.h" michael@0: #include "SkBitSet.h" michael@0: #include "SkPDFTypes.h" michael@0: #include "SkTDArray.h" michael@0: #include "SkThread.h" michael@0: #include "SkTypeface.h" michael@0: michael@0: class SkPaint; michael@0: class SkPDFCatalog; michael@0: class SkPDFFont; michael@0: michael@0: class SkPDFGlyphSet : public SkNoncopyable { michael@0: public: michael@0: SkPDFGlyphSet(); michael@0: michael@0: void set(const uint16_t* glyphIDs, int numGlyphs); michael@0: bool has(uint16_t glyphID) const; michael@0: void merge(const SkPDFGlyphSet& usage); michael@0: void exportTo(SkTDArray* glyphIDs) const; michael@0: michael@0: private: michael@0: SkBitSet fBitSet; michael@0: }; michael@0: michael@0: class SkPDFGlyphSetMap : public SkNoncopyable { michael@0: public: michael@0: struct FontGlyphSetPair { michael@0: FontGlyphSetPair(SkPDFFont* font, SkPDFGlyphSet* glyphSet); michael@0: michael@0: SkPDFFont* fFont; michael@0: SkPDFGlyphSet* fGlyphSet; michael@0: }; michael@0: michael@0: SkPDFGlyphSetMap(); michael@0: ~SkPDFGlyphSetMap(); michael@0: michael@0: class F2BIter { michael@0: public: michael@0: explicit F2BIter(const SkPDFGlyphSetMap& map); michael@0: const FontGlyphSetPair* next() const; michael@0: void reset(const SkPDFGlyphSetMap& map); michael@0: michael@0: private: michael@0: const SkTDArray* fMap; michael@0: mutable int fIndex; michael@0: }; michael@0: michael@0: void merge(const SkPDFGlyphSetMap& usage); michael@0: void reset(); michael@0: michael@0: void noteGlyphUsage(SkPDFFont* font, const uint16_t* glyphIDs, michael@0: int numGlyphs); michael@0: michael@0: private: michael@0: SkPDFGlyphSet* getGlyphSetForFont(SkPDFFont* font); michael@0: michael@0: SkTDArray fMap; michael@0: }; michael@0: michael@0: michael@0: /** \class SkPDFFont michael@0: A PDF Object class representing a font. The font may have resources michael@0: attached to it in order to embed the font. SkPDFFonts are canonicalized michael@0: so that resource deduplication will only include one copy of a font. michael@0: This class uses the same pattern as SkPDFGraphicState, a static weak michael@0: reference to each instantiated class. michael@0: */ michael@0: class SkPDFFont : public SkPDFDict { michael@0: SK_DECLARE_INST_COUNT(SkPDFFont) michael@0: public: michael@0: virtual ~SkPDFFont(); michael@0: michael@0: virtual void getResources(const SkTSet& knownResourceObjects, michael@0: SkTSet* newResourceObjects); michael@0: michael@0: /** Returns the typeface represented by this class. Returns NULL for the michael@0: * default typeface. michael@0: */ michael@0: SkTypeface* typeface(); michael@0: michael@0: /** Returns the font type represented in this font. For Type0 fonts, michael@0: * returns the type of the decendant font. michael@0: */ michael@0: virtual SkAdvancedTypefaceMetrics::FontType getType(); michael@0: michael@0: /** Returns true if this font encoding supports glyph IDs above 255. michael@0: */ michael@0: virtual bool multiByteGlyphs() const = 0; michael@0: michael@0: /** Return true if this font has an encoding for the passed glyph id. michael@0: */ michael@0: bool hasGlyph(uint16_t glyphID); michael@0: michael@0: /** Convert (in place) the input glyph IDs into the font encoding. If the michael@0: * font has more glyphs than can be encoded (like a type 1 font with more michael@0: * than 255 glyphs) this method only converts up to the first out of range michael@0: * glyph ID. michael@0: * @param glyphIDs The input text as glyph IDs. michael@0: * @param numGlyphs The number of input glyphs. michael@0: * @return Returns the number of glyphs consumed. michael@0: */ michael@0: size_t glyphsToPDFFontEncoding(uint16_t* glyphIDs, size_t numGlyphs); michael@0: michael@0: /** Get the font resource for the passed typeface and glyphID. The michael@0: * reference count of the object is incremented and it is the caller's michael@0: * responsibility to unreference it when done. This is needed to michael@0: * accommodate the weak reference pattern used when the returned object michael@0: * is new and has no other references. michael@0: * @param typeface The typeface to find. michael@0: * @param glyphID Specify which section of a large font is of interest. michael@0: */ michael@0: static SkPDFFont* GetFontResource(SkTypeface* typeface, michael@0: uint16_t glyphID); michael@0: michael@0: /** Subset the font based on usage set. Returns a SkPDFFont instance with michael@0: * subset. michael@0: * @param usage Glyph subset requested. michael@0: * @return NULL if font does not support subsetting, a new instance michael@0: * of SkPDFFont otherwise. michael@0: */ michael@0: virtual SkPDFFont* getFontSubset(const SkPDFGlyphSet* usage); michael@0: michael@0: protected: michael@0: // Common constructor to handle common members. michael@0: SkPDFFont(SkAdvancedTypefaceMetrics* fontInfo, SkTypeface* typeface, michael@0: SkPDFDict* relatedFontDescriptor); michael@0: michael@0: // Accessors for subclass. michael@0: SkAdvancedTypefaceMetrics* fontInfo(); michael@0: void setFontInfo(SkAdvancedTypefaceMetrics* info); michael@0: uint16_t firstGlyphID() const; michael@0: uint16_t lastGlyphID() const; michael@0: void setLastGlyphID(uint16_t glyphID); michael@0: michael@0: // Add object to resource list. michael@0: void addResource(SkPDFObject* object); michael@0: michael@0: // Accessors for FontDescriptor associated with this object. michael@0: SkPDFDict* getFontDescriptor(); michael@0: void setFontDescriptor(SkPDFDict* descriptor); michael@0: michael@0: // Add common entries to FontDescriptor. michael@0: bool addCommonFontDescriptorEntries(int16_t defaultWidth); michael@0: michael@0: /** Set fFirstGlyphID and fLastGlyphID to span at most 255 glyphs, michael@0: * including the passed glyphID. michael@0: */ michael@0: void adjustGlyphRangeForSingleByteEncoding(int16_t glyphID); michael@0: michael@0: // Generate ToUnicode table according to glyph usage subset. michael@0: // If subset is NULL, all available glyph ids will be used. michael@0: void populateToUnicodeTable(const SkPDFGlyphSet* subset); michael@0: michael@0: // Create instances of derived types based on fontInfo. michael@0: static SkPDFFont* Create(SkAdvancedTypefaceMetrics* fontInfo, michael@0: SkTypeface* typeface, uint16_t glyphID, michael@0: SkPDFDict* relatedFontDescriptor); michael@0: michael@0: static bool Find(uint32_t fontID, uint16_t glyphID, int* index); michael@0: michael@0: private: michael@0: class FontRec { michael@0: public: michael@0: SkPDFFont* fFont; michael@0: uint32_t fFontID; michael@0: uint16_t fGlyphID; michael@0: michael@0: // A fGlyphID of 0 with no fFont always matches. michael@0: bool operator==(const FontRec& b) const; michael@0: FontRec(SkPDFFont* font, uint32_t fontID, uint16_t fGlyphID); michael@0: }; michael@0: michael@0: SkAutoTUnref fTypeface; michael@0: michael@0: // The glyph IDs accessible with this font. For Type1 (non CID) fonts, michael@0: // this will be a subset if the font has more than 255 glyphs. michael@0: uint16_t fFirstGlyphID; michael@0: uint16_t fLastGlyphID; michael@0: // The font info is only kept around after construction for large michael@0: // Type1 (non CID) fonts that need multiple "fonts" to access all glyphs. michael@0: SkAutoTUnref fFontInfo; michael@0: SkTDArray fResources; michael@0: SkAutoTUnref fDescriptor; michael@0: michael@0: SkAdvancedTypefaceMetrics::FontType fFontType; michael@0: michael@0: // This should be made a hash table if performance is a problem. michael@0: static SkTDArray& CanonicalFonts(); michael@0: static SkBaseMutex& CanonicalFontsMutex(); michael@0: typedef SkPDFDict INHERITED; michael@0: }; michael@0: michael@0: #endif