1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        pdffontsubsetcfft.h
3 // Purpose:
4 // Author:      Ulrich Telle
5 // Created:     2008-06-24
6 // Copyright:   (c) Ulrich Telle
7 // Licence:     wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /// \file pdffontsubsetcff.h Interface of the OpenType Font support classes
11 
12 #ifndef _PDF_FONT_SUBSET_CFF_H_
13 #define _PDF_FONT_SUBSET_CFF_H_
14 
15 // wxWidgets headers
16 #include <wx/dynarray.h>
17 #include <wx/mstream.h>
18 #include <wx/string.h>
19 #include <wx/wfstream.h>
20 
21 // wxPdfDocument headers
22 #include "wx/pdfdocdef.h"
23 #include "wx/pdffontdata.h"
24 
25 class WXDLLIMPEXP_FWD_PDFDOC wxPdfCffDecoder;
26 
27 class wxPdfCffDictElement;
28 class wxPdfCffFontObject;
29 class wxPdfCffIndexArray;
30 
31 WX_DECLARE_HASH_MAP(long, wxPdfCffDictElement*, wxIntegerHash, wxIntegerEqual, wxPdfCffDictionary);
32 
33 /// Class representing OpenType Font Subsets. (For internal use only)
34 class WXDLLIMPEXP_PDFDOC wxPdfFontSubsetCff
35 {
36 public:
37   /// Default constructor
38   wxPdfFontSubsetCff(const wxString& fileName);
39 
40   /// Default destructor
41   virtual ~wxPdfFontSubsetCff();
42 
43   /// Destruct dictionary
44   /**
45   * \param dict reference of the dictionary to be destructed
46   */
47   void DestructDictionary(wxPdfCffDictionary* dict);
48 
49   /// Create subset of a font
50   /**
51   * \param inFont stream containing the font data
52   * \param glyphsUsed a list of used glyphs
53   * \param includeCmap flag whether to include the CMap table
54   * \return the stream containing the font subset
55   */
56   wxMemoryOutputStream* CreateSubset(wxInputStream* inFont,
57                                      wxPdfChar2GlyphMap* glyphsUsed,
58                                      bool includeCmap = false);
59 
60 protected:
61   /// Read a font which is in CFF format
62   bool ReadCffFont();
63 
64   /// Read the font header
65   bool ReadHeader();
66 
67   /// Read the font name
68   bool ReadFontName();
69 
70   /// Read the top dictionary
71   bool ReadTopDict();
72 
73   /// Read the list of strings
74   bool ReadStrings();
75 
76   /// read the global subroutines
77   bool ReadGlobalSubroutines();
78 
79   /// Read a font index
80   bool ReadFontIndex(wxPdfCffIndexArray* index);
81 
82   /// Read a font dictionary
83   bool ReadFontDict(wxPdfCffDictionary* dict, int dictOffset, int dictSize);
84 
85   /// Read a FD selector
86   bool ReadFdSelect();
87 
88   /// Read the font dictionary of a CID font
89   bool ReadCidFontDict();
90 
91   /// Read a private dictionary
92   bool ReadPrivateDict(wxPdfCffDictionary* privateDict, wxPdfCffIndexArray* localSubIndex, int offset, int size);
93 
94   /// Find a dictionary element
95   wxPdfCffDictElement* FindDictElement(wxPdfCffDictionary* dict, int key);
96 
97   /// Set the argument of a dictionary element
98   void SetDictElementArgument(wxPdfCffDictionary* dict, int key, wxMemoryOutputStream& buffer);
99 
100   /// Remove an element from a dictionary
101   void RemoveDictElement(wxPdfCffDictionary* dict, int key);
102 
103   /// Decode an integer
104   int DecodeInteger();
105 
106   /// Encode an integer using maximal size
107   void EncodeIntegerMax(int value, wxMemoryOutputStream& buffer);
108 
109   /// Encode an integer
110   void EncodeInteger(int value, wxMemoryOutputStream& buffer);
111 
112   /// Seek to offset in the default font input stream
113   void SeekI(int offset);
114 
115   /// Get the current position in the default font input stream
116   int TellI();
117 
118   /// Get the size of the default font input stream
119   int GetSizeI();
120 
121   /// Read a byte from the default font input stream
122   unsigned char ReadByte();
123 
124   /// Read a short integer from the default font input stream
125   short ReadShort();
126 
127   /// Read an integer from the default font input stream
128   int ReadInt();
129 
130   /// Read an offset of specific size from the default font input stream
131   int ReadOffset(int offSize);
132 
133   /// Read the length of an operand from the default font input stream
134   int ReadOperandLength();
135 
136   /// Read an operator from the default font input stream
137   int ReadOperator();
138 
139   /// Read a string from the default font input stream
140   wxString ReadString(int length);
141 
142   /// Generate the subset
143   void GenerateFontSubset();
144 
145   /// Set the ROS strings
146   void SetRosStrings();
147 
148   /// Build the subset of the charstrings' list
149   void SubsetCharstrings();
150 
151   /// Build the subset of the font dictionary
152   void SubsetFontDict();
153 
154   /// Create a dictionary for a CID font
155   void CreateCidFontDict();
156 
157   /// Build the subset of the strings' list
158   void SubsetStrings();
159 
160   /// Build the subset of a dictionary string
161   void SubsetDictString(wxPdfCffDictionary* dict, int op);
162 
163   /// Build the subset of the strings' dictionary
164   void SubsetDictStrings(wxPdfCffDictionary* dict);
165 
166   /// Seek offset in the default output stream
167   void SeekO(int offset);
168 
169   /// Get the current position in the default output stream
170   int TellO();
171 
172   /// Write the font's subset to the default output stream
173   void WriteFontSubset();
174 
175   /// Write the font header
176   void WriteHeader();
177 
178   /// Write the font's name
179   void WriteName();
180 
181   /// Write the top dictionary
182   void WriteTopDict();
183 
184   /// Write a dictionary
185   void WriteDict(wxPdfCffDictionary* dict);
186 
187   /// Write a dictionary operator
188   void WriteDictOperator(wxPdfCffDictElement* op);
189 
190   /// Set a top dictionary operator to the current position
191   void SetTopDictOperatorToCurrentPosition(int op);
192 
193   /// Get the location of a dictionary in the default output stream
194   int GetLocation(wxPdfCffDictionary* dict, int op);
195 
196   /// Write the list of strings
197   void WriteStrings();
198 
199   /// Write the list of global subroutines
200   void WriteGlobalSubrs();
201 
202   /// Write the charset
203   void WriteCharset();
204 
205   /// Write the FD selector
206   void WriteFdSelect();
207 
208   /// Write the list of charstrings
209   void WriteCharStrings();
210 
211   /// Write the CID font dictionary
212   void WriteCidFontDict();
213 
214   /// Write a CID private dictionary and local subroutines
215   void WriteCidPrivateDictAndLocalSub();
216 
217   /// Write a private dictionary
218   void WritePrivateDict(int dictNum, wxPdfCffDictionary* parentDict, wxPdfCffDictionary* privateDict);
219 
220   /// Write the local subroutines
221   void WriteLocalSub(int dictNum, wxPdfCffDictionary* privateDict, wxPdfCffIndexArray* localSubIndex);
222 
223   /// Write an index
224   void WriteIndex(wxPdfCffIndexArray* index);
225 
226   /// Write an integer
227   void WriteInteger(int value, int size, wxMemoryOutputStream* buffer);
228 
229   /// Find  the local and global subroutines used
230   void FindLocalAndGlobalSubrsUsed();
231 
232   /// Build the subset of the subroutines
233   void SubsetSubrs(wxPdfCffIndexArray& subrIndex, wxPdfSortedArrayInt& subrsUsed);
234 
235   /// Find the subroutines used
236   void FindSubrsUsed(int fd, wxPdfCffIndexArray& localSubIndex,
237                      wxPdfSortedArrayInt& hSubrsUsed, wxArrayInt& lSubrsUsed);
238 
239   /// Find the global subroutines use
240   void FindGlobalSubrsUsed();
241 
242 private:
243   wxString              m_fileName;                ///< File name of the font file
244   wxInputStream*        m_inFont;                  ///< Font file input stream
245   wxMemoryOutputStream* m_outFont;                 ///< Subset output stream
246 
247   wxPdfCffDecoder*      m_decoder;                 ///< Decoder for CFF format
248 
249   int                   m_numGlyphsUsed;           ///< number of used glyphs
250   wxArrayInt            m_usedGlyphs;              ///< array of used glyphs
251   bool                  m_includeCmap;             ///< flag whether to include the CMap
252 
253   wxString              m_fontName;                ///< font name
254   wxPdfCffDictionary*   m_topDict;                 ///< reference of the top dictionary
255   wxPdfCffDictionary*   m_privateDict;             ///< reference of the private dictionary
256 
257   wxPdfCffIndexArray*   m_stringsIndex;            ///< index of strings
258   wxPdfCffIndexArray*   m_charstringsIndex;        ///< index of charstrings
259   wxPdfCffIndexArray*   m_globalSubrIndex;         ///< index of global subroutines
260   wxPdfCffIndexArray*   m_localSubrIndex;          ///< index of local subroutines
261 
262   wxPdfCffIndexArray*   m_stringsSubsetIndex;      ///< index of strings for subset
263   wxPdfCffIndexArray*   m_charstringsSubsetIndex;  ///< index of charstrings for subset
264 
265   wxArrayInt            m_fdSelect;                ///< array of FD selectors
266 
267   int                   m_hdrSize;                 ///< Header size
268   bool                  m_isCid;                   ///< Flag whether the font is a CID font
269   int                   m_numGlyphs;               ///< number of glyphs in the font
270   int                   m_numFontDicts;            ///< number of font dictionaries
271 
272   wxArrayPtrVoid        m_fdDict;                  ///< FD dictionary
273   wxArrayPtrVoid        m_fdPrivateDict;           ///< FD private dictionary
274   wxArrayPtrVoid        m_fdLocalSubrIndex;        ///< FD index of local subroutines
275 
276   wxArrayInt            m_fdSelectSubset;          ///< FD selectors of subset
277   int                   m_numSubsetFontDicts;      ///< number of font dictionaries for subset
278   wxArrayInt            m_fdSubsetMap;             ///< map of FD selectors for subset
279   wxArrayInt            m_privateDictOffset;       ///< offsets in private dictionary
280 
281   int                   m_globalBias;              ///< The bias for the global subroutines
282   int                   m_numHints;                ///< Number of arguments to the stem operators in a subroutine calculated recursively
283 
284   wxPdfSortedArrayInt*  m_hGlobalSubrsUsed;        ///< A HashMap for keeping the Global subroutines used in the font
285   wxArrayInt            m_lGlobalSubrsUsed;        ///< The Global SubroutinesUsed HashMaps as ArrayLists
286   wxPdfSortedArrayInt*  m_hLocalSubrsUsed;         ///< A HashMap for keeping the subroutines used in a non-cid font
287   wxArrayInt            m_lLocalSubrsUsed;         ///< The SubroutinesUsed HashMap as ArrayList
288 };
289 
290 #endif
291