1 // -*- related-file-name: "../../libefont/t1cs.cc" -*-
2 #ifndef EFONT_T1CS_HH
3 #define EFONT_T1CS_HH
4 #include <lcdf/permstr.hh>
5 #include <lcdf/string.hh>
6 #include <lcdf/vector.hh>
7 #include <lcdf/inttypes.h>
8 namespace Efont {
9
10 // Allow unknown doubles to have some `fuzz' -- so if an unknown double
11 // is a bit off from the canonical UNKDOUBLE value, we'll still recognize
12 // it as unknown. (Useful for interpolation.)
13 #define UNKDOUBLE -9.79797e97
14 #define MIN_KNOWN_DOUBLE -9.69696e97
15 #define KNOWN(d) ((d) >= MIN_KNOWN_DOUBLE)
16
17 class CharstringProgram;
18 class CharstringInterp;
19 struct CharstringContext;
20 class MultipleMasterSpace;
21 class Type1Encoding;
22
23 class Charstring { public:
24
Charstring()25 Charstring() { }
26 virtual ~Charstring();
27
28 virtual bool process(CharstringInterp &) const = 0;
29
30 enum Commands {
31 cError = 0,
32 cHstem = 1,
33 cVstem = 3,
34 cVmoveto = 4,
35 cRlineto = 5,
36 cHlineto = 6,
37 cVlineto = 7,
38 cRrcurveto = 8,
39 cClosepath = 9,
40 cCallsubr = 10,
41 cReturn = 11,
42 cEscape = 12,
43 cHsbw = 13,
44 cEndchar = 14,
45 cBlend = 16,
46 cHstemhm = 18,
47 cHintmask = 19,
48 cCntrmask = 20,
49 cRmoveto = 21,
50 cHmoveto = 22,
51 cVstemhm = 23,
52 cRcurveline = 24,
53 cRlinecurve = 25,
54 cVvcurveto = 26,
55 cHhcurveto = 27,
56 cShortint = 28,
57 cCallgsubr = 29,
58 cVhcurveto = 30,
59 cHvcurveto = 31,
60
61 cEscapeDelta = 32,
62 cDotsection = 32 + 0,
63 cVstem3 = 32 + 1,
64 cHstem3 = 32 + 2,
65 cAnd = 32 + 3,
66 cOr = 32 + 4,
67 cNot = 32 + 5,
68 cSeac = 32 + 6,
69 cSbw = 32 + 7,
70 cStore = 32 + 8,
71 cAbs = 32 + 9,
72 cAdd = 32 + 10,
73 cSub = 32 + 11,
74 cDiv = 32 + 12,
75 cLoad = 32 + 13,
76 cNeg = 32 + 14,
77 cEq = 32 + 15,
78 cCallothersubr = 32 + 16,
79 cPop = 32 + 17,
80 cDrop = 32 + 18,
81 cPut = 32 + 20,
82 cGet = 32 + 21,
83 cIfelse = 32 + 22,
84 cRandom = 32 + 23,
85 cMul = 32 + 24,
86 cSqrt = 32 + 26,
87 cDup = 32 + 27,
88 cExch = 32 + 28,
89 cIndex = 32 + 29,
90 cRoll = 32 + 30,
91 cSetcurrentpoint = 32 + 33,
92 cHflex = 32 + 34,
93 cFlex = 32 + 35,
94 cHflex1 = 32 + 36,
95 cFlex1 = 32 + 37,
96
97 cLastCommand = cFlex1
98 };
99
100 enum OthersubrCommands {
101 othcFlexend = 0,
102 othcFlexbegin = 1,
103 othcFlexmiddle = 2,
104 othcReplacehints = 3,
105 othcMM1 = 14,
106 othcMM2 = 15,
107 othcMM3 = 16,
108 othcMM4 = 17,
109 othcMM6 = 18,
110 othcITC_load = 19,
111 othcITC_add = 20,
112 othcITC_sub = 21,
113 othcITC_mul = 22,
114 othcITC_div = 23,
115 othcITC_put = 24,
116 othcITC_get = 25,
117 othcITC_unknown = 26,
118 othcITC_ifelse = 27,
119 othcITC_random = 28
120 };
121
122 static String command_name(int);
123 static const char * const command_names[];
124
125 static const char * const standard_encoding[256];
126
127 };
128
129
130 class Type1Charstring : public Charstring { public:
131
Type1Charstring()132 Type1Charstring() { }
133 inline Type1Charstring(const String &); // unencrypted
134 Type1Charstring(int lenIV, const String &); // encrypted
135 // default copy constructor
136 // default destructor
137 // default assignment operator
138
139 inline const uint8_t *data() const;
length() const140 int length() const { return _s.length(); }
operator String::unspecified_bool_type() const141 operator String::unspecified_bool_type() const { return _s; }
142
143 inline const String &data_string() const;
144 inline String substring(int pos, int len) const;
145 int first_caret_after(int pos) const;
146
147 inline void assign(const String &);
148 void prepend(const Type1Charstring &);
149 void assign_substring(int pos, int len, const String &);
150
151 bool process(CharstringInterp &) const;
152
153 private:
154
155 mutable String _s;
156 mutable int _key;
157
158 void decrypt() const;
159
160 };
161
162
163 class Type2Charstring : public Charstring { public:
164
Type2Charstring()165 Type2Charstring() { }
166 inline Type2Charstring(const String &);
167 // default copy constructor
168 // default destructor
169 // default assignment operator
170
171 inline const uint8_t *data() const;
length() const172 int length() const { return _s.length(); }
173
174 bool process(CharstringInterp &) const;
175
176 private:
177
178 String _s;
179
180 };
181
182
183 struct CharstringContext {
184
CharstringContextEfont::CharstringContext185 CharstringContext(const CharstringProgram *program_, const Charstring *cs_) : program(program_), cs(cs_) { }
186
operator String::unspecified_bool_typeEfont::CharstringContext187 operator String::unspecified_bool_type() const {
188 return cs != 0 ? &String::length : 0;
189 }
190
191 const CharstringProgram *program;
192 const Charstring *cs;
193
194 };
195
196
197 class CharstringProgram { public:
198
199 explicit CharstringProgram(unsigned units_per_em);
~CharstringProgram()200 virtual ~CharstringProgram() { }
201
font_name() const202 virtual PermString font_name() const { return PermString(); }
203 virtual void font_matrix(double[6]) const;
units_per_em() const204 unsigned units_per_em() const { return _units_per_em; }
205
206 inline const CharstringProgram *program(int) const;
207 virtual const CharstringProgram *child_program(int) const;
parent_program() const208 bool parent_program() const { return _parent_program; }
set_parent_program(bool pp)209 void set_parent_program(bool pp) { _parent_program = pp; }
210
nsubrs() const211 virtual int nsubrs() const { return 0; }
subr(int) const212 virtual Charstring *subr(int) const { return 0; }
subr_bias() const213 virtual int subr_bias() const { return 0; }
214
ngsubrs() const215 virtual int ngsubrs() const { return 0; }
gsubr(int) const216 virtual Charstring *gsubr(int) const { return 0; }
gsubr_bias() const217 virtual int gsubr_bias() const { return 0; }
218
219 inline int nxsubrs(bool g) const;
220 inline Charstring *xsubr(bool g, int) const;
221 inline int xsubr_bias(bool g) const;
222
nglyphs() const223 virtual int nglyphs() const { return 0; }
glyph_name(int) const224 virtual PermString glyph_name(int) const { return PermString(); }
225 virtual void glyph_names(Vector<PermString> &) const;
glyph(int) const226 virtual Charstring *glyph(int) const { return 0; }
glyph(PermString) const227 virtual Charstring *glyph(PermString) const { return 0; }
228
229 inline CharstringContext glyph_context(int) const;
230 inline CharstringContext glyph_context(PermString) const;
231
is_mm() const232 virtual bool is_mm() const { return mmspace() != 0; }
mmspace() const233 virtual MultipleMasterSpace *mmspace() const { return 0; }
234 enum VectorType { VEC_WEIGHT = 0, VEC_NORM_DESIGN = 1, VEC_DESIGN = 2 };
235 virtual Vector<double> *mm_vector(VectorType, bool writable) const;
236
type1_encoding() const237 virtual Type1Encoding *type1_encoding() const { return 0; }
238
239 virtual double global_width_x(bool is_nominal) const;
240
241 private:
242
243 bool _parent_program;
244 uint16_t _units_per_em;
245
246 };
247
248
249 enum Type1Defs {
250 t1Warmup_ee = 4,
251 t1R_ee = 55665,
252 t1R_cs = 4330,
253 t1C1 = 52845,
254 t1C2 = 22719
255 };
256
257
Type1Charstring(const String & s)258 inline Type1Charstring::Type1Charstring(const String &s)
259 : Charstring(), _s(s), _key(-1)
260 {
261 }
262
assign(const String & s)263 inline void Type1Charstring::assign(const String &s)
264 {
265 _s = s;
266 _key = -1;
267 }
268
data() const269 inline const uint8_t *Type1Charstring::data() const
270 {
271 if (_key >= 0)
272 decrypt();
273 return reinterpret_cast<const uint8_t *>(_s.data());
274 }
275
data_string() const276 inline const String &Type1Charstring::data_string() const
277 {
278 if (_key >= 0)
279 decrypt();
280 return _s;
281 }
282
substring(int pos,int len) const283 inline String Type1Charstring::substring(int pos, int len) const
284 {
285 if (_key >= 0)
286 decrypt();
287 return _s.substring(pos, len);
288 }
289
operator ==(const Type1Charstring & a,const Type1Charstring & b)290 inline bool operator==(const Type1Charstring &a, const Type1Charstring &b)
291 {
292 return a.data_string() == b.data_string();
293 }
294
295
Type2Charstring(const String & s)296 inline Type2Charstring::Type2Charstring(const String &s)
297 : _s(s)
298 {
299 }
300
data() const301 inline const uint8_t *Type2Charstring::data() const
302 {
303 return reinterpret_cast<const uint8_t *>(_s.data());
304 }
305
306
nxsubrs(bool g) const307 inline int CharstringProgram::nxsubrs(bool g) const
308 {
309 return (g ? ngsubrs() : nsubrs());
310 }
311
xsubr(bool g,int i) const312 inline Charstring *CharstringProgram::xsubr(bool g, int i) const
313 {
314 return (g ? gsubr(i) : subr(i));
315 }
316
xsubr_bias(bool g) const317 inline int CharstringProgram::xsubr_bias(bool g) const
318 {
319 return (g ? gsubr_bias() : subr_bias());
320 }
321
program(int gi) const322 inline const CharstringProgram *CharstringProgram::program(int gi) const
323 {
324 return (_parent_program ? child_program(gi) : this);
325 }
326
glyph_context(int gi) const327 inline CharstringContext CharstringProgram::glyph_context(int gi) const
328 {
329 if (!_parent_program)
330 return CharstringContext(this, glyph(gi));
331 else if (const CharstringProgram *p = child_program(gi))
332 return CharstringContext(p, p->glyph(gi));
333 else
334 return CharstringContext(0, 0);
335 }
336
glyph_context(PermString gn) const337 inline CharstringContext CharstringProgram::glyph_context(PermString gn) const
338 {
339 return CharstringContext(this, glyph(gn));
340 }
341
342 }
343 #endif
344