Scribus
Open source desktop publishing at your fingertips
cff.h
1 //
2 // cff.h
3 // Scribus
4 //
5 // Created by Andreas Vox on 04.05.15.
6 //
7 //
8 
9 #ifndef Scribus__cff_h
10 #define Scribus__cff_h
11 
12 
13 #include "scribusapi.h"
14 
15 #include <QByteArray>
16 #include <QDataStream>
17 #include <QHash>
18 #include <QList>
19 #include <QMap>
20 #include <QString>
21 
22 #include <ft2build.h>
23 #include FT_FREETYPE_H
24 
25 namespace cff {
26 
27  typedef quint16 sid_type;
28  typedef uint operator_type;
29 
30  enum sid_range {
31  sid_min = 0,
32  sid_last_std = 390,
33  sid_max = 64999,
34  sid_max1 = 65000
35  };
36 
37  enum CFF_Header_Format {
38  cff_major = 0,
39  cff_minor = 1,
40  cff_hdrSize = 2,
41  cff_offSize = 3
42  };
43 
44 
45  enum CFF_INDEX_Format {
46  cff_idx_count = 0,
47  cff_idx_offsize = 2,
48  cff_idx_offsets = 3
49  };
50 
51 
52  enum cff_Real_Format {
53  cff_nibble_maxDigit = 9,
54  cff_nibble_Point = 10,
55  cff_nibble_PosExp = 11,
56  cff_nibble_NegExp = 12,
57  cff_nibble_Reserved = 13,
58  cff_nibble_Minus = 14,
59  cff_nibble_End = 15
60  };
61 
62 
63  enum CFF_DICT_Format {
64  cff_dict_version = 0x00,
65  cff_dict_Notice = 0x01,
66  cff_dict_FullName = 0x02,
67  cff_dict_FamilyName = 0x03,
68  cff_dict_Weight = 0x04,
69  cff_dict_FontBBox = 0x05,
70  cff_dict_BlueValues = 0x06,
71  cff_dict_OtherBlues = 0x07,
72  cff_dict_FamilyBlues = 0x08,
73  cff_dict_FamilyOtherBlues = 0x09,
74  cff_dict_StdHW = 0x0a,
75  cff_dict_StdVW = 0x0b,
76  cff_dict_TwoBytes = 12,
77  cff_dict_UniqueID = 0x0d,
78  cff_dict_XUID = 0x0e,
79  cff_dict_charset = 0x0f,
80  cff_dict_Encoding = 0x10,
81  cff_dict_CharStrings = 0x11,
82  cff_dict_Private = 0x12,
83  cff_dict_Subrs = 0x13,
84  cff_dict_defaultWidthX = 0x14,
85  cff_dict_nominalWidthX = 0x15,
86  // 0x16+ reserved
87  cff_dict_Card16 = 28,
88  cff_dict_Card32 = 29,
89  cff_dict_Real = 30,
90  cff_dict_minOperand = 32,
91  cff_dict_maxSmallCard = 246,
92  cff_dict_biasSmallCard = -139,
93  cff_dict_minPosCard = 247,
94  cff_dict_maxPosCard = 250,
95  cff_dict_biasPosCard = 108,
96  cff_dict_minNegCard = 251,
97  cff_dict_maxNegCard = 254,
98  cff_dict_biasNegCard = -108,
99  cff_dict_Copyright = 0x0c00,
100  cff_dict_isFixedPitch = 0x0c01,
101  cff_dict_ItalicAngle = 0x0c02,
102  cff_dict_UnderlinePosition = 0x0c03,
103  cff_dict_UnderlineThickness = 0x0c04,
104  cff_dict_CharstringType = 0x0c06,
105  cff_dict_FontMatrix = 0x0c07,
106  cff_dict_StrokeWidth = 0x0c08,
107  cff_dict_BlueScale = 0x0c09,
108  cff_dict_BlueShift = 0x0c0a,
109  cff_dict_BlueFuzz = 0x0c0b,
110  cff_dict_StemSnapH = 0x0c0c,
111  cff_dict_StemSnapV = 0x0c0d,
112  cff_dict_ForceBold = 0x0c0e,
113  // 0c 0f -Reserved-
114  // 0c 10 -Reserved-
115  cff_dict_LanguageGroup = 0x0c11,
116  cff_dict_ExpansionFactor = 0x0c12,
117  cff_dict_initialRandomSeed = 0x0c13,
118  cff_dict_SyntheticBase = 0x0c14,
119  cff_dict_PostScript = 0x0c15,
120  cff_dict_BaseFontName = 0x0c16,
121  cff_dict_BaseFontBlend = 0x0c17,
122  // 0c 18 -Reserved-
123  // 0c 19 -Reserved-
124  // 0c 1a -Reserved-
125  // 0c 1b -Reserved-
126  // 0c 1c -Reserved-
127  // 0c 1d -Reserved-
128  cff_dict_ROS = 0x0c1e,
129  cff_dict_CIDFontVersion = 0x0c1f,
130  cff_dict_CIDFontRevision = 0x0c20,
131  cff_dict_CIDFontType = 0x0c21,
132  cff_dict_CIDCount = 0x0c22,
133  cff_dict_UIDBase = 0x0c23,
134  cff_dict_FDArray = 0x0c24,
135  cff_dict_FDSelect = 0x0c25,
136  cff_dict_FontName = 0x0c26
137  };
138 
139 
140  enum CFF_Variant_Type {
141  cff_varnt_Error = 0,
142  cff_varnt_Bool = 1,
143  cff_varnt_Card = 2,
144  cff_varnt_SID = 3,
145  cff_varnt_Real = 4,
146  cff_varnt_Array = 5,
147  cff_varnt_Delta = 6,
148  cff_varnt_Operator = 7
149  };
150 
151 
152  struct CFF_Number {
153  long long card;
154  int exponent;
155  uchar type;
156  bool isCardinal() const;
157  double toDouble() const;
158  int toCardinal() const;
159  };
160 
161 
162  struct CFF_Variant {
163  uchar type;
164  QList<CFF_Number> array;
165  CFF_Variant() : type(cff_varnt_Error) {}
166  CFF_Variant(CFF_Number val) : type(val.type), array() { array.append(val); }
167  CFF_Variant(QList<CFF_Number> arr) : type(cff_varnt_Array), array(arr) {}
168  };
169 
170 
171  class CFF {
172  public:
174  CFF();
175  CFF(const QByteArray& cff);
176 
177  uint readCard(uint pos) const;
178  QByteArray readSegment(uint pos, uint size) const;
179  QMap<operator_type,CFF_Variant> getDict(const QByteArray& dict) const;
180  QList<QByteArray> readIndex(uint& pos) const;
181  CFF extractSubset(uint faceIndex, QList<uint> cids) const;
182 
183  void dump();
184  QByteArray dump(const CFF_Variant& var) const;
185 
186  const QByteArray& data() const {
187  return bytes;
188  }
189 
190  QList<QByteArray> fontNames() const {
191  return fontTopDicts.keys();
192  }
193 
194  uint offset(uint unscaled)
195  {
196  return unscaled * offsetSize;
197  }
198 
199  QByteArray string(sid_type sid) const {
200  return sid < strings.length()? strings[sid] : "";
201  }
202 
203  sid_type sid(const QByteArray str) const {
204  return sids.contains(str)? sids[str] : sid_max1;
205  }
206 
207  void dump(QDataStream& out) const;
208 
209  private:
210  QByteArray bytes;
211  uint offsetSize;
212 
213  QList<QByteArray> names;
214  QMap<QByteArray, QMap<uint,CFF_Variant> > fontTopDicts;
215  QList<QByteArray> strings;
216  QHash<QByteArray,uint> sids;
217  QList<QByteArray> globalSubr;
218 
219  sid_type createSid(const QByteArray& str);
220 
221  CFF_Number parseDictElement(const QByteArray& dict, uint& pos) const;
222  CFF_Number parseReal(const QByteArray& dict, uint& pos) const;
223  CFF_Number parseCard(const QByteArray& dict, uint& pos) const;
224  QList<sid_type> readCharset(uint nGlyphs, uint& pos) const;
225  QList<uint> readEncoding(uint& pos) const;
226 
229  uint writeTopDict(QByteArray name, QMap<operator_type, CFF_Variant> dict, QList<QByteArray> oldStrings, QHash<operator_type, uint>& patches);
231  uint writeSegment(const QByteArray& data);
232  void patch(QHash<operator_type, uint> patchPositions, uint patchOffset, operator_type op, uint offset, uint length = 0);
233 
234  QByteArray makeCharset(QList<sid_type>) const;
235  QByteArray makeEncoding(QList<uint>) const;
236  QByteArray makeIndex(QList<QByteArray> data) const;
237  QByteArray makeDict(QMap<operator_type, CFF_Variant> dict, QList<QByteArray> oldStrings, QHash<operator_type, uint>& patchAddresses);
238  };
239 
240  QByteArray extractFace(const QByteArray& cff, int faceIndex);
241  QByteArray subsetFace(const QByteArray& cff, QList<uint> cids);
242 }
243 
244 
245 #endif /* defined(Scribus__cff_h) */
Definition: cff.cpp:15
Definition: cff.h:152
Definition: cff.h:162
CFF()
For creating new CFF fonts.
Definition: cff.cpp:549
Definition: cff.h:171