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