Line data Source code
1 : /* Copyright (C) 2005-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * dercved from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "fontforgeui.h"
28 : #include <math.h>
29 : #include <gkeysym.h>
30 : #include <ustring.h>
31 : #include <stdarg.h>
32 :
33 : extern GBox _ggadget_Default_Box;
34 : #define MAIN_FOREGROUND (_ggadget_Default_Box.main_foreground)
35 :
36 : #ifdef FREETYPE_HAS_DEBUGGER
37 :
38 : #include <ft2build.h>
39 : #include FT_FREETYPE_H
40 :
41 : #include <internal/internal.h>
42 : #include "ttinterp.h"
43 :
44 : #define PPEMX(exc) ((exc)->size->root.metrics.x_ppem)
45 : #define PPEMY(exc) ((exc)->size->root.metrics.y_ppem)
46 :
47 : struct scr {
48 : int y, fh;
49 : int lines;
50 : GWindow pixmap;
51 : };
52 :
53 : static int ttround(int val, TT_ExecContext exc) {
54 : if ( val<0 )
55 : return( -ttround(-val,exc));
56 :
57 : switch ( exc->GS.round_state ) {
58 : case TT_Round_To_Grid:
59 : val = 64*((val+32)/64);
60 : break;
61 : case TT_Round_Down_To_Grid:
62 : val = 64*(val/64);
63 : break;
64 : case TT_Round_Up_To_Grid:
65 : val = 64*((val+63)/64);
66 : break;
67 : case TT_Round_To_Half_Grid:
68 : val = 64*(val/64)+32;
69 : break;
70 : case TT_Round_Super:
71 : val = (val - exc->phase + exc->threshold) & -exc->period;
72 : val += exc->phase;
73 : break;
74 : case TT_Round_Super_45:
75 : val = ((val - exc->phase + exc->threshold) / exc->period)*exc->period;
76 : val += exc->phase;
77 : break;
78 : }
79 : return(val);
80 : }
81 :
82 : static void scrprintf(struct scr *scr, char *format, ... ) {
83 : va_list ap;
84 : char buffer[100];
85 :
86 : va_start(ap,format);
87 : vsnprintf(buffer,sizeof(buffer),format,ap);
88 : GDrawDrawText8(scr->pixmap,3,scr->y,buffer,-1,MAIN_FOREGROUND);
89 : scr->y += scr->fh;
90 : ++scr->lines;
91 : va_end(ap);
92 : }
93 :
94 : static void scrrounding(struct scr *scr, TT_ExecContext exc ) {
95 : scrprintf(scr, "RndState: %s",
96 : exc->GS.round_state==TT_Round_To_Half_Grid? "To Half Grid" :
97 : exc->GS.round_state==TT_Round_To_Grid? "To Grid" :
98 : exc->GS.round_state==TT_Round_To_Double_Grid? "To Double Grid" :
99 : exc->GS.round_state==TT_Round_Down_To_Grid? "Down To Grid" :
100 : exc->GS.round_state==TT_Round_Up_To_Grid? "Up To Grid" :
101 : exc->GS.round_state==TT_Round_Off? "Off" :
102 : exc->GS.round_state==TT_Round_Super? "Super" :
103 : exc->GS.round_state==TT_Round_Super_45? "Super45" :
104 : "Unknown" );
105 : }
106 :
107 : static void scrfree(struct scr *scr, TT_ExecContext exc ) {
108 : scrprintf(scr, "freeVec: %g,%g", (((int)exc->GS.freeVector.x<<16)>>(16+14)) + ((exc->GS.freeVector.x&0x3fff)/16384.0),
109 : (((int)exc->GS.freeVector.y<<16)>>(16+14)) + ((exc->GS.freeVector.y&0x3fff)/16384.0) );
110 : }
111 :
112 : static void scrproj(struct scr *scr, TT_ExecContext exc ) {
113 : scrprintf(scr,"projVec: %g,%g", (((int)exc->GS.projVector.x<<16)>>(16+14)) + ((exc->GS.projVector.x&0x3fff)/16384.0),
114 : (((int)exc->GS.projVector.y<<16)>>(16+14)) + ((exc->GS.projVector.y&0x3fff)/16384.0) );
115 : }
116 :
117 : static int DVGlossExpose(GWindow pixmap,DebugView *dv,GEvent *event) {
118 : TT_ExecContext exc = DebuggerGetEContext(dv->dc);
119 : CharView *cv = dv->cv;
120 : long val1, val2, ret, i, cnt, off, a1, a2, b1, b2;
121 : int operator;
122 : BasePoint freedom;
123 : struct scr scr;
124 : int base;
125 :
126 : GDrawFillRect(pixmap,&event->u.expose.rect,GDrawGetDefaultBackground(screen_display));
127 : GDrawSetFont(pixmap,dv->ii.gfont);
128 : scr.pixmap = pixmap;
129 : scr.y = 3+dv->ii.as - dv->gloss_offtop*dv->ii.fh;
130 : scr.lines = 0;
131 : scr.fh = dv->ii.fh;
132 :
133 : if ( exc==NULL ) {
134 : scrprintf(&scr,"<not running>");
135 : return(1);
136 : }
137 : if ( exc->IP>=exc->codeSize || exc->code==NULL ) {
138 : scrprintf(&scr,"<at end>");
139 : return(1);
140 : }
141 :
142 : operator = ((uint8 *) exc->code)[exc->IP];
143 : if ( operator>=0xc0 && operator <= 0xdf ) {
144 : scrprintf(&scr," MDRP: Move Direct Relative Point");
145 : if ( operator&0x10 )
146 : scrprintf(&scr,(operator&0x10)?" Set rp0 to point":" don't set rp0 to point" );
147 : scrprintf(&scr,(operator&8)?" Keep distance>=min dist":" don't keep distance>=min dist");
148 : scrprintf(&scr,(operator&4)?" Round distance":" don't round distance");
149 : scrprintf(&scr,(operator&3)==0?" Grey":(operator&3)==1?" Black":(operator&3)==2?" White":" Undefined Rounding");
150 : scrprintf(&scr,"Move point so cur distance to rp0 is");
151 : scrprintf(&scr," the same as the original distance between");
152 : val1 = exc->stack[exc->top-1];
153 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
154 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
155 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
156 : val2 = exc->GS.rp0;
157 : scrprintf(&scr,"Reference Point rp0: %d (%.2f,%.2f)", val2,
158 : exc->zp0.cur[val2].x/64.0,exc->zp0.cur[val2].y/64.0 );
159 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
160 : scrprintf(&scr,"Sets rp1: %d (rp0)", val2);
161 : scrprintf(&scr,"Sets rp2: %d (point)", val1);
162 : scrprintf(&scr, "MinDist: %.2f", exc->GS.minimum_distance/64.0 );
163 : scrprintf(&scr, "SingWidVal: %.2f", exc->GS.single_width_value/64.0 );
164 : scrprintf(&scr, "SingWidCut: %.2f", exc->GS.single_width_cutin/64.0 );
165 : scrrounding(&scr,exc);
166 : scrfree(&scr,exc);
167 : scrproj(&scr,exc);
168 : } else if ( operator>=0xe0 && operator <= 0xff ) {
169 : scrprintf(&scr," MIRP: Move Indirect Relative Point");
170 : if ( operator&0x10 )
171 : scrprintf(&scr,(operator&0x10)?" Set rp0 to point":" don't set rp0 to point" );
172 : scrprintf(&scr,(operator&8)?" Keep distance>=min dist":" don't keep distance>=min dist");
173 : scrprintf(&scr,(operator&4)?" Round distance/use cvt cutin":" don't round distance nor use cvt cutin");
174 : scrprintf(&scr,(operator&3)==0?" Grey":(operator&3)==1?" Black":(operator&3)==2?" White":" Undefined Rounding");
175 : scrprintf(&scr,"Move point along freedom vector so distance");
176 : scrprintf(&scr," measured along projection to rp0 is the");
177 : scrprintf(&scr," value in the cvt table");
178 : val2 = exc->stack[exc->top-1];
179 : val1 = exc->stack[exc->top-2];
180 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
181 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
182 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
183 : scrprintf(&scr,"Pop: %d (cvt %.2f)", val2, exc->cvt[val2]/64.0 );
184 : val2 = exc->GS.rp0;
185 : scrprintf(&scr,"Reference Point rp0: %d (%.2f,%.2f)", val2,
186 : exc->zp0.cur[val2].x/64.0,exc->zp0.cur[val2].y/64.0 );
187 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
188 : scrprintf(&scr,"Sets rp1: %d (rp0)", val2);
189 : scrprintf(&scr,"Sets rp2: %d (point)", val1);
190 : scrprintf(&scr, "MinDist: %.2f", exc->GS.minimum_distance/64.0 );
191 : scrprintf(&scr, "CvtCutin: %.2f", exc->GS.control_value_cutin/64.0 );
192 : scrprintf(&scr, "SingWidVal: %.2f", exc->GS.single_width_value/64.0 );
193 : scrprintf(&scr, "SingWidCut: %.2f", exc->GS.single_width_cutin/64.0 );
194 : scrprintf(&scr, "AutoFlip: %s", exc->GS.auto_flip?"True": "False" );
195 : scrrounding(&scr,exc);
196 : scrfree(&scr,exc);
197 : scrproj(&scr,exc);
198 : } else if ( operator>=0xb0 && operator <= 0xb7 ) {
199 : scrprintf(&scr," Pushes %d byte%s", operator+1-0xb0, operator==0xb0?"":"s" );
200 : } else if ( operator>=0xb8 && operator <= 0xbf ) {
201 : scrprintf(&scr," Pushes %d word%s", operator+1-0xb8, operator==0xb8?"":"s" );
202 : } else switch ( operator ) {
203 : case 0x0:
204 : scrprintf(&scr," Set Freedom/Projection vector to y axis");
205 : break;
206 : case 0x1:
207 : scrprintf(&scr," Set Freedom/Projection vector to x axis");
208 : break;
209 : case 0x2:
210 : scrprintf(&scr," Set Projection vector to y axis");
211 : break;
212 : case 0x3:
213 : scrprintf(&scr," Set Projection vector to x axis");
214 : break;
215 : case 0x4:
216 : scrprintf(&scr," Set Freedom vector to y axis");
217 : break;
218 : case 0x5:
219 : scrprintf(&scr," Set Freedom vector to x axis");
220 : break;
221 : case 0xb: case 0xa:
222 : scrprintf(&scr," Set %s vector from stack", operator==0xb?"Freedom":"Projection");
223 : val1 = exc->stack[exc->top-2];
224 : val2 = exc->stack[exc->top-1];
225 : scrprintf(&scr,"Pops: %.4f (x-coord)", val1/16384.0 );
226 : scrprintf(&scr,"Pops: %.4f (y-coord)", val2/16384.0 );
227 : scrprintf(&scr,"Sets: %s Vector", operator==0xb?"Freedom":"Projection" );
228 : break;
229 : case 0xe:
230 : scrprintf(&scr," Set Freedom vector to Projection vector");
231 : scrprintf(&scr,"projVec: %g,%g", (((int)exc->GS.projVector.x<<16)>>(16+14)) + ((exc->GS.projVector.x&0x3fff)/16384.0),
232 : (((int)exc->GS.projVector.y<<16)>>(16+14)) + ((exc->GS.projVector.y&0x3fff)/16384.0) );
233 : scrprintf(&scr,"Sets: Freedom Vector" );
234 : break;
235 : case 0xc: case 0xd:
236 : scrprintf(&scr,operator==0xc?" Get Projection Vector":" Get Freedom Vector");
237 : scrprintf(&scr,operator==0xc?"Pushes: Projection Vector":"Pushes: Freedom Vector");
238 : if ( operator==0xd )
239 : scrfree(&scr,exc);
240 : else
241 : scrproj(&scr,exc);
242 : break;
243 : case 0xf:
244 : scrprintf(&scr," Moves point to intersection of two lines");
245 : val1 = exc->stack[exc->top-5];
246 : a1 = exc->stack[exc->top-4];
247 : a2 = exc->stack[exc->top-3];
248 : b1 = exc->stack[exc->top-2];
249 : b2 = exc->stack[exc->top-1];
250 :
251 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
252 : exc->zp2.cur[val1].x/64.0,exc->zp2.cur[val1].y/64.0 );
253 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
254 :
255 : scrprintf(&scr,"Pops: %d (line1.s (%.2f,%.2f))", a1,
256 : exc->zp0.cur[a1].x/64.0,exc->zp0.cur[a1].y/64.0 );
257 : scrprintf(&scr,"Pops: %d (line1.e (%.2f,%.2f))", a2,
258 : exc->zp0.cur[a2].x/64.0,exc->zp0.cur[a2].y/64.0 );
259 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
260 :
261 : scrprintf(&scr,"Pops: %d (line2.s (%.2f,%.2f))", b1,
262 : exc->zp1.cur[b1].x/64.0,exc->zp1.cur[b1].y/64.0 );
263 : scrprintf(&scr,"Pops: %d (line2.e (%.2f,%.2f))", b2,
264 : exc->zp1.cur[b2].x/64.0,exc->zp1.cur[b2].y/64.0 );
265 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
266 :
267 : scrprintf(&scr,"(ignores freedom vector)");
268 : break;
269 : case 0x10:
270 : scrprintf(&scr," Set Reference Point 0");
271 : val1 = exc->stack[exc->top-1];
272 : scrprintf(&scr,"Pops: %d (point = new rp0)", val1 );
273 : break;
274 : case 0x11:
275 : scrprintf(&scr," Set Reference Point 1");
276 : val1 = exc->stack[exc->top-1];
277 : scrprintf(&scr,"Pops: %d (point = new rp1)", val1 );
278 : break;
279 : case 0x12:
280 : scrprintf(&scr," Set Reference Point 2");
281 : val1 = exc->stack[exc->top-1];
282 : scrprintf(&scr,"Pops: %d (point = new rp2)", val1 );
283 : break;
284 : case 0x13:
285 : scrprintf(&scr," Set Zone Pointer 0");
286 : val1 = exc->stack[exc->top-1];
287 : scrprintf(&scr,"Pops: %d (new zp0 %s)", val1, val1?"Normal":"Twilight" );
288 : break;
289 : case 0x14:
290 : scrprintf(&scr," Set Zone Pointer 1");
291 : val1 = exc->stack[exc->top-1];
292 : scrprintf(&scr,"Pops: %d (new zp1 %s)", val1, val1?"Normal":"Twilight" );
293 : break;
294 : case 0x15:
295 : scrprintf(&scr," Set Zone Pointer 2");
296 : val1 = exc->stack[exc->top-1];
297 : scrprintf(&scr,"Pops: %d (new zp2 %s)", val1, val1?"Normal":"Twilight" );
298 : break;
299 : case 0x16:
300 : scrprintf(&scr," Set Zone Pointers");
301 : val1 = exc->stack[exc->top-1];
302 : scrprintf(&scr,"Pops: %d (new zp0,zp1,zp2 %s)", val1, val1?"Normal":"Twilight" );
303 : break;
304 : case 0x17:
305 : scrprintf(&scr," Set Loop variable");
306 : val1 = exc->stack[exc->top-1];
307 : scrprintf(&scr,"Pops: %d (new loop count)", val1 );
308 : break;
309 : case 0x1A:
310 : scrprintf(&scr," Set Minimum Distance");
311 : val1 = exc->stack[exc->top-1];
312 : scrprintf(&scr,"Pops: %d (new minimum distance)", val1/64.0 );
313 : break;
314 : case 0x1B: case 0x2D: case 0x59:
315 : switch( operator ) {
316 : case 0x1B:
317 : scrprintf(&scr," Else");
318 : break;
319 : case 0x2D:
320 : scrprintf(&scr," End Function Definition (return)");
321 : break;
322 : case 0x59:
323 : scrprintf(&scr," End If");
324 : break;
325 : }
326 : break;
327 : case 0x1C:
328 : scrprintf(&scr," Jump Relative (to here)");
329 : val1 = exc->stack[exc->top-1];
330 : scrprintf(&scr,"Pops: %d (byte offset)", val1 );
331 : break;
332 : case 0x1D:
333 : scrprintf(&scr," Set Control Value Table Cut-In");
334 : val1 = exc->stack[exc->top-1];
335 : scrprintf(&scr,"Pops: %.2f (new cvt cut-in value)", val1/64.0 );
336 : break;
337 : case 0x1E:
338 : scrprintf(&scr," Set Single Width Cut-In");
339 : val1 = exc->stack[exc->top-1];
340 : scrprintf(&scr,"Pops: %.2f (new single width cut-in value)", val1/64.0 );
341 : break;
342 : case 0x1F:
343 : scrprintf(&scr," Set Single Width");
344 : val1 = exc->stack[exc->top-1];
345 : scrprintf(&scr,"Pops: %.2f (new single width value)", val1/64.0 );
346 : break;
347 : case 0x20:
348 : scrprintf(&scr," Duplicate TOS");
349 : scrprintf(&scr,"Pushes: %d", exc->stack[exc->top-1] );
350 : break;
351 : case 0x21:
352 : scrprintf(&scr," Pop TOS");
353 : scrprintf(&scr,"Pops: %d", exc->stack[exc->top-1] );
354 : break;
355 : case 0x22:
356 : scrprintf(&scr," Clear Stack");
357 : scrprintf(&scr,"Pops everything" );
358 : break;
359 : case 0x23:
360 : scrprintf(&scr," Swap top of stack");
361 : scrprintf(&scr,"Pops: top two elements" );
362 : scrprintf(&scr,"Pushs: top two elements in opposite order" );
363 : break;
364 : case 0x24:
365 : scrprintf(&scr," Depth of Stack");
366 : scrprintf(&scr,"Pushes: %d", exc->top );
367 : break;
368 : case 0x25: case 0x26:
369 : val1 = exc->stack[exc->top-1];
370 : scrprintf(&scr,operator==0x25?" Copy Indexed element to TOS":" Move Indexed element to TOS");
371 : scrprintf(&scr,"Pops: %d", val1 );
372 : if ( val1<exc->top ) {
373 : val2 = exc->stack[exc->top-1-val1];
374 : scrprintf(&scr,"Pushes: %.2f (%d)", val2/64.0, val2 );
375 : if ( operator==0x26 )
376 : scrprintf(&scr,"(and removes it from further down the stack)" );
377 : } else
378 : scrprintf(&scr,"*** Stack underflow ***" );
379 : break;
380 : case 0x27:
381 : scrprintf(&scr," Align Points");
382 : val2 = exc->stack[exc->top-1];
383 : val1 = exc->stack[exc->top-2];
384 : scrprintf(&scr,"Pop1: %d (point (%.2f,%.2f))", val1,
385 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
386 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
387 : scrprintf(&scr,"Pop2: %d (point (%.2f,%.2f))", val2,
388 : exc->zp0.cur[val2].x/64.0,exc->zp0.cur[val2].y/64.0 );
389 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
390 : scrfree(&scr,exc);
391 : scrproj(&scr,exc);
392 : break;
393 : case 0x28:
394 : scrprintf(&scr," Untouch Point");
395 : val1 = exc->stack[exc->top-1];
396 : scrprintf(&scr,"Pop1: %d (point (%.2f,%.2f))", val1,
397 : exc->zp0.cur[val1].x/64.0,exc->zp0.cur[val1].y/64.0 );
398 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
399 : scrfree(&scr,exc);
400 : break;
401 : case 0x2A:
402 : case 0x2B:
403 : case 0x2C:
404 : switch ( operator ) {
405 : case 0x2A:
406 : scrprintf(&scr," Loop Call Function");
407 : break;
408 : case 0x2B:
409 : scrprintf(&scr," Call Function");
410 : break;
411 : case 0x2C:
412 : scrprintf(&scr," Function Definition");
413 : break;
414 : }
415 : val1 = exc->stack[exc->top-1];
416 : scrprintf(&scr,"Pops: %d (function number)", val1 );
417 : if ( operator==0x2a ) {
418 : val2 = exc->stack[exc->top-2];
419 : scrprintf(&scr,"Pops: %d (count)", val2 );
420 : }
421 : break;
422 : case 0x2E: case 0x2F:
423 : scrprintf(&scr, operator==0x2E?" MDAP (touch point)":" MDAP (round & touch point)");
424 : val1 = exc->stack[exc->top-1];
425 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
426 : exc->zp0.cur[val1].x/64.0,exc->zp0.cur[val1].y/64.0 );
427 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
428 : scrprintf(&scr,"Sets: rp0,rp1 to %d", val1 );
429 : if ( operator==0x2F )
430 : scrrounding(&scr,exc);
431 : scrfree(&scr,exc);
432 : scrproj(&scr,exc);
433 : break;
434 : case 0x30: case 0x31:
435 : switch ( operator ) {
436 : case 0x30:
437 : scrprintf(&scr," Interpolate Untouched Points in y");
438 : break;
439 : case 0x31:
440 : scrprintf(&scr," Interpolate Untouched Points in x");
441 : break;
442 : }
443 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
444 : break;
445 : case 0x32: case 0x33:
446 : scrprintf(&scr," Shift point by amount ref point shifted");
447 : if ( operator==0x33 ) {
448 : scrprintf(&scr, "Reference point in rp1: %d (point (%.2f,%.2f))", exc->GS.rp2,
449 : exc->zp0.cur[exc->GS.rp1].x/64.0,exc->zp0.cur[exc->GS.rp1].y/64.0 );
450 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
451 : } else {
452 : scrprintf(&scr, "Reference point in rp2: %d (point (%.2f,%.2f))", exc->GS.rp2,
453 : exc->zp1.cur[exc->GS.rp2].x/64.0,exc->zp1.cur[exc->GS.rp2].y/64.0 );
454 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
455 : }
456 : scrprintf(&scr, "loop: %ld", exc->GS.loop );
457 : for ( val1=1; val1<=exc->GS.loop && val1<exc->top; ++val1 ) {
458 : val2 = exc->stack[exc->top-val1];
459 : scrprintf(&scr,"Pop%d: %d (point (%.2f,%.2f))", val1, val2,
460 : exc->zp2.cur[val2].x/64.0,exc->zp2.cur[val2].y/64.0 );
461 : }
462 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
463 : scrfree(&scr,exc);
464 : scrproj(&scr,exc);
465 : break;
466 : case 0x34: case 0x35:
467 : scrprintf(&scr," Shift contour by amount ref point shifted");
468 : if ( operator==0x35 ) {
469 : scrprintf(&scr, "Reference point in rp1: %d (point (%.2f,%.2f))", exc->GS.rp2,
470 : exc->zp0.cur[exc->GS.rp1].x/64.0,exc->zp0.cur[exc->GS.rp1].y/64.0 );
471 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
472 : } else {
473 : scrprintf(&scr, "Reference point in rp2: %d (point (%.2f,%.2f))", exc->GS.rp2,
474 : exc->zp1.cur[exc->GS.rp2].x/64.0,exc->zp1.cur[exc->GS.rp2].y/64.0 );
475 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
476 : }
477 : scrprintf(&scr, "Pops: %d (contour index)", exc->stack[exc->top-1]);
478 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
479 : scrfree(&scr,exc);
480 : scrproj(&scr,exc);
481 : break;
482 : case 0x36: case 0x37:
483 : scrprintf(&scr," Shift zone by amount ref point shifted");
484 : if ( operator==0x37 ) {
485 : scrprintf(&scr, "Reference point in rp1: %d (point (%.2f,%.2f))", exc->GS.rp2,
486 : exc->zp0.cur[exc->GS.rp1].x/64.0,exc->zp0.cur[exc->GS.rp1].y/64.0 );
487 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
488 : } else {
489 : scrprintf(&scr, "Reference point in rp2: %d (point (%.2f,%.2f))", exc->GS.rp2,
490 : exc->zp1.cur[exc->GS.rp2].x/64.0,exc->zp1.cur[exc->GS.rp2].y/64.0 );
491 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
492 : }
493 : scrprintf(&scr, "Pops: %d (%s zone)", exc->stack[exc->top-1],
494 : exc->stack[exc->top-1]?"Normal":"Twilight" );
495 : scrfree(&scr,exc);
496 : scrproj(&scr,exc);
497 : break;
498 : case 0x38:
499 : scrprintf(&scr," Shift point by pixel amount");
500 : val1 = exc->stack[exc->top-1];
501 : scrprintf(&scr, "Pops: %.2f (pixel amount)", val1/64.0 );
502 : scrprintf(&scr, "loop: %ld", exc->GS.loop );
503 : for ( val1=2; val1<=exc->GS.loop+1 && val1<exc->top; ++val1 ) {
504 : val2 = exc->stack[exc->top-val1];
505 : scrprintf(&scr,"Pop%d: %d (point (%.2f,%.2f))", val1, val2,
506 : exc->zp2.cur[val2].x/64.0,exc->zp2.cur[val2].y/64.0 );
507 : }
508 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
509 : scrfree(&scr,exc);
510 : scrproj(&scr,exc);
511 : break;
512 : case 0x39:
513 : scrprintf(&scr," Interpolated Point");
514 : scrprintf(&scr, "Reference point in rp1: %d (point (%.2f,%.2f))", exc->GS.rp1,
515 : exc->zp0.cur[exc->GS.rp1].x/64.0,exc->zp0.cur[exc->GS.rp1].y/64.0 );
516 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
517 : scrprintf(&scr, "Reference point in rp2: %d (point (%.2f,%.2f))", exc->GS.rp2,
518 : exc->zp1.cur[exc->GS.rp2].x/64.0,exc->zp1.cur[exc->GS.rp2].y/64.0 );
519 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
520 : scrprintf(&scr, "loop: %ld", exc->GS.loop );
521 : for ( val1=1; val1<=exc->GS.loop && val1<exc->top; ++val1 ) {
522 : val2 = exc->stack[exc->top-val1];
523 : scrprintf(&scr,"Pop%d: %d (point (%.2f,%.2f))", val1, val2,
524 : exc->zp2.cur[val2].x/64.0,exc->zp2.cur[val2].y/64.0 );
525 : }
526 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
527 : scrfree(&scr,exc);
528 : scrproj(&scr,exc);
529 : break;
530 : case 0x3A: case 0x3B:
531 : scrprintf(&scr," MSIRP Move Stack Indirect Relative Point");
532 : scrprintf(&scr,operator&1?" set rp0 to point":
533 : " don't set rp0");
534 : scrprintf(&scr,"moves point along freedom vector");
535 : scrprintf(&scr," until distance from rp0 along");
536 : scrprintf(&scr," projection vector is value from stack");
537 : val2 = exc->stack[exc->top-1];
538 : val1 = exc->stack[exc->top-2];
539 : scrprintf(&scr,"Pop: %d (point (%.2f,%.2f))", val1,
540 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
541 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
542 : scrprintf(&scr, "Reference point in rp0: %d (point (%.2f,%.2f))", exc->GS.rp0,
543 : exc->zp0.cur[exc->GS.rp0].x/64.0,exc->zp0.cur[exc->GS.rp0].y/64.0 );
544 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
545 : scrprintf(&scr,"Pop: %.2f (distance)", val2/64.0 );
546 : scrfree(&scr,exc);
547 : scrproj(&scr,exc);
548 : break;
549 : case 0x3C:
550 : scrprintf(&scr," Align to Reference Point");
551 : scrprintf(&scr, "Reference point in rp0: %d (point (%.2f,%.2f))", exc->GS.rp0,
552 : exc->zp0.cur[exc->GS.rp0].x/64.0,exc->zp0.cur[exc->GS.rp0].y/64.0 );
553 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
554 : scrprintf(&scr, "loop: %ld", exc->GS.loop );
555 : for ( val1=1; val1<=exc->GS.loop && val1<exc->top; ++val1 ) {
556 : val2 = exc->stack[exc->top-val1];
557 : scrprintf(&scr,"Pop%d: %d (point (%.2f,%.2f))", val1, val2,
558 : exc->zp1.cur[val2].x/64.0,exc->zp1.cur[val2].y/64.0 );
559 : }
560 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
561 : scrfree(&scr,exc);
562 : scrproj(&scr,exc);
563 : break;
564 : case 0x3E: case 0x3F:
565 : scrprintf(&scr," MIAP Move Indirect Absolute Point");
566 : scrprintf(&scr,operator&1?" round distance and look at cvt cutin":
567 : " don't round distance and look at cvt cutin");
568 : scrprintf(&scr,"moves point to cvt value along freedom vector");
569 : val2 = exc->stack[exc->top-1];
570 : val1 = exc->stack[exc->top-2];
571 : scrprintf(&scr,"Pop: %d (point (%.2f,%.2f))", val1,
572 : exc->zp0.cur[val1].x/64.0,exc->zp0.cur[val1].y/64.0 );
573 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
574 : scrprintf(&scr,"Pop: %d (cvt %.2f)", val2, exc->cvt[val2]/64.0 );
575 : scrprintf(&scr,"Sets: rp0 and rp1 to point %d", val1 );
576 : scrfree(&scr,exc);
577 : scrproj(&scr,exc);
578 : scrprintf(&scr, "CvtCutin: %.2f", exc->GS.control_value_cutin/64.0 );
579 : break;
580 : case 0x40:
581 : scrprintf(&scr," Push %d Bytes", ((uint8 *) exc->code)[exc->IP+1]);
582 : break;
583 : case 0x41:
584 : scrprintf(&scr," Push %d Words", ((uint8 *) exc->code)[exc->IP+1]);
585 : break;
586 : case 0x42:
587 : scrprintf(&scr," Write Store" );
588 : val2 = exc->stack[exc->top-1];
589 : val1 = exc->stack[exc->top-2];
590 : scrprintf(&scr,"Pops: %d (%.2f)", val2, val2/64.0 );
591 : scrprintf(&scr,"Pops: %d (store index)", val1 );
592 : break;
593 : case 0x43:
594 : scrprintf(&scr," Read Store" );
595 : val1 = exc->stack[exc->top-1];
596 : scrprintf(&scr,"Pop: %d (store index)", val1 );
597 : scrprintf(&scr,"Pushes: %d (%.2f)", exc->storage[val1], exc->storage[val1]/64.0 );
598 : break;
599 : case 0x44:
600 : scrprintf(&scr," Write CVT entry in Pixels" );
601 : val2 = exc->stack[exc->top-1];
602 : val1 = exc->stack[exc->top-2];
603 : scrprintf(&scr,"Pops: %.2f", val2/64.0 );
604 : scrprintf(&scr,"Pops: %d (cvt index)", val1 );
605 : break;
606 : case 0x45:
607 : scrprintf(&scr,"Read Control Value Table entry" );
608 : val1 = exc->stack[exc->top-1];
609 : scrprintf(&scr,"Pop: %d (cvt index)", val1 );
610 : scrprintf(&scr,"Pushes: %.2f (%d)", exc->cvt[val1]/64.0, exc->cvt[val1] );
611 : break;
612 : case 0x46: case 0x47:
613 : scrprintf(&scr,"Get %s point coord projected on projection vector",
614 : operator==0x46 ? "current" : "original" );
615 : val1 = exc->stack[exc->top-1];
616 : if ( operator==0x46 ) {
617 : scrprintf(&scr,"Pop: %d (cur point (%.2f,%.2f))", val1,
618 : exc->zp2.cur[val1].x/64.0,exc->zp2.cur[val1].y/64.0 );
619 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
620 : scrprintf(&scr, "projVec: %g,%g", (((int)exc->GS.projVector.x<<16)>>(16+14)) + ((exc->GS.projVector.x&0x3fff)/16384.0),
621 : (((int)exc->GS.projVector.y<<16)>>(16+14)) + ((exc->GS.projVector.y&0x3fff)/16384.0) );
622 : } else {
623 : scrprintf(&scr,"Pop: %d (orig point (%.2f,%.2f))", val1,
624 : exc->zp2.org[val1].x/64.0,exc->zp2.org[val1].y/64.0 );
625 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
626 : scrprintf(&scr,"dualVec: %g,%g", (((int)exc->GS.dualVector.x<<16)>>(16+14)) + ((exc->GS.dualVector.x&0x3fff)/16384.0),
627 : (((int)exc->GS.dualVector.y<<16)>>(16+14)) + ((exc->GS.dualVector.y&0x3fff)/16384.0) );
628 : }
629 : scrprintf(&scr,"Pushes: projection" );
630 : break;
631 : case 0x48:
632 : scrprintf(&scr," Sets coordinate from stack using proj & free vectors" );
633 : val2 = exc->stack[exc->top-1];
634 : val1 = exc->stack[exc->top-2];
635 : scrprintf(&scr,"Moves point along freedom vector until its" );
636 : scrprintf(&scr," projection on the projection vector is the" );
637 : scrprintf(&scr," desired amount" );
638 : scrprintf(&scr,"Pop: %d (cur point (%.2f,%.2f))", val1,
639 : exc->zp2.cur[val1].x/64.0,exc->zp2.cur[val1].y/64.0 );
640 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
641 : scrfree(&scr,exc);
642 : scrproj(&scr,exc);
643 : break;
644 : case 0x49: case 0x4A:
645 : switch ( operator ) {
646 : case 0x49:
647 : scrprintf(&scr," Measure Distance (current)");
648 : break;
649 : case 0x4A:
650 : scrprintf(&scr," Measure Distance (original)");
651 : break;
652 : }
653 :
654 : val1 = exc->stack[exc->top-1];
655 : val2 = exc->stack[exc->top-2];
656 : if ( operator==0x49 ) {
657 : scrprintf(&scr,"Pop: %d (cur point (%.2f,%.2f))", val1,
658 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
659 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
660 : scrprintf(&scr,"Pop: %d (cur point (%.2f,%.2f))", val2,
661 : exc->zp0.cur[val2].x/64.0,exc->zp0.cur[val2].y/64.0 );
662 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
663 : scrprintf(&scr, "projVec: %g,%g", (((int)exc->GS.projVector.x<<16)>>(16+14)) + ((exc->GS.projVector.x&0x3fff)/16384.0),
664 : (((int)exc->GS.projVector.y<<16)>>(16+14)) + ((exc->GS.projVector.y&0x3fff)/16384.0) );
665 : } else {
666 : scrprintf(&scr,"Pop: %d (orig point (%.2f,%.2f))", val1,
667 : exc->zp1.org[val1].x/64.0,exc->zp1.org[val1].y/64.0 );
668 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
669 : scrprintf(&scr,"Pop: %d (orig point (%.2f,%.2f))", val2,
670 : exc->zp0.org[val2].x/64.0,exc->zp0.org[val2].y/64.0 );
671 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
672 : scrprintf(&scr, "dualVec: %g,%g", (((int)exc->GS.dualVector.x<<16)>>(16+14)) + ((exc->GS.dualVector.x&0x3fff)/16384.0),
673 : (((int)exc->GS.dualVector.y<<16)>>(16+14)) + ((exc->GS.dualVector.y&0x3fff)/16384.0) );
674 : }
675 : scrprintf(&scr,"Pushes: distance" );
676 : break;
677 : case 0x4B:
678 : scrprintf(&scr," MPPEM Push Pixels Per Em");
679 : scrprintf(&scr,"Pushes: %d", PPEMY(exc)); /* Actually this depends on the projection vector. But if xppem==yppem it will make no difference */
680 : break;
681 : case 0x4C:
682 : scrprintf(&scr," Push Pointsize");
683 : scrprintf(&scr,"(one might assume this returns the pointsize, %d", cv->ft_pointsizey);
684 : scrprintf(&scr," as it is documented to do, but instead it");
685 : scrprintf(&scr," returns ppem)");
686 : scrprintf(&scr,"Pushes: %d", PPEMY(exc) );
687 : break;
688 : case 0x4D: case 0x4E:
689 : switch ( operator ) {
690 : case 0x4D:
691 : scrprintf(&scr," set auto Flip On");
692 : break;
693 : case 0x4E:
694 : scrprintf(&scr," set auto Flip Off");
695 : break;
696 : }
697 : break;
698 : case 0x4F:
699 : val1 = exc->stack[exc->top-1];
700 : scrprintf(&scr," Debug");
701 : scrprintf(&scr,"Pops: %d (debug hook)", val1 );
702 : break;
703 : case 0x58:
704 : val1 = exc->stack[exc->top-1];
705 : scrprintf(&scr," If");
706 : scrprintf(&scr,"Pops: %d (condition)", val1 );
707 : break;
708 : case 0x5e:
709 : scrprintf(&scr," Set Delta Base");
710 : val1 = exc->stack[exc->top-1];
711 : scrprintf(&scr,"Pops: %d (new delta base)", val1 );
712 : break;
713 : case 0x5f:
714 : scrprintf(&scr," Set Delta Shift");
715 : val1 = exc->stack[exc->top-1];
716 : scrprintf(&scr,"Pops: %d (new delta shift)", val1 );
717 : break;
718 : case 0x8B: case 0x8C:
719 : case 0x60: case 0x61: case 0x62: case 0x63:
720 : case 0x5A: case 0x5B:
721 : case 0x55: case 0x54: case 0x53: case 0x52: case 0x51: case 0x50:
722 : val2 = exc->stack[exc->top-1];
723 : val1 = exc->stack[exc->top-2];
724 : switch( operator ) {
725 : case 0x50:
726 : scrprintf(&scr," Less Than");
727 : ret = val1<val2;
728 : break;
729 : case 0x51:
730 : scrprintf(&scr," Less Than Or Equal");
731 : ret = val1<=val2;
732 : break;
733 : case 0x52:
734 : scrprintf(&scr," Greater Than");
735 : ret = val1>val2;
736 : break;
737 : case 0x53:
738 : scrprintf(&scr," Greater Than or Equal");
739 : ret = val1>=val2;
740 : break;
741 : case 0x54:
742 : scrprintf(&scr," Equal");
743 : ret = val1==val2;
744 : break;
745 : case 0x55:
746 : scrprintf(&scr," Not Equal");
747 : ret = val1!=val2;
748 : break;
749 : case 0x5A:
750 : scrprintf(&scr," And");
751 : ret = val1 & val2;
752 : break;
753 : case 0x5B:
754 : scrprintf(&scr," Or");
755 : ret = val1 | val2;
756 : break;
757 : case 0x60:
758 : scrprintf(&scr," Add");
759 : ret = val1 + val2;
760 : break;
761 : case 0x61:
762 : scrprintf(&scr," Sub");
763 : ret = val1 - val2;
764 : break;
765 : case 0x62:
766 : scrprintf(&scr," Divide");
767 : if ( val2!=0 )
768 : ret = val1*64/val2;
769 : else
770 : ret = 0x7fffffff;
771 : break;
772 : case 0x63:
773 : scrprintf(&scr," Multiply");
774 : ret = val1*val2/64.0;
775 : break;
776 : case 0x8B:
777 : scrprintf(&scr," Max");
778 : ret = val1>val2 ? val1 : val2;
779 : break;
780 : case 0x8C:
781 : scrprintf(&scr," Min");
782 : ret = val1<val2 ? val1 : val2;
783 : break;
784 : }
785 : scrprintf(&scr,"Pop1: %.2f (%d)", val1/64.0, val1 );
786 : scrprintf(&scr,"Pop2: %.2f (%d)", val2/64.0, val2 );
787 : scrprintf(&scr,"Pushes: %.2f (%d)", ret/64.0, ret );
788 : break;
789 : case 0x64: case 0x65: case 0x66: case 0x67:
790 : case 0x57: case 0x5C:
791 : val2 = val1 = exc->stack[exc->top-1];
792 : switch( operator ) {
793 : case 0x64:
794 : scrprintf(&scr," Absolute Value");
795 : if ( val2<0 ) val2 = -val2;
796 : break;
797 : case 0x65:
798 : scrprintf(&scr," Negate");
799 : val2 = -val1;
800 : break;
801 : case 0x66:
802 : scrprintf(&scr," Floor");
803 : val2 = 64*(val2/64);
804 : break;
805 : case 0x67:
806 : scrprintf(&scr," Ceiling");
807 : val2 = 64*((val2+63)/64);
808 : break;
809 : case 0x5C:
810 : scrprintf(&scr," Not");
811 : val2 = !val1;
812 : break;
813 : case 0x56:
814 : scrprintf(&scr," Odd (after rounding)");
815 : ret = ttround(val1,exc);
816 : if ( ret&64 ) ret = 0; else ret = 1;
817 : break;
818 : case 0x57:
819 : scrprintf(&scr," Even (after rounding)");
820 : ret = ttround(val1,exc);
821 : if ( ret&64 ) ret = 0; else ret = 1;
822 : break;
823 : }
824 : scrprintf(&scr,"Pops: %.2f (%d)", val1/64.0, val1 );
825 : scrprintf(&scr,"Pushes: %.2f (%d)", val2/64.0, val2 );
826 : break;
827 : case 0x68: case 0x69: case 0x6A: case 0x6B:
828 : scrprintf(&scr," Round & adjust for engine characteristics" );
829 : scrprintf(&scr,(operator&3)==0?" Grey":(operator&3)==1?" Black":(operator&3)==2?" White":" Undefined Rounding");
830 : val1 = exc->stack[exc->top-1];
831 : scrprintf(&scr,"Pops: %.2f", val1/64.0 );
832 : val1 = ttround(val1,exc);
833 : scrprintf(&scr,"Pushes: %.2f", val1/64.0 );
834 : break;
835 : case 0x6C: case 0x6D: case 0x6E: case 0x6F:
836 : scrprintf(&scr," Adjust for engine characteristics without rounding" );
837 : scrprintf(&scr,(operator&3)==0?" Grey":(operator&3)==1?" Black":(operator&3)==2?" White":" Undefined Rounding");
838 : val1 = exc->stack[exc->top-1];
839 : scrprintf(&scr,"Pops: %.2f", val1/64.0 );
840 : scrprintf(&scr,"Pushes: %.2f", val1/64.0 );
841 : break;
842 : case 0x5D: case 0x71: case 0x72:
843 : base = operator==0x5D?1:operator-0x6F;
844 : scrprintf(&scr," Delta Point%d", base );
845 : freedom.x = (((int)exc->GS.freeVector.x<<16)>>(16+14)) + ((exc->GS.freeVector.x&0x3fff)/16384.0);
846 : freedom.y = (((int)exc->GS.freeVector.y<<16)>>(16+14)) + ((exc->GS.freeVector.y&0x3fff)/16384.0);
847 : cnt = exc->stack[exc->top-1];
848 : scrprintf(&scr,"Pops: %d (count)", cnt );
849 : for ( i=0; i<cnt; ++i ) {
850 : if ( 2*i+3 > exc->top ) {
851 : scrprintf(&scr,"*** Stack underflow ***");
852 : break;
853 : }
854 : val1 = exc->stack[exc->top-2-2*i];
855 : val2 = exc->stack[exc->top-3-2*i];
856 : if ( (val2&0xf)<=7 )
857 : off = -8+(val2&0xf);
858 : else
859 : off = -7+(val2&0xf);
860 : off *= 64 / (1L << exc->GS.delta_shift);
861 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
862 : exc->zp0.cur[val1].x/64.0,exc->zp0.cur[val1].y/64.0 );
863 : scrprintf(&scr,"Pops: %d => at %d ppem, move (%.2f,%.2f)",
864 : val2, exc->GS.delta_base+(base-1)*16+((val2>>4)&0xf),
865 : freedom.x*off/64.0, freedom.y*off/64.0 );
866 : }
867 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
868 : scrprintf(&scr, "DeltaBase: %d", exc->GS.delta_base );
869 : scrprintf(&scr, "DeltaShift: %d", exc->GS.delta_shift );
870 : scrprintf(&scr, "freeVec: %g,%g", freedom.x, freedom.y);
871 : break;
872 : case 0x70:
873 : scrprintf(&scr," Write CVT entry in Funits" );
874 : val2 = exc->stack[exc->top-1];
875 : val1 = exc->stack[exc->top-2];
876 : scrprintf(&scr,"Pops: %d (em-units=%.2fpixels)", val2,
877 : val2*PPEMX(exc)*64.0/
878 : (cv->b.sc->parent->ascent+cv->b.sc->parent->descent));
879 : scrprintf(&scr,"Pops: %d (cvt index)", val1 );
880 : break;
881 : case 0x73: case 0x74: case 0x75:
882 : base = operator-0x72;
883 : scrprintf(&scr," Delta Point%d", base );
884 : cnt = exc->stack[exc->top-1];
885 : scrprintf(&scr,"Pops: %d (count)", cnt );
886 : for ( i=0; i<cnt; ++i ) {
887 : if ( 2*cnt+3 > exc->top ) {
888 : scrprintf(&scr,"*** Stack underflow ***");
889 : break;
890 : }
891 : val1 = exc->stack[exc->top-2-2*i];
892 : val2 = exc->stack[exc->top-3-2*i];
893 : if ( (val2&0xf)<=7 )
894 : off = -8+(val2&0xf);
895 : else
896 : off = -7+(val2&0xf);
897 : off *= 64 / (1L << exc->GS.delta_shift);
898 : scrprintf(&scr,"Pops: %d (cvt index (%d,%.2f))", val1,
899 : exc->cvt[val1],exc->cvt[val1]/64.0 );
900 : scrprintf(&scr,"Pops: %d => at %d ppem, change by %.2f",
901 : val2, exc->GS.delta_base+(base-1)*16+((val2>>4)&0xf),
902 : off/64.0 );
903 : }
904 : scrprintf(&scr, "DeltaBase: %d", exc->GS.delta_base );
905 : scrprintf(&scr, "DeltaShift: %d", exc->GS.delta_shift );
906 : break;
907 : case 0x78: case 0x79:
908 : scrprintf(&scr,operator==0x78?" Jump Relative (to here) on True":" Jump Relative (to here) on False");
909 : val1 = exc->stack[exc->top-1];
910 : val2 = exc->stack[exc->top-2];
911 : scrprintf(&scr,"Pops: %d (condition)", val1 );
912 : scrprintf(&scr,"Pops: %d (byte offset)", val2 );
913 : break;
914 : case 0x18: case 0x19:
915 : case 0x3D:
916 : case 0x76: case 0x77: case 0x7a: case 0x7c: case 0x7d:
917 : scrprintf(&scr, operator==0x7a?" set Rounding off":
918 : operator==0x7c?" set Rounding up to grid":
919 : operator==0x77?" set Rounding to Super 45":
920 : operator==0x7d?" set Rounding down to grid":
921 : operator==0x18?" set Rounding to grid":
922 : operator==0x3D?" set Rounding to double grid":
923 : operator==0x19?" set Rounding to half grid":
924 : " set Rounding to Super");
925 : scrprintf(&scr,"Sets: Rounding state");
926 : break;
927 : case 0x7e:
928 : scrprintf(&scr," Set Angle Weight (obsolete)");
929 : scrprintf(&scr,"Pops: an ignored value");
930 : break;
931 : case 0x7f:
932 : scrprintf(&scr," Adjust Angle");
933 : scrprintf(&scr,"Pops: %d (point)", exc->stack[exc->top-1]);
934 : break;
935 : case 0x80:
936 : scrprintf(&scr," Flip Points");
937 : scrprintf(&scr, "loop: %ld", exc->GS.loop );
938 : for ( val1=1; val1<=exc->GS.loop && val1<exc->top; ++val1 ) {
939 : val2 = exc->stack[exc->top-val1];
940 : scrprintf(&scr,"Pop%d: %d (point (%.2f,%.2f))", val1, val2,
941 : exc->zp0.cur[val2].x/64.0,exc->zp0.cur[val2].y/64.0 );
942 : scrprintf(&scr," was %s-curve, becomes %s-curve",
943 : exc->pts.tags[val2] & FT_CURVE_TAG_ON ? "on" : "off",
944 : exc->pts.tags[val2] & FT_CURVE_TAG_ON ? "off" : "on" );
945 : }
946 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
947 : break;
948 : case 0x81: case 0x82:
949 : val2 = exc->stack[exc->top-1];
950 : val1 = exc->stack[exc->top-2];
951 : scrprintf(&scr,operator==0x81?" Flip point range On":" Flip point range Off");
952 :
953 : for ( i=val2; i<=val2; ++i ) {
954 : scrprintf(&scr," change point %d (%.2f,%.2f)", i,
955 : exc->zp0.cur[i].x/64.0,exc->zp0.cur[i].y/64.0 );
956 : scrprintf(&scr," was %s-curve, becomes %s-curve",
957 : exc->pts.tags[val2] & FT_CURVE_TAG_ON ? "on" : "off",
958 : operator==0x82 ? "off" : "on" );
959 : }
960 : scrprintf(&scr," (in zone from zp0: %s)", exc->GS.gep0?"Normal":"Twilight" );
961 : break;
962 : case 0x85:
963 : scrprintf(&scr," SCANCTRL Set dropout control" );
964 : val1 = exc->stack[exc->top-1];
965 : scrprintf(&scr,"Pops: %d (flags)",val1 );
966 : if ( val1==0 )
967 : scrprintf(&scr,"Turn off dropout control");
968 : else {
969 : if ( val1&0x100 ) {
970 : if ( (val1&0xff)==0xff )
971 : scrprintf(&scr,"set dropout control for all ppem");
972 : else
973 : scrprintf(&scr,"set dropout control for ppem <= %d", (val1&0xff));
974 : }
975 : if ( val1&0x800 ) {
976 : if ( (val1&0xff)==0xff )
977 : scrprintf(&scr,"<I can't figure this combination out>");
978 : else
979 : scrprintf(&scr,"unset dropout control unless ppem <= %d", (val1&0xff));
980 : }
981 : if ( val1&0x200 )
982 : scrprintf(&scr,"set dropout control if glyph rotated");
983 : if ( val1&0x1000 )
984 : scrprintf(&scr,"unset dropout control unless glyph rotated");
985 : if ( val1&0x400 )
986 : scrprintf(&scr,"set dropout control if glyph stretched");
987 : if ( val1&0x2000 )
988 : scrprintf(&scr,"unset dropout control unless glyph stretched");
989 : }
990 : break;
991 : case 0x06: case 0x07:
992 : case 0x08: case 0x09:
993 : case 0x86: case 0x87:
994 : scrprintf(&scr,operator<0x8?" Sets projection vector from line":
995 : operator<0x86?" Sets freedom vector from line":
996 : " Set dual projection vector from line");
997 : scrprintf(&scr,(operator&1)?"orthogonal to line":"parallel to line");
998 : val1 = exc->stack[exc->top-2];
999 : val2 = exc->stack[exc->top-1];
1000 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val1,
1001 : exc->zp1.cur[val1].x/64.0,exc->zp1.cur[val1].y/64.0 );
1002 : scrprintf(&scr," (in zone from zp1: %s)", exc->GS.gep1?"Normal":"Twilight" );
1003 : scrprintf(&scr,"Pops: %d (point (%.2f,%.2f))", val2,
1004 : exc->zp2.cur[val2].x/64.0,exc->zp2.cur[val2].y/64.0 );
1005 : scrprintf(&scr," (in zone from zp2: %s)", exc->GS.gep2?"Normal":"Twilight" );
1006 : if ( operator>=0x86 ) {
1007 : scrprintf(&scr,"Sets: Project vector based on current positions" );
1008 : scrprintf(&scr,"Sets: Dual proj vector based on original positions" );
1009 : } else
1010 : scrprintf(&scr,"Sets: %s vector", operator<8?"Projection":"Freedom" );
1011 : break;
1012 : case 0x88:
1013 : val1 = exc->stack[exc->top-1];
1014 : scrprintf(&scr," Get Information");
1015 : scrprintf(&scr, "Pops: %d %s%s%s%s%s%s%s%s%s%s", val1,
1016 : val1&(1<<0) ? "version (result in bits 0-7) " : "",
1017 : val1&(1<<1) ? "rotated (result in bit 8)" : "",
1018 : val1&(1<<2) ? "stretched (result in bit 9)" : "",
1019 : val1&(1<<3) ? "Undocumented Apple ?variations? (result in bit 10)" : "",
1020 : val1&(1<<4) ? "Undocumented Apple ?vertical metrics? (result in bit 11)" : "",
1021 : val1&(1<<5) ? "greyscale (result in bit 12)" : "",
1022 : val1&(1<<6) ? "ClearType (result in bit 13)" : "",
1023 : val1&(1<<7) ? "CT widths compat (result in bit 14)" : "",
1024 : val1&(1<<8) ? "CT symetrical smoothing (result in bit 15)" : "",
1025 : val1&(1<<9) ? "CT processes in BGR(1) or RGB(0) (result in bit 16)" : "");
1026 : if ( val1&1 ) {
1027 : scrprintf(&scr, " Versions: 1 => Mac OS 6" );
1028 : scrprintf(&scr, " 2 => Mac OS 7" );
1029 : scrprintf(&scr, " 3 => Win 3.1" );
1030 : scrprintf(&scr, " 33=> Win rasterizer 1.5" );
1031 : scrprintf(&scr, " 34=> Win rasterizer 1.6" );
1032 : scrprintf(&scr, " 35=> Win rasterizer 1.7" );
1033 : scrprintf(&scr, " 37=> Win rasterizer 1.8" );
1034 : scrprintf(&scr, " 38=> Win rasterizer 1.9" );
1035 : }
1036 : scrprintf(&scr,"Pushes: result");
1037 : scrprintf(&scr,"FreeType returns: %s%s%s%s",
1038 : (val1&1) ? "(Win 1.7) | ": "",
1039 : (val1&2) ? exc->tt_metrics.rotated ? "(rotated) | ": "(not rotated) | " : "",
1040 : (val1&4) ? exc->tt_metrics.stretched ? "(stretched) | ": "(not stretched) | " : "",
1041 : (val1&32) ? exc->grayscale ? "(grey scale)": "(black/white)" : ""
1042 : );
1043 : break;
1044 : case 0x89:
1045 : scrprintf(&scr," Instruction Definition");
1046 : val1 = exc->stack[exc->top-1];
1047 : scrprintf(&scr,"Pops: %d (opcode)", val1 );
1048 : break;
1049 : case 0x8a:
1050 : scrprintf(&scr," Roll top three stack elements");
1051 : break;
1052 : case 0x8D:
1053 : scrprintf(&scr," SCANTYPE Set dropout control" );
1054 : val1 = exc->stack[exc->top-1];
1055 : scrprintf(&scr,"Pops: %d (mode)",val1 );
1056 : if ( val1==0 )
1057 : scrprintf(&scr,"simple dropout control scan conversion including stubs (rules 1,2,3)");
1058 : else if ( val1==1 )
1059 : scrprintf(&scr,"simple dropout control scan conversion excluding stubs (rules 1,2,4)");
1060 : else if ( val1==2 || val1==3 || val1==6 || val1==7 )
1061 : scrprintf(&scr,"fast scan conversion; dropout control turned off (rule 1,2)");
1062 : else if ( val1==4 )
1063 : scrprintf(&scr,"smart dropout control scan conversion including stubs (rule 1,2,5)");
1064 : else if ( val1==5 )
1065 : scrprintf(&scr,"smart dropout control scan conversion excluding stubs (rule 1,2,6)");
1066 : else
1067 : scrprintf(&scr,"*** Unknown mode ***");
1068 : break;
1069 : case 0x8E:
1070 : val2 = exc->stack[exc->top-1];
1071 : val1 = exc->stack[exc->top-2];
1072 : scrprintf(&scr," Instruction Control");
1073 : scrprintf(&scr,"Pops: %d (selector)", val1 );
1074 : scrprintf(&scr,"Pops: %d (value)", val1 );
1075 : if ( val1==1 )
1076 : scrprintf(&scr, " => grid fitting %s", val2 ? "inhibited" : "normal" );
1077 : else if ( val1==2 )
1078 : scrprintf(&scr, " => cvt parameters %s", val2 ? "ignored" : "normal" );
1079 : else
1080 : scrprintf(&scr, "Unknown selector");
1081 : break;
1082 : }
1083 : return( scr.lines );
1084 : }
1085 :
1086 : static void dvgloss_scroll(DebugView *dv,struct sbevent *sb) {
1087 : int newpos = dv->cvt_offtop;
1088 : GRect size;
1089 : int min, max, page;
1090 : extern int _GScrollBar_Width;
1091 :
1092 : GScrollBarGetBounds(dv->glosssb,&min,&max,&page);
1093 : GDrawGetSize(dv->gloss,&size);
1094 : switch( sb->type ) {
1095 : case et_sb_top:
1096 : newpos = 0;
1097 : break;
1098 : case et_sb_uppage:
1099 : newpos -= size.height/dv->ii.fh;
1100 : break;
1101 : case et_sb_up:
1102 : --newpos;
1103 : break;
1104 : case et_sb_down:
1105 : ++newpos;
1106 : break;
1107 : case et_sb_downpage:
1108 : newpos += size.height/dv->ii.fh;
1109 : break;
1110 : case et_sb_bottom:
1111 : newpos = max-size.height/dv->ii.fh;
1112 : break;
1113 : case et_sb_thumb:
1114 : case et_sb_thumbrelease:
1115 : newpos = sb->pos;
1116 : break;
1117 : }
1118 : if ( newpos>max-size.height/dv->ii.fh )
1119 : newpos = max-size.height/dv->ii.fh;
1120 : if ( newpos<0 ) newpos =0;
1121 : if ( newpos!=dv->gloss_offtop ) {
1122 : int diff = newpos-dv->gloss_offtop;
1123 : dv->gloss_offtop = newpos;
1124 : GScrollBarSetPos(dv->glosssb,dv->gloss_offtop);
1125 : size.x = size.y = 0;
1126 : size.width -= GDrawPointsToPixels(dv->gloss,_GScrollBar_Width);
1127 : GDrawScroll(dv->gloss,&size,0,diff*dv->ii.fh);
1128 : }
1129 : }
1130 :
1131 : static void DVGlossExposeSize(GWindow gw,DebugView *dv,GEvent *event) {
1132 : int len = DVGlossExpose(gw,dv,event);
1133 : GRect size;
1134 : int min, max, page, offtop;
1135 :
1136 : GScrollBarGetBounds(dv->glosssb,&min,&max,&page);
1137 : GGadgetGetSize(dv->glosssb,&size);
1138 : size.height /= dv->ii.fh;
1139 :
1140 : if ( len!=max || page!=size.height ) {
1141 : GScrollBarSetBounds(dv->glosssb,0,len,size.height);
1142 : offtop = dv->gloss_offtop;
1143 : if ( offtop+size.height > len )
1144 : offtop = len-size.height;
1145 : if ( offtop < 0 )
1146 : offtop = 0;
1147 : if ( offtop!=dv->gloss_offtop ) {
1148 : dv->gloss_offtop = offtop;
1149 : GScrollBarSetPos(dv->glosssb,dv->gloss_offtop);
1150 : DVGlossExpose(gw,dv,event);
1151 : }
1152 : }
1153 : }
1154 :
1155 : static int dvgloss_e_h(GWindow gw, GEvent *event) {
1156 : DebugView *dv = (DebugView *) GDrawGetUserData(gw);
1157 : GRect r,g;
1158 : extern int debug_wins;
1159 :
1160 : if ( dv==NULL )
1161 : return( true );
1162 :
1163 : switch ( event->type ) {
1164 : case et_expose:
1165 : DVGlossExposeSize(gw,dv,event);
1166 : break;
1167 : case et_char:
1168 : return( DVChar(dv,event));
1169 : break;
1170 : case et_controlevent:
1171 : switch ( event->u.control.subtype ) {
1172 : case et_scrollbarchange:
1173 : dvgloss_scroll(dv,&event->u.control.u.sb);
1174 : break;
1175 : }
1176 : break;
1177 : case et_resize:
1178 : GDrawGetSize(gw,&r);
1179 : GGadgetGetSize(dv->glosssb,&g);
1180 : GGadgetMove(dv->glosssb,r.width-g.width,0);
1181 : GGadgetResize(dv->glosssb,g.width,r.height);
1182 : GDrawRequestExpose(dv->gloss,NULL,false);
1183 : break;
1184 : case et_close:
1185 : GDrawDestroyWindow(dv->gloss);
1186 : debug_wins &= ~dw_gloss;
1187 : break;
1188 : case et_destroy:
1189 : dv->gloss = NULL;
1190 : break;
1191 : case et_mouseup: case et_mousedown:
1192 : case et_mousemove:
1193 : GGadgetEndPopup();
1194 : break;
1195 : }
1196 : return( true );
1197 : }
1198 :
1199 : void DVCreateGloss(DebugView *dv) {
1200 : GWindowAttrs wattrs;
1201 : GRect pos;
1202 : GGadgetData gd;
1203 : extern int _GScrollBar_Width;
1204 :
1205 : memset(&wattrs,0,sizeof(wattrs));
1206 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle;
1207 : wattrs.event_masks = -1;
1208 : wattrs.cursor = ct_mypointer;
1209 : wattrs.utf8_window_title = _("Instruction Gloss (TrueType)");
1210 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,230)); pos.height = 169;
1211 : pos.x = CVXPos(dv,143,pos.width); pos.y = 302;
1212 : dv->gloss = GDrawCreateTopWindow(NULL,&pos,dvgloss_e_h,dv,&wattrs);
1213 :
1214 : memset(&gd,0,sizeof(gd));
1215 :
1216 : gd.pos.y = 0; gd.pos.height = pos.height;
1217 : gd.pos.width = GDrawPointsToPixels(dv->gloss,_GScrollBar_Width);
1218 : gd.pos.x = pos.width-gd.pos.width;
1219 : gd.flags = gg_visible|gg_enabled|gg_pos_in_pixels|gg_sb_vert;
1220 : dv->glosssb = GScrollBarCreate(dv->gloss,&gd,dv);
1221 :
1222 : GDrawSetVisible(dv->gloss,true);
1223 : }
1224 :
1225 : /* ************************************************************************** */
1226 : /* Variant of the gloss window: Mark the points to show what the next */
1227 : /* instruction will do to them. (Change (usually move) them, or use them */
1228 : /* or ignore them */
1229 : /* ************************************************************************** */
1230 :
1231 : static SplinePoint *FindPoint(SplineSet *ss,int ptnum) {
1232 : SplineSet *spl;
1233 : SplinePoint *sp;
1234 :
1235 : for ( spl=ss; spl!=NULL ; spl=spl->next ) {
1236 : for ( sp = spl->first; ; ) {
1237 : if ( sp->ttfindex==ptnum || sp->nextcpindex==ptnum )
1238 : return( sp );
1239 : if ( sp->next==NULL )
1240 : break;
1241 : sp = sp->next->to;
1242 : if ( sp==spl->first )
1243 : break;
1244 : }
1245 : }
1246 : return( NULL );
1247 : }
1248 :
1249 : static void SetBasisPoint(SplineSet *ss, int ptnum) {
1250 : SplinePoint *sp = FindPoint(ss,ptnum);
1251 : if ( sp==NULL )
1252 : return;
1253 : /* A roundx point or flexx nextcp means this is the reference */
1254 : /* point, etc. */
1255 : if ( sp->ttfindex==ptnum )
1256 : sp->roundx = true;
1257 : else
1258 : sp->flexx = true;
1259 : }
1260 :
1261 : static void SetChangingPoint(SplineSet *ss, int ptnum) {
1262 : SplinePoint *sp = FindPoint(ss,ptnum);
1263 : if ( sp==NULL )
1264 : return;
1265 : /* I reuse these flags. A "selected" point is one which will be */
1266 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1267 : /* will be moved by the next instruction */
1268 : if ( sp->ttfindex==ptnum )
1269 : sp->selected = true;
1270 : else
1271 : sp->flexy = true;
1272 : }
1273 :
1274 : void DVMarkPts(DebugView *dv,SplineSet *ss) {
1275 : TT_ExecContext exc = DebuggerGetEContext(dv->dc);
1276 : long changing_point, basis_point;
1277 : int i,cnt,top;
1278 : int operator;
1279 : SplineSet *spl;
1280 : SplinePoint *sp;
1281 :
1282 : for ( spl=ss; spl!=NULL ; spl=spl->next ) {
1283 : for ( sp = spl->first; ; ) {
1284 : sp->selected = false;
1285 : sp->roundx = sp->roundy = false;
1286 : sp->flexx = sp->flexy = false;
1287 : /* I reuse these flags. A "selected" point is one which will be */
1288 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1289 : /* will be moved by the next instruction */
1290 : /* A roundx point or flexx nextcp means this is the reference */
1291 : /* point, etc. */
1292 : if ( sp->next==NULL )
1293 : break;
1294 : sp = sp->next->to;
1295 : if ( sp==spl->first )
1296 : break;
1297 : }
1298 : }
1299 :
1300 : if ( exc==NULL )
1301 : return; /* Not running */
1302 : if ( exc->IP>=exc->codeSize || exc->code==NULL )
1303 : return; /* At end */
1304 :
1305 : operator = ((uint8 *) exc->code)[exc->IP];
1306 : changing_point = -1;
1307 : basis_point = -1;
1308 :
1309 : if ( operator>=0xc0 && operator <= 0xdf ) {
1310 : /* MDRP */
1311 : if ( exc->GS.gep1 ) /* No good way to mark twilight points, so only mark normal ones */
1312 : changing_point = exc->stack[exc->top-1];
1313 : if ( exc->GS.gep0 )
1314 : basis_point = exc->GS.rp0;
1315 : } else if ( operator>=0xe0 && operator <= 0xff ) {
1316 : /* MIRP */
1317 : if ( exc->GS.gep1 ) /* No good way to mark twilight points, so only mark normal ones */
1318 : changing_point = exc->stack[exc->top-2];
1319 : if ( exc->GS.gep0 )
1320 : basis_point = exc->GS.rp0;
1321 : } else if ( operator>=0xb0 && operator <= 0xbf ) {
1322 : /* Push */
1323 : } else switch ( operator ) {
1324 : case 0xf:
1325 : /* Moves point to intersection of two lines */
1326 : if ( exc->GS.gep2 ) /* No good way to mark twilight points, so only mark normal ones */
1327 : changing_point = exc->stack[exc->top-5];
1328 : if ( exc->GS.gep0 ) {
1329 : SetBasisPoint(ss,exc->stack[exc->top-4]);
1330 : SetBasisPoint(ss,exc->stack[exc->top-3]);
1331 : }
1332 : if ( exc->GS.gep1 ) {
1333 : SetBasisPoint(ss,exc->stack[exc->top-2]);
1334 : SetBasisPoint(ss,exc->stack[exc->top-1]);
1335 : }
1336 : break;
1337 : case 0x10: case 0x11: case 0x12:
1338 : /* Set Reference Point ? */
1339 : basis_point = exc->stack[exc->top-1];
1340 : break;
1341 : case 0x27:
1342 : /* Align Points */
1343 : if ( exc->GS.gep0 )
1344 : SetChangingPoint(ss,exc->stack[exc->top-1]);
1345 : if ( exc->GS.gep1 )
1346 : SetChangingPoint(ss,exc->stack[exc->top-2]);
1347 : break;
1348 : case 0x28:
1349 : /* Untouch point */
1350 : if ( exc->GS.gep0 )
1351 : changing_point = exc->stack[exc->top-1];
1352 : break;
1353 : case 0x2E:
1354 : /* Touch point */
1355 : if ( exc->GS.gep0 )
1356 : changing_point = exc->stack[exc->top-1];
1357 : break;
1358 : case 0x2F:
1359 : /* Round and Touch point */
1360 : if ( exc->GS.gep0 )
1361 : changing_point = exc->stack[exc->top-1];
1362 : break;
1363 : case 0x30:
1364 : /* Interpolate Untouched Points in y */
1365 : if ( exc->GS.gep2 ) {
1366 : TT_GlyphZoneRec *r = &exc->pts;
1367 : for ( spl=ss; spl!=NULL ; spl=spl->next ) {
1368 : for ( sp = spl->first; ; ) {
1369 : if ( sp->ttfindex<r->n_points &&
1370 : !(r->tags[sp->ttfindex]&FT_Curve_Tag_Touch_Y) )
1371 : sp->selected = true;
1372 : if ( sp->nextcpindex<r->n_points &&
1373 : !(r->tags[sp->nextcpindex]&FT_Curve_Tag_Touch_Y) )
1374 : sp->flexy = true;
1375 : /* I reuse these flags. A "selected" point is one which will be */
1376 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1377 : /* will be moved by the next instruction */
1378 : if ( sp->next==NULL )
1379 : break;
1380 : sp = sp->next->to;
1381 : if ( sp==spl->first )
1382 : break;
1383 : }
1384 : }
1385 : }
1386 : break;
1387 : case 0x31:
1388 : /* Interpolate Untouched Points in x */
1389 : if ( exc->GS.gep2 ) {
1390 : TT_GlyphZoneRec *r = &exc->pts;
1391 : for ( spl=ss; spl!=NULL ; spl=spl->next ) {
1392 : for ( sp = spl->first; ; ) {
1393 : if ( sp->ttfindex<r->n_points &&
1394 : !(r->tags[sp->ttfindex]&FT_Curve_Tag_Touch_X) )
1395 : sp->selected = true;
1396 : if ( sp->nextcpindex<r->n_points &&
1397 : !(r->tags[sp->nextcpindex]&FT_Curve_Tag_Touch_X) )
1398 : sp->flexy = true;
1399 : /* I reuse these flags. A "selected" point is one which will be */
1400 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1401 : /* will be moved by the next instruction */
1402 : if ( sp->next==NULL )
1403 : break;
1404 : sp = sp->next->to;
1405 : if ( sp==spl->first )
1406 : break;
1407 : }
1408 : }
1409 : }
1410 : break;
1411 : case 0x32: case 0x33:
1412 : /* Shift point by amount ref point shifted */
1413 : if ( operator==0x33 ) {
1414 : if ( exc->GS.gep0 )
1415 : basis_point = exc->GS.rp1;
1416 : } else {
1417 : if ( exc->GS.gep1 )
1418 : basis_point = exc->GS.rp2;
1419 : }
1420 : if ( exc->GS.gep2 )
1421 : for ( i=1; i<=exc->GS.loop && i<exc->top; ++i ) {
1422 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1423 : }
1424 : break;
1425 : case 0x34: case 0x35:
1426 : /* Shift contour by amount ref point shifted */
1427 : if ( operator==0x35 ) {
1428 : if ( exc->GS.gep0 )
1429 : basis_point = exc->stack[exc->GS.rp1];
1430 : } else {
1431 : if ( exc->GS.gep1 )
1432 : basis_point = exc->stack[exc->GS.rp2];
1433 : }
1434 : if ( exc->GS.gep2 ) {
1435 : for ( spl=ss, i=exc->stack[exc->top-1]; i>0 && spl!=NULL; --i, spl=spl->next );
1436 : if ( spl!=NULL ) {
1437 : for ( sp = spl->first; ; ) {
1438 : if ( sp->ttfindex<0xfff0 )
1439 : sp->selected = true;
1440 : if ( sp->nextcpindex<0xfff0 )
1441 : sp->flexy = true;
1442 : /* I reuse these flags. A "selected" point is one which will be */
1443 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1444 : /* will be moved by the next instruction */
1445 : if ( sp->next==NULL )
1446 : break;
1447 : sp = sp->next->to;
1448 : if ( sp==spl->first )
1449 : break;
1450 : }
1451 : }
1452 : }
1453 : break;
1454 : case 0x36: case 0x37:
1455 : if ( operator==0x37 ) {
1456 : if ( exc->GS.gep0 )
1457 : basis_point = exc->stack[exc->GS.rp1];
1458 : } else {
1459 : if ( exc->GS.gep1 )
1460 : basis_point = exc->stack[exc->GS.rp2];
1461 : }
1462 : if ( exc->stack[exc->top-1] ) {
1463 : for ( spl=ss; spl!=NULL; spl=spl->next ) {
1464 : for ( sp = spl->first; ; ) {
1465 : if ( sp->ttfindex<0xfff0 )
1466 : sp->selected = true;
1467 : if ( sp->nextcpindex<0xfff0 )
1468 : sp->flexy = true;
1469 : /* I reuse these flags. A "selected" point is one which will be */
1470 : /* moved by the instruction. A "flexy"ed point means its nextcp */
1471 : /* will be moved by the next instruction */
1472 : if ( sp->next==NULL )
1473 : break;
1474 : sp = sp->next->to;
1475 : if ( sp==spl->first )
1476 : break;
1477 : }
1478 : }
1479 : }
1480 : break;
1481 : case 0x38:
1482 : /* Shift point by pixel amount */
1483 : if ( exc->GS.gep2 ) {
1484 : for ( i=2; i<=exc->GS.loop+1 && i<exc->top; ++i )
1485 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1486 : }
1487 : break;
1488 : case 0x39:
1489 : /* Interpolated Point */
1490 : if ( exc->GS.gep0 )
1491 : SetBasisPoint(ss,exc->GS.rp1);
1492 : if ( exc->GS.gep1 )
1493 : SetBasisPoint(ss,exc->GS.rp2);
1494 : if ( exc->GS.gep2 ) {
1495 : for ( i=1; i<=exc->GS.loop+1 && i<exc->top; ++i )
1496 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1497 : }
1498 : break;
1499 : case 0x3A: case 0x3B:
1500 : /* MSIRP Move Stack Indirect Relative Point */
1501 : if ( exc->GS.gep1 )
1502 : changing_point = exc->stack[exc->top-2];
1503 : if ( exc->GS.gep0 )
1504 : basis_point = exc->GS.rp0;
1505 : break;
1506 : case 0x3C:
1507 : /* Align to Reference Point */
1508 : if ( exc->GS.gep0 )
1509 : basis_point = exc->GS.rp0;
1510 : if ( exc->GS.gep1 )
1511 : for ( i=1; i<=exc->GS.loop && i<exc->top; ++i ) {
1512 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1513 : }
1514 : break;
1515 : case 0x3E: case 0x3F:
1516 : /* MIAP Move Indirect Absolute Point */
1517 : if ( exc->GS.gep0 )
1518 : changing_point = exc->stack[exc->top-2];
1519 : break;
1520 : case 0x46: case 0x47:
1521 : /* Get current/original point coord projected on projection vector */
1522 : if ( exc->GS.gep2 )
1523 : basis_point = exc->stack[exc->top-1];
1524 : break;
1525 : case 0x48:
1526 : /* Sets coordinate from stack using proj & free vectors */
1527 : if ( exc->GS.gep2 )
1528 : changing_point = exc->stack[exc->top-2];
1529 : break;
1530 : case 0x49: case 0x4A:
1531 : /* Measure Distance */
1532 : if ( exc->GS.gep0 )
1533 : SetBasisPoint( ss, exc->stack[exc->top-1] );
1534 : if ( exc->GS.gep1 )
1535 : SetBasisPoint( ss, exc->stack[exc->top-2] );
1536 : break;
1537 : case 0x5D: case 0x71: case 0x72:
1538 : case 0x73: case 0x74: case 0x75:
1539 : /* Delta Point */
1540 : cnt = exc->stack[exc->top-1];
1541 : for ( i=0; i<cnt; ++i ) {
1542 : if ( 2*i+3 > exc->top )
1543 : break;
1544 : if ( exc->GS.gep0 )
1545 : SetChangingPoint(ss, exc->stack[exc->top-2-2*i]);
1546 : }
1547 : break;
1548 : case 0x80:
1549 : /* Flip Points */
1550 : if ( exc->GS.gep0 )
1551 : for ( i=1; i<=exc->GS.loop && i<exc->top; ++i ) {
1552 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1553 : }
1554 : break;
1555 : case 0x81: case 0x82:
1556 : i = exc->stack[exc->top-1];
1557 : top = exc->stack[exc->top-2];
1558 : if ( exc->GS.gep0 )
1559 : for ( ; i<=top; ++i ) {
1560 : SetChangingPoint(ss,exc->stack[exc->top-i]);
1561 : }
1562 : break;
1563 : case 0x06: case 0x07:
1564 : case 0x08: case 0x09:
1565 : case 0x86: case 0x87:
1566 : /* Sets vector from line */
1567 : if ( exc->GS.gep1 )
1568 : SetBasisPoint(ss,exc->stack[exc->top-2]);
1569 : if ( exc->GS.gep2 )
1570 : SetBasisPoint(ss,exc->stack[exc->top-1]);
1571 : break;
1572 : default:
1573 : /* Many instructions don't refer to points */
1574 : break;
1575 : }
1576 : if ( changing_point!=-1 )
1577 : SetChangingPoint(ss,changing_point);
1578 : if ( basis_point!=-1 )
1579 : SetBasisPoint(ss,basis_point);
1580 : }
1581 :
1582 : #else
1583 0 : void DVCreateGloss(DebugView *dv) {
1584 0 : }
1585 :
1586 0 : void DVMarkPts(DebugView *dv,SplineSet *ss) {
1587 0 : }
1588 : #endif /* Has Debugger */
|