1 #ifndef CSCHECK_HH
2 #define CSCHECK_HH
3 #include <efont/t1interp.hh>
4 #include <lcdf/point.hh>
5 #include <lcdf/vector.hh>
6 #include <lcdf/error.hh>
7 #include <lcdf/straccum.hh>
8 #include <ctype.h>
9 
10 template <typename T>
11 class CharstringCheckerErrorHandler : public ErrorVeneer { public:
12 
CharstringCheckerErrorHandler(ErrorHandler * errh,T * checker)13     CharstringCheckerErrorHandler(ErrorHandler *errh, T *checker)
14 	: ErrorVeneer(errh), _checker(checker) {
15     }
16 
17     String decorate(const String &str);
18 
19   private:
20 
21     T *_checker;
22 
23 };
24 
25 class CharstringChecker : public Efont::CharstringInterp { public:
26 
27     CharstringChecker();
28     CharstringChecker(const Vector<double> &weight_vec);
29 
30     bool error(int, int);
31     bool callothersubr();
32     bool type1_command(int);
33 
34     bool check(const Efont::CharstringContext &, ErrorHandler *);
35 
ncommand() const36     int ncommand() const {
37 	return _ncommand;
38     }
subrno() const39     int subrno() const {
40 	return _subrno;
41     }
42 
43   private:
44 
45     ErrorHandler *_errh;
46     int _ncommand;
47     int _subrno;
48 
49     Point _cp;
50 
51     bool _started;
52     bool _flex;
53     bool _cp_exists;
54 
55     bool _hstem;
56     bool _hstem3;
57     bool _vstem;
58     bool _vstem3;
59 
60     bool _just_flexed;
61 
62     Vector<double> _h_hstem;
63     Vector<double> _h_vstem;
64 
65     Vector<double> _h_hstem3;
66     Vector<double> _h_vstem3;
67 
68     void stem(double, double, const char *);
69     void check_stem3(const char *);
70 
71     void moveto(double, double, bool cp_exists = true);
72     void rmoveto(double, double);
73     void rlineto(double, double);
74     void rrcurveto(double, double, double, double, double, double);
75 
76 };
77 
78 class CharstringSubrChecker : public Efont::CharstringInterp { public:
79 
80     CharstringSubrChecker();
81     CharstringSubrChecker(const Vector<double> &weight_vec);
82 
83     bool error(int, int);
84     bool type1_command(int);
85 
86     bool check(const Efont::CharstringContext &, ErrorHandler *);
87 
ncommand() const88     int ncommand() const {
89 	return -1;
90     }
subrno() const91     int subrno() const {
92 	return -1;
93     }
94 
95   private:
96 
97     ErrorHandler *_errh;
98 
99     bool _returned;
100 
101 };
102 
103 
104 template <typename T> String
decorate(const String & str)105 CharstringCheckerErrorHandler<T>::decorate(const String &str)
106 {
107     StringAccum sa;
108     const char *s = skip_anno(str.begin(), str.end());
109     while (s < str.end() && isspace((unsigned char) *s))
110 	++s;
111     sa.append(str.begin(), s);
112     if (_checker->subrno() >= 0)
113 	sa << "called from ";
114     if (_checker->ncommand() >= 0)
115 	sa << "command " << (_checker->ncommand() - 1) << ':';
116     if (sa)
117 	sa << ' ';
118     if (s + 11 < str.end() && memcmp(s, "charstring ", 11) == 0) {
119 	bool quote_parity = 0;
120 	const char *last = s + 11;
121 	for (const char *x = last; x != str.end(); ++x)
122 	    if (*x == '\'') {
123 		sa.append(last, x);
124 		sa << format(quote_parity ? "%>" : "%<");
125 		quote_parity = !quote_parity;
126 		last = x + 1;
127 	    }
128 	sa.append(last, str.end());
129     } else
130 	sa.append(s, str.end());
131     return ErrorVeneer::decorate(sa.take_string());
132 }
133 
134 #endif
135