LCOV - code coverage report
Current view: top level - fontforgeexe - cvdgloss.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 4 0.0 %
Date: 2017-08-04 Functions: 0 2 0.0 %

          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 */

Generated by: LCOV version 1.10