LCOV - code coverage report
Current view: top level - fontforgeexe - ttfinstrsui.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 13 1396 0.9 %
Date: 2017-08-04 Functions: 2 42 4.8 %

          Line data    Source code
       1             : /* Copyright (C) 2001-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             :  * derived 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 "cvundoes.h"
      28             : #include "fontforgeui.h"
      29             : #include "splineutil.h"
      30             : #include <gkeysym.h>
      31             : #include <ustring.h>
      32             : #include <utype.h>
      33             : #include "ttf.h"
      34             : #include "ttfinstrs.h"
      35             : 
      36             : extern GBox _ggadget_Default_Box;
      37             : #define ACTIVE_BORDER   (_ggadget_Default_Box.active_border)
      38             : #define MAIN_FOREGROUND (_ggadget_Default_Box.main_foreground)
      39             : 
      40             : extern int _GScrollBar_Width;
      41             : #define EDGE_SPACING    2
      42             : 
      43             : #define ttf_width 16
      44             : #define ttf_height 16
      45             : static unsigned char ttf_bits[] = {
      46             :    0xff, 0x07, 0x21, 0x04, 0x20, 0x00, 0xfc, 0x7f, 0x24, 0x40, 0xf4, 0x5e,
      47             :    0xbc, 0x72, 0xa0, 0x02, 0xa0, 0x02, 0xa0, 0x02, 0xf0, 0x02, 0x80, 0x02,
      48             :    0xc0, 0x06, 0x40, 0x04, 0xc0, 0x07, 0x00, 0x00};
      49             : GWindow ttf_icon = NULL;
      50             : 
      51             : static char *instrhelppopup[256];
      52             : 
      53           0 : static void ihaddr(int bottom,int top,char *msg) {
      54           0 :     while ( bottom<=top )
      55           0 :         instrhelppopup[bottom++] = msg;
      56           0 : }
      57             : 
      58           0 : static void ihadd(int p,char *msg) {
      59           0 :     ihaddr(p,p,msg);
      60           0 : }
      61             : 
      62           0 : static void instrhelpsetup(void) {
      63           0 :     if ( instrhelppopup[0]!=NULL )
      64           0 : return;
      65           0 :     ihadd(0x7f,N_("Adjust Angle\nObsolete instruction\nPops one value"));
      66           0 :     ihadd(0x64,N_("ABSolute Value\nReplaces top of stack with its abs"));
      67           0 :     ihadd(0x60,N_("ADD\nPops two 26.6 fixed numbers from stack\nadds them, pushes result"));
      68           0 :     ihadd(0x27,N_("ALIGN PoinTS\nAligns (&pops) the two points which are on the stack\nby moving along freedom vector to the average of their\npositions on projection vector"));
      69           0 :     ihadd(0x3c,N_("ALIGN to Reference Point\nPops as many points as specified in loop counter\nAligns points with RP0 by moving each\nalong freedom vector until distance to\nRP0 on projection vector is 0"));
      70           0 :     ihadd(0x5a,N_("logical AND\nPops two values, ands them, pushes result"));
      71           0 :     ihadd(0x2b,N_("CALL function\nPops a value, calls the function represented by it"));
      72           0 :     ihadd(0x67,N_("CEILING\nPops one 26.6 value, rounds upward to an int\npushes result"));
      73           0 :     ihadd(0x25,N_("Copy INDEXed element to stack\nPops an index & copies stack\nelement[index] to top of stack"));
      74           0 :     ihadd(0x22,N_("CLEAR\nPops all elements on stack"));
      75           0 :     ihadd(0x4f,N_("DEBUG call\nPops a value and executes a debugging interpreter\n(if available)"));
      76           0 :     ihadd(0x73,N_("DELTA exception C1\nPops a value n & then n exception specifications & cvt entries\nchanges each cvt entry at a given size by the pixel amount"));
      77           0 :     ihadd(0x74,N_("DELTA exception C2\nPops a value n & then n exception specifications & cvt entries\nchanges each cvt entry at a given size by the amount"));
      78           0 :     ihadd(0x75,N_("DELTA exception C3\nPops a value n & then n exception specifications & cvt entries\nchanges each cvt entry at a given size by the amount"));
      79           0 :     ihadd(0x5D,N_("DELTA exception P1\nPops a value n & then n exception specifications & points\nmoves each point at a given size by the amount"));
      80           0 :     ihadd(0x71,N_("DELTA exception P2\nPops a value n & then n exception specifications & points\nmoves each point at a given size by the amount"));
      81           0 :     ihadd(0x72,N_("DELTA exception P3\nPops a value n & then n exception specifications & points\nmoves each point at a given size by the amount"));
      82           0 :     ihadd(0x24,N_("DEPTH of stack\nPushes the number of elements on the stack"));
      83           0 :     ihadd(0x62,N_("DIVide\nPops two 26.6 numbers, divides them, pushes result"));
      84           0 :     ihadd(0x20,N_("DUPlicate top stack element\nPushes the top stack element again"));
      85           0 :     ihadd(0x59,N_("End IF\nEnds an IF or IF-ELSE sequence"));
      86           0 :     ihadd(0x1b,N_("ELSE clause\nStart of Else clause of preceding IF"));
      87           0 :     ihadd(0x2d,N_("END Function definition"));
      88           0 :     ihadd(0x54,N_("EQual\nPops two values, tests for equality, pushes result(0/1)"));
      89           0 :     ihadd(0x57,N_("EVEN\nPops one value, rounds it and tests if it is even(0/1)"));
      90           0 :     ihadd(0x2C,N_("Function DEFinition\nPops a value (n) and starts the nth\nfunction definition"));
      91           0 :     ihadd(0x4e,N_("set the auto FLIP boolean to OFF"));
      92           0 :     ihadd(0x4d,N_("set the auto FLIP boolean to ON"));
      93           0 :     ihadd(0x80,N_("FLIP PoinT\nPops as many points as specified in loop counter\nFlips whether each point is on/off curve"));
      94           0 :     ihadd(0x82,N_("FLIP RanGe OFF\nPops two point numbers\nsets all points between to be off curve points"));
      95           0 :     ihadd(0x81,N_("FLIP RanGe ON\nPops two point numbers\nsets all points between to be on curve points"));
      96           0 :     ihadd(0x66,N_("FLOOR\nPops a value, rounds to lowest int, pushes result"));
      97           0 :     ihaddr(0x46,0x47,N_("Get Coordinate[a] projected onto projection vector\n 0=>use current pos\n 1=>use original pos\nPops one point, pushes the coordinate of\nthe point along projection vector"));
      98           0 :     ihadd(0x88,N_("GET INFOrmation\nPops information type, pushes result"));
      99           0 :     ihadd(0x0d,N_("Get Freedom Vector\nDecomposes freedom vector, pushes its\ntwo coordinates onto stack as 2.14"));
     100           0 :     ihadd(0x0c,N_("Get Projection Vector\nDecomposes projection vector, pushes its\ntwo coordinates onto stack as 2.14"));
     101           0 :     ihadd(0x52,N_("Greater Than\nPops two values, pushes (0/1) if bottom el > top"));
     102           0 :     ihadd(0x53,N_("Greater Than or EQual\nPops two values, pushes (0/1) if bottom el >= top"));
     103           0 :     ihadd(0x89,N_("Instruction DEFinition\nPops a value which becomes the opcode\nand begins definition of new instruction"));
     104           0 :     ihadd(0x58,N_("IF test\nPops an integer,\nif 0 (false) next instruction is ELSE or EIF\nif non-0 execution continues normally\n(unless there's an ELSE)"));
     105           0 :     ihadd(0x8e,N_("INSTRuction execution ConTRoL\nPops a selector and value\nSets a state variable"));
     106           0 :     ihadd(0x39,N_("Interpolate Point\nPops as many points as specified in loop counter\nInterpolates each point to preserve original status\nwith respect to RP1 and RP2"));
     107           0 :     ihadd(0x0f,N_("moves point to InterSECTion of two lines\nPops start,end start,end points of two lines\nand a point to move. Point is moved to\nintersection"));
     108           0 :     ihaddr(0x30,0x31,N_("Interpolate Untouched Points[a]\n 0=> interpolate in y direction\n 1=> x direction"));
     109           0 :     ihadd(0x1c,N_("JuMP Relative\nPops offset (in bytes) to move the instruction pointer"));
     110           0 :     ihadd(0x79,N_("Jump Relative On False\nPops a boolean and an offset\nChanges instruction pointer by offset bytes\nif boolean is false"));
     111           0 :     ihadd(0x78,N_("Jump Relative On True\nPops a boolean and an offset\nChanges instruction pointer by offset bytes\nif boolean is true"));
     112           0 :     ihadd(0x2a,N_("LOOP and CALL function\nPops a function number & count\nCalls function count times"));
     113           0 :     ihadd(0x50,N_("Less Than\nPops two values, pushes (0/1) if bottom el < top"));
     114           0 :     ihadd(0x51,N_("Less Than or EQual\nPops two values, pushes (0/1) if bottom el <= top"));
     115           0 :     ihadd(0x8b,N_("MAXimum of top two stack entries\nPops two values, pushes the maximum back"));
     116           0 :     ihaddr(0x49,0x4a,N_("Measure Distance[a]\n 0=>distance with current positions\n 1=>distance with original positions\nPops two point numbers, pushes distance between them"));
     117           0 :     ihaddr(0x2e,0x2f,N_("Move Direct Absolute Point[a]\n 0=>do not round\n 1=>round\nPops a point number, touches that point\nand perhaps rounds it to the grid along\nthe projection vector. Sets rp0&rp1 to the point"));
     118           0 :     ihaddr(0xc0,0xdf,N_("Move Direct Relative Point[abcde]\n a=0=>don't set rp0\n a=1=>set rp0 to p\n b=0=>do not keep distance more than minimum\n b=1=>keep distance at least minimum\n c=0 do not round\n c=1 round\n de=0 => grey distance\n de=1 => black distance\n de=2 => white distance\nPops a point moves it so that it maintains\nits original distance to the rp0. Sets\nrp1 to rp0, rp2 to point, sometimes rp0 to point"));
     119           0 :     ihaddr(0x3e,0x3f,N_("Move Indirect Absolute Point[a]\n 0=>do not round, don't use cvt cutin\n 1=>round\nPops a point number & a cvt entry,\ntouches the point and moves it to the coord\nspecified in the cvt (along the projection vector).\nSets rp0&rp1 to the point"));
     120           0 :     ihadd(0x8c,N_("Minimum of top two stack entries\nPops two values, pushes the minimum back"));
     121           0 :     ihadd(0x26,N_("Move INDEXed element to stack\nPops an index & moves stack\nelement[index] to top of stack\n(removing it from where it was)"));
     122           0 :     ihaddr(0xe0,0xff,N_("Move Indirect Relative Point[abcde]\n a=0=>don't set rp0\n a=1=>set rp0 to p\n b=0=>do not keep distance more than minimum\n b=1=>keep distance at least minimum\n c=0 do not round nor use cvt cutin\n c=1 round & use cvt cutin\n de=0 => grey distance\n de=1 => black distance\n de=2 => white distance\nPops a cvt index and a point moves it so that it\nis cvt[index] from rp0. Sets\nrp1 to rp0, rp2 to point, sometimes rp0 to point"));
     123           0 :     ihadd(0x4b,N_("Measure Pixels Per EM\nPushs the pixels per em (for current rasterization)"));
     124           0 :     ihadd(0x4c,N_("Measure Point Size\nPushes the current point size"));
     125           0 :     ihaddr(0x3a,0x3b,N_("Move Stack Indirect Relative Point[a]\n 0=>do not set rp0\n 1=>set rp0 to point\nPops a 26.6 distance and a point\nMoves point so it is distance from rp0"));
     126           0 :     ihadd(0x63,N_("MULtiply\nPops two 26.6 numbers, multiplies them, pushes result"));
     127           0 :     ihadd(0x65,N_("NEGate\nNegates the top of the stack"));
     128           0 :     ihadd(0x55,N_("Not EQual\nPops two values, tests for inequality, pushes result(0/1)"));
     129           0 :     ihadd(0x5c,N_("logical NOT\nPops a number, if 0 pushes 1, else pushes 0"));
     130           0 :     ihadd(0x40,N_("N PUSH Bytes\nReads an (unsigned) count byte from the\ninstruction stream, then reads and pushes\nthat many unsigned bytes"));
     131           0 :     ihadd(0x41,N_("N PUSH Words\nReads an (unsigned) count byte from the\ninstruction stream, then reads and pushes\nthat many signed 2byte words"));
     132           0 :     ihaddr(0x6c,0x6f,N_("No ROUNDing of value[ab]\n ab=0 => grey distance\n ab=1 => black distance\n ab=2 => white distance\nPops a coordinate (26.6), changes it (without\nrounding) to compensate for engine effects\npushes it back"));
     133           0 :     ihadd(0x56,N_("ODD\nPops one value, rounds it and tests if it is odd(0/1)"));
     134           0 :     ihadd(0x5b,N_("logical OR\nPops two values, ors them, pushes result"));
     135           0 :     ihadd(0x21,N_("POP top stack element"));
     136           0 :     ihaddr(0xb0,0xb7,N_("PUSH Byte[abc]\n abc is the number-1 of bytes to push\nReads abc+1 unsigned bytes from\nthe instruction stream and pushes them"));
     137           0 :     ihaddr(0xb8,0xbf,N_("PUSH Word[abc]\n abc is the number-1 of words to push\nReads abc+1 signed words from\nthe instruction stream and pushes them"));
     138           0 :     ihadd(0x45,N_("Read Control Value Table entry\nPops an index to the CVT and\npushes it in 26.6 format"));
     139           0 :     ihadd(0x7d,N_("Round Down To Grid\n\nSets round state to the obvious"));
     140           0 :     ihadd(0x7a,N_("Round OFF\nSets round state so that no rounding occurs\nbut engine compensation does"));
     141           0 :     ihadd(0x8a,N_("ROLL the top three stack elements"));
     142           0 :     ihaddr(0x68,0x6b,N_("ROUND value[ab]\n ab=0 => grey distance\n ab=1 => black distance\n ab=2 => white distance\nRounds a coordinate (26.6) at top of stack\nand compensates for engine effects"));
     143           0 :     ihadd(0x43,N_("Read Store\nPops an index into store array\nPushes value at that index"));
     144           0 :     ihadd(0x3d,N_("Round To Double Grid\nSets the round state (round to closest .5/int)"));
     145           0 :     ihadd(0x18,N_("Round To Grid\nSets the round state"));
     146           0 :     ihadd(0x19,N_("Round To Half Grid\nSets the round state (round to closest .5 not int)"));
     147           0 :     ihadd(0x7c,N_("Round Up To Grid\nSets the round state"));
     148           0 :     ihadd(0x77,N_("Super 45\302\260 ROUND\nToo complicated. Look it up"));
     149           0 :     ihadd(0x7e,N_("Set ANGle Weight\nPops an int, and sets the angle\nweight state variable to it\nObsolete"));
     150           0 :     ihadd(0x85,N_("SCAN conversion ConTRoL\nPops a number which sets the\ndropout control mode"));
     151           0 :     ihadd(0x8d,N_("SCANTYPE\nPops number which sets which scan\nconversion rules to use"));
     152           0 :     ihadd(0x48,N_("Sets Coordinate From Stack using projection & freedom vectors\nPops a coordinate 26.6 and a point\nMoves point to given coordinate"));
     153           0 :     ihadd(0x1d,N_("Sets Control Value Table Cut-In\nPops 26.6 from stack, sets cvt cutin"));
     154           0 :     ihadd(0x5e,N_("Set Delta Base\nPops value sets delta base"));
     155           0 :     ihaddr(0x86,0x87,N_("Set Dual Projection Vector To Line[a]\n 0 => parallel to line\n 1=>orthogonal to line\nPops two points used to establish the line\nSets a second projection vector based on original\npositions of points"));
     156           0 :     ihadd(0x5F,N_("Set Delta Shift\nPops a new value for delta shift"));
     157           0 :     ihadd(0x0b,N_("Set Freedom Vector From Stack\npops 2 2.14 values (x,y) from stack\nmust be a unit vector"));
     158           0 :     ihaddr(0x04,0x05,N_("Set Freedom Vector To Coordinate Axis[a]\n 0=>y axis\n 1=>x axis\n"));
     159           0 :     ihaddr(0x08,0x09,N_("Set Freedom Vector To Line[a]\n 0 => parallel to line\n 1=>orthogonal to line\nPops two points used to establish the line\nSets the freedom vector"));
     160           0 :     ihadd(0x0e,N_("Set Freedom Vector To Projection Vector"));
     161           0 :     ihaddr(0x34,0x35,N_("SHift Contour using reference point[a]\n 0=>uses rp2 in zp1\n 1=>uses rp1 in zp0\nPops number of contour to be shifted\nShifts the entire contour by the amount\nreference point was shifted"));
     162           0 :     ihaddr(0x32,0x33,N_("SHift Point using reference point[a]\n 0=>uses rp2 in zp1\n 1=>uses rp1 in zp0\nPops as many points as specified by the loop count\nShifts each by the amount the reference\npoint was shifted"));
     163           0 :     ihadd(0x38,N_("SHift point by a PIXel amount\nPops an amount (26.6) and as many points\nas the loop counter specifies\neach point is shifted along the FREEDOM vector"));
     164           0 :     ihaddr(0x36,0x37,N_("SHift Zone using reference point[a]\n 0=>uses rp2 in zp1\n 1=>uses rp1 in zp0\nPops the zone to be shifted\nShifts all points in zone by the amount\nthe reference point was shifted"));
     165           0 :     ihadd(0x17,N_("Set LOOP variable\nPops the new value for the loop counter\nDefaults to 1 after each use"));
     166           0 :     ihadd(0x1a,N_("Set Minimum Distance\nPops a 26.6 value from stack to be new minimum distance"));
     167           0 :     ihadd(0x0a,N_("Set Projection Vector From Stack\npops 2 2.14 values (x,y) from stack\nmust be a unit vector"));
     168           0 :     ihaddr(0x02,0x03,N_("Set Projection Vector To Coordinate Axis[a]\n 0=>y axis\n 1=>x axis\n" ));
     169           0 :     ihaddr(0x06,0x07,N_("Set Projection Vector To Line[a]\n 0 => parallel to line\n 1=>orthogonal to line\nPops two points used to establish the line\nSets the projection vector" ));
     170           0 :     ihadd(0x76,N_("Super ROUND\nToo complicated. Look it up"));
     171           0 :     ihadd(0x10,N_("Set Reference Point 0\nPops a point which becomes the new rp0"));
     172           0 :     ihadd(0x11,N_("Set Reference Point 1\nPops a point which becomes the new rp1"));
     173           0 :     ihadd(0x12,N_("Set Reference Point 2\nPops a point which becomes the new rp2"));
     174           0 :     ihadd(0x1f,N_("Set Single Width\nPops value for single width value (FUnit)"));
     175           0 :     ihadd(0x1e,N_("Set Single Width Cut-In\nPops value for single width cut-in value (26.6)"));
     176           0 :     ihadd(0x61,N_("SUBtract\nPops two 26.6 fixed numbers from stack\nsubtracts them, pushes result"));
     177           0 :     ihaddr(0x00,0x01,N_("Set freedom & projection Vectors To Coordinate Axis[a]\n 0=>both to y axis\n 1=>both to x axis\n" ));
     178           0 :     ihadd(0x23,N_("SWAP top two elements on stack"));
     179           0 :     ihadd(0x13,N_("Set Zone Pointer 0\nPops the zone number into zp0"));
     180           0 :     ihadd(0x14,N_("Set Zone Pointer 1\nPops the zone number into zp1"));
     181           0 :     ihadd(0x15,N_("Set Zone Pointer 2\nPops the zone number into zp2"));
     182           0 :     ihadd(0x16,N_("Set Zone PointerS\nPops the zone number into zp0,zp1 and zp2"));
     183           0 :     ihadd(0x29,N_("UnTouch Point\nPops a point number and marks it untouched"));
     184           0 :     ihadd(0x70,N_("Write Control Value Table in Funits\nPops a number(Funits) and a\nCVT index and writes the number to cvt[index]"));
     185           0 :     ihadd(0x44,N_("Write Control Value Table in Pixel units\nPops a number(26.6) and a\nCVT index and writes the number to cvt[index]"));
     186           0 :     ihadd(0x42,N_("Write Store\nPops a value and an index and writes the value to storage[index]"));
     187             : }
     188             : 
     189             : typedef struct instrdlg /* : InstrBase */{
     190             :     unsigned int inedit: 1;
     191             :     struct instrdata *instrdata;
     192             :     struct instrinfo instrinfo;
     193             :     int oc_height;
     194             :     GWindow gw, v;
     195             :     GGadget *ok, *cancel, *edit, *parse, *text, *topbox;
     196             : } InstrDlg;
     197             : 
     198           0 : static void instr_info_init(struct instrinfo *instrinfo) {
     199             : 
     200           0 :     instrinfo->lheight = instr_typify(instrinfo->instrdata);
     201           0 :     if ( instrinfo->fh!=0 ) {
     202           0 :         if ( instrinfo->lpos > instrinfo->lheight-instrinfo->vheight/instrinfo->fh )
     203           0 :             instrinfo->lpos = instrinfo->lheight-instrinfo->vheight/instrinfo->fh;
     204           0 :         if ( instrinfo->lpos<0 )
     205           0 :             instrinfo->lpos = 0;
     206             :     }
     207           0 : }
     208             : 
     209           0 : static void instr_resize(InstrDlg *iv,GEvent *event) {
     210             :     GRect size;
     211             :     int lh;
     212           0 :     struct instrinfo *ii = &iv->instrinfo;
     213             : 
     214           0 :     GGadgetGetSize(iv->text,&size);
     215           0 :     GDrawMove(ii->v,size.x,size.y);
     216           0 :     GDrawResize(ii->v,size.width,size.height);
     217           0 :     ii->vheight = size.height; ii->vwidth = size.width;
     218           0 :     lh = ii->lheight;
     219             : 
     220           0 :     GScrollBarSetBounds(ii->vsb,0,lh+2,ii->vheight<ii->fh ? 1 : ii->vheight/ii->fh);
     221           0 :     if ( ii->lpos + ii->vheight/ii->fh > lh )
     222           0 :         ii->lpos = lh-ii->vheight/ii->fh;
     223           0 :     if ( ii->lpos<0 ) ii->lpos = 0;
     224           0 :     GScrollBarSetPos(ii->vsb,ii->lpos);
     225           0 :     GDrawRequestExpose(iv->gw,NULL,false);
     226           0 : }
     227             : 
     228           0 : static void IVError(void *_iv,char *msg,int offset) {
     229           0 :     InstrDlg *iv = _iv;
     230             : 
     231           0 :     if ( iv!=NULL ) {
     232           0 :         GTextFieldSelect(iv->text,offset,offset);
     233           0 :         GTextFieldShow(iv->text,offset);
     234           0 :         GWidgetIndicateFocusGadget(iv->text);
     235             :     }
     236           0 :     ff_post_error(_("Parse Error"),msg);
     237           0 : }
     238             : 
     239           0 : static int IVParse(InstrDlg *iv) {
     240           0 :     char *text = GGadgetGetTitle8(iv->text);
     241           0 :     int icnt=0, i;
     242             :     uint8 *instrs;
     243             : 
     244           0 :     instrs = _IVParse(iv->instrdata->sf, text, &icnt, IVError, iv);
     245           0 :     free(text);
     246             : 
     247           0 :     if ( instrs==NULL )
     248           0 : return( false );
     249           0 :     if ( icnt!=iv->instrdata->instr_cnt )
     250           0 :         iv->instrdata->changed = true;
     251             :     else {
     252           0 :         for ( i=0; i<icnt; ++i )
     253           0 :             if ( instrs[i]!=iv->instrdata->instrs[i])
     254           0 :         break;
     255           0 :         if ( i==icnt ) {                /* Unchanged */
     256           0 :             free(instrs);
     257           0 : return( true );
     258             :         }
     259             :     }
     260           0 :     free( iv->instrdata->instrs );
     261           0 :     iv->instrdata->instrs = instrs;
     262           0 :     iv->instrdata->instr_cnt = icnt;
     263           0 :     iv->instrdata->max = icnt;
     264           0 :     iv->instrdata->changed = true;
     265           0 :     free(iv->instrdata->bts );
     266           0 :     iv->instrdata->bts = NULL;
     267           0 :     instr_info_init(&iv->instrinfo);
     268           0 :     GScrollBarSetBounds(iv->instrinfo.vsb,0,iv->instrinfo.lheight+2,
     269           0 :             iv->instrinfo.vheight<iv->instrinfo.fh? 1 : iv->instrinfo.vheight/iv->instrinfo.fh);
     270           0 : return( true );
     271             : }
     272             : 
     273           0 : static void IVOk(InstrDlg *iv) {
     274           0 :     struct instrdata *id = iv->instrdata;
     275             : 
     276             :     /* We need to update bits like instructions_out_of_date even if they */
     277             :     /* make no change. */
     278             :     if ( /*id->changed*/true ) {
     279           0 :         if ( id->sc!=NULL ) {
     280           0 :             SplineChar *sc = id->sc;
     281             :             CharView *cv;
     282           0 :             free(sc->ttf_instrs);
     283           0 :             sc->ttf_instrs_len = id->instr_cnt;
     284           0 :             if ( id->instr_cnt==0 )
     285           0 :                 sc->ttf_instrs = NULL;
     286             :             else {
     287           0 :                 sc->ttf_instrs = malloc( id->instr_cnt );
     288           0 :                 memcpy(sc->ttf_instrs,id->instrs,id->instr_cnt );
     289             :             }
     290           0 :             for ( cv=(CharView *) (sc->views); cv!=NULL; cv=(CharView *) (cv->b.next) )
     291           0 :                 cv->showpointnumbers = false;
     292           0 :             sc->instructions_out_of_date = true;
     293           0 :             SCCharChangedUpdate(sc,ly_none);
     294           0 :             sc->instructions_out_of_date = false;
     295           0 :             FVRefreshAll(sc->parent);
     296             :         } else {
     297             :             struct ttf_table *tab, *prev;
     298           0 :             if ( id->instr_cnt==0 ) {
     299           0 :                 for ( prev=NULL, tab=id->sf->ttf_tables; tab!=NULL && tab->tag!=id->tag; prev=tab, tab=tab->next );
     300           0 :                 if ( tab==NULL )
     301             :                     /* Nothing to be done */;
     302           0 :                 else if ( prev==NULL )
     303           0 :                     id->sf->ttf_tables = tab->next;
     304             :                 else
     305           0 :                     prev->next = tab->next;
     306           0 :                 if ( tab!=NULL ) {
     307           0 :                     tab->next = NULL;
     308           0 :                     TtfTablesFree(tab);
     309             :                 }
     310             :             } else {
     311           0 :                 tab = SFFindTable(id->sf,id->tag);
     312           0 :                 if ( tab==NULL ) {
     313           0 :                     tab = chunkalloc(sizeof(struct ttf_table));
     314           0 :                     tab->next = id->sf->ttf_tables;
     315           0 :                     id->sf->ttf_tables = tab;
     316           0 :                     tab->tag = id->tag;
     317             :                 }
     318           0 :                 free( tab->data );
     319           0 :                 tab->data = malloc( id->instr_cnt );
     320           0 :                 memcpy(tab->data,id->instrs,id->instr_cnt );
     321           0 :                 tab->len = id->instr_cnt;
     322             :             }
     323             :         }
     324             :     }
     325             :     /* Instructions get freed in et_destroy */
     326           0 : }
     327             : 
     328           0 : static void IVBuildEdit(InstrDlg *iv) {
     329             :     char *ret;
     330           0 :     ret = __IVUnParseInstrs((InstrBase *) iv);
     331           0 :     if ( iv->text!=NULL ) {
     332           0 :         GGadgetSetTitle8(iv->text,ret);
     333           0 :         GTextFieldSelect(iv->text,iv->instrinfo.offset-ret,iv->instrinfo.offset-ret);
     334           0 :         GTextFieldShow(iv->text,iv->instrinfo.scroll-ret);
     335             :     }
     336           0 : }
     337             : 
     338           0 : static void instr_expose(struct instrinfo *ii,GWindow pixmap,GRect *rect) {
     339             :     int low, high;
     340             :     int i,x,y;
     341             :     char loc[8], ins[8], val[8]; unichar_t uins[8], uname[30];
     342             :     int addr_end, num_end;
     343             :     static unichar_t nums[] = { '0', '0', '0', '0', '0', '0', '\0' };
     344             :     int indent;
     345             :     extern GBox _ggadget_Default_Box;
     346             : 
     347           0 :     GDrawSetFont(pixmap,ii->gfont);
     348           0 :     GDrawSetLineWidth(pixmap,0);
     349           0 :     addr_end = 0;
     350           0 :     if ( ii->showaddr )
     351           0 :         addr_end = GDrawGetTextWidth(pixmap,nums,4)+EDGE_SPACING;
     352           0 :     num_end = addr_end;
     353           0 :     if ( ii->showhex )
     354           0 :         num_end = addr_end + GDrawGetTextWidth(pixmap,nums,5)+4;
     355           0 :     else if ( addr_end<36+2*EDGE_SPACING )
     356           0 :         num_end = addr_end = 36+2*EDGE_SPACING;
     357             : 
     358           0 :     low = ( (rect->y-EDGE_SPACING)/ii->fh ) * ii->fh +EDGE_SPACING;
     359           0 :     high = ( (rect->y+rect->height+ii->fh-1-EDGE_SPACING)/ii->fh ) * ii->fh +EDGE_SPACING;
     360             : 
     361           0 :     if ( ii->isel_pos!=-1 ) {
     362             :         GRect r;
     363           0 :         r.x = 0; r.width = ii->vwidth;
     364           0 :         r.y = (ii->isel_pos-ii->lpos)*ii->fh+EDGE_SPACING; r.height = ii->fh;
     365           0 :         GDrawFillRect(pixmap,&r,ACTIVE_BORDER);
     366             :     }
     367             : 
     368           0 :     if ( ii->showaddr )
     369           0 :         GDrawDrawLine(pixmap,addr_end,rect->y,addr_end,rect->y+rect->height,0x000000);
     370           0 :     if ( ii->showhex )
     371           0 :         GDrawDrawLine(pixmap,num_end,rect->y,num_end,rect->y+rect->height,0x000000);
     372             : 
     373           0 :     indent = 0;
     374           0 :     for ( i=0, y=EDGE_SPACING-ii->lpos*ii->fh; y<low && i<ii->instrdata->instr_cnt; ++i ) {
     375           0 :         if ( ii->instrdata->bts[i]==bt_instr ) {
     376           0 :             int instr = ii->instrdata->instrs[i];
     377           0 :             if ( instr == ttf_if || instr==ttf_idef || instr == ttf_fdef )
     378           0 :                 ++indent;
     379           0 :             else if ( instr == ttf_eif || instr==ttf_endf )
     380           0 :                 --indent;
     381           0 :         } else if ( ii->instrdata->bts[i]==bt_wordhi )
     382           0 :             ++i;
     383           0 :         y += ii->fh;
     384             :     }
     385           0 :     if ( y<=high && ii->instrdata->instr_cnt==0 && i==0 ) {
     386           0 :         if ( ii->instrdata->in_composit ) {
     387           0 :             GDrawDrawText8(pixmap,num_end+EDGE_SPACING,y+ii->as,_("<instrs inherited>"),-1,0xff0000);
     388           0 :             y += ii->fh;
     389             :         }
     390           0 :         GDrawDrawText8(pixmap,num_end+EDGE_SPACING,y+ii->as,_("<no instrs>"),-1,0xff0000);
     391             :     } else {
     392             :         int temp_indent;
     393           0 :         for ( ; y<=high && i<ii->instrdata->instr_cnt+1; ++i ) {
     394           0 :             temp_indent = indent;
     395           0 :             sprintf( loc, "%d", i );
     396           0 :             if ( ii->instrdata->bts[i]==bt_wordhi ) {
     397           0 :                 sprintf( ins, " %02x%02x", ii->instrdata->instrs[i], ii->instrdata->instrs[i+1]); uc_strcpy(uins,ins);
     398           0 :                 sprintf( val, " %d", (short) ((ii->instrdata->instrs[i]<<8) | ii->instrdata->instrs[i+1]) );
     399           0 :                 uc_strcpy(uname,val);
     400           0 :                 ++i;
     401           0 :             } else if ( ii->instrdata->bts[i]==bt_cnt || ii->instrdata->bts[i]==bt_byte ) {
     402           0 :                 sprintf( ins, " %02x", ii->instrdata->instrs[i] ); uc_strcpy(uins,ins);
     403           0 :                 sprintf( val, " %d", ii->instrdata->instrs[i]);
     404           0 :                 uc_strcpy(uname,val);
     405           0 :             } else if ( ii->instrdata->bts[i]==bt_impliedreturn ) {
     406           0 :                 uc_strcpy(uname,_("<return>"));
     407           0 :                 uins[0] = '\0';
     408             :             } else {
     409           0 :                 int instr = ii->instrdata->instrs[i];
     410           0 :                 if ( instr == ttf_eif || instr==ttf_endf )
     411           0 :                     --indent;
     412           0 :                 temp_indent = indent;
     413           0 :                 if ( instr == ttf_else )
     414           0 :                     --temp_indent;
     415           0 :                 sprintf( ins, "%02x", instr ); uc_strcpy(uins,ins);
     416           0 :                 uc_strcpy(uname, ff_ttf_instrnames[instr]);
     417           0 :                 if ( instr == ttf_if || instr==ttf_idef || instr == ttf_fdef )
     418           0 :                     ++indent;
     419             :             }
     420             : 
     421           0 :             if ( ii->showaddr ) {
     422             :                 GRect size;
     423           0 :                 GDrawLayoutInit(pixmap,loc,-1,NULL);
     424           0 :                 GDrawLayoutExtents(pixmap,&size);
     425           0 :                 x = addr_end - EDGE_SPACING - size.width;
     426           0 :                 GDrawLayoutDraw(pixmap,x,y+ii->as,MAIN_FOREGROUND);
     427           0 :                 if ( ii->bpcheck && ii->bpcheck(ii,i))
     428           0 :                     GDrawDrawImage(pixmap,&GIcon_Stop,NULL,EDGE_SPACING,
     429           0 :                             y+(ii->fh-8)/2-5);
     430             :             }
     431           0 :             x = addr_end + EDGE_SPACING;
     432           0 :             if ( ii->showhex )
     433           0 :                 GDrawDrawText(pixmap,x,y+ii->as,uins,-1,MAIN_FOREGROUND);
     434           0 :             GDrawDrawText(pixmap,num_end+EDGE_SPACING+temp_indent*4,y+ii->as,uname,-1,MAIN_FOREGROUND);
     435           0 :             y += ii->fh;
     436             :         }
     437           0 :         if ( ii->showaddr && ii->lstopped!=-1 ) {
     438           0 :             GDrawDrawImage(pixmap,&GIcon_Stopped,NULL,EDGE_SPACING,
     439           0 :                     (ii->lstopped-ii->lpos)*ii->fh+(ii->fh-8)/2);
     440             :         }
     441             :     }
     442           0 : }
     443             : 
     444           0 : static void instr_mousedown(struct instrinfo *ii,int pos) {
     445             :     int i,l;
     446             : 
     447           0 :     pos = (pos-2)/ii->fh + ii->lpos;
     448           0 :     if ( pos>=ii->lheight )
     449           0 :         pos = -1;
     450             : 
     451           0 :     for ( i=l=0; l<pos && i<ii->instrdata->instr_cnt; ++i, ++l ) {
     452           0 :         if ( ii->instrdata->bts[i]==bt_wordhi )
     453           0 :             ++i;
     454             :     }
     455             : 
     456           0 :     ii->isel_pos=pos;
     457           0 :     if ( ii->selection_callback!=NULL )
     458           0 :         (ii->selection_callback)(ii,i);
     459           0 :     GDrawRequestExpose(ii->v,NULL,false);
     460           0 : }
     461             : 
     462           0 : static void instr_mousemove(struct instrinfo *ii,int pos) {
     463             :     int i,y;
     464             :     char *msg;
     465             : 
     466           0 :     if ( ii->mousedown ) {
     467           0 :         instr_mousedown(ii,pos);
     468           0 : return;
     469             :     }
     470           0 :     if ( ii->instrdata->bts==NULL )
     471           0 : return;
     472             : 
     473           0 :     pos = ((pos-2)/ii->fh) * ii->fh + 2;
     474             : 
     475           0 :     for ( i=0, y=2-ii->lpos*ii->fh; y<pos && i<ii->instrdata->instr_cnt; ++i ) {
     476           0 :         if ( ii->instrdata->bts[i]==bt_wordhi )
     477           0 :             ++i;
     478           0 :         y += ii->fh;
     479             :     }
     480           0 :     switch ( ii->instrdata->bts[i] ) {
     481             :       case bt_wordhi: case bt_wordlo:
     482           0 :         msg = _("A short to be pushed on the stack");
     483           0 :       break;
     484             :       case bt_cnt:
     485           0 :         msg = _("A count specifying how many bytes/shorts\nshould be pushed on the stack");
     486           0 :       break;
     487             :       case bt_byte:
     488           0 :         msg = _("An unsigned byte to be pushed on the stack");
     489           0 :       break;
     490             :       case bt_instr:
     491           0 :         msg = _(instrhelppopup[ii->instrdata->instrs[i]]);
     492           0 :         if ( msg==NULL ) msg = "???";
     493           0 :       break;
     494             :       default:
     495           0 :         msg = "???";
     496           0 :       break;
     497             :     }
     498           0 :     GGadgetPreparePopup8(GDrawGetParentWindow(ii->v),msg);
     499             : }
     500             : 
     501           0 : void instr_scroll(struct instrinfo *ii,struct sbevent *sb) {
     502           0 :     int newpos = ii->lpos;
     503             : 
     504           0 :     switch( sb->type ) {
     505             :       case et_sb_top:
     506           0 :         newpos = 0;
     507           0 :       break;
     508             :       case et_sb_uppage:
     509           0 :         newpos -= ii->vheight/ii->fh;
     510           0 :       break;
     511             :       case et_sb_up:
     512           0 :         --newpos;
     513           0 :       break;
     514             :       case et_sb_down:
     515           0 :         ++newpos;
     516           0 :       break;
     517             :       case et_sb_downpage:
     518           0 :         newpos += ii->vheight/ii->fh;
     519           0 :       break;
     520             :       case et_sb_bottom:
     521           0 :         newpos = ii->lheight-ii->vheight/ii->fh;
     522           0 :       break;
     523             :       case et_sb_thumb:
     524             :       case et_sb_thumbrelease:
     525           0 :         newpos = sb->pos;
     526           0 :       break;
     527             :     }
     528           0 :     if ( newpos>ii->lheight+1-ii->vheight/ii->fh )
     529           0 :         newpos = ii->lheight+1-ii->vheight/ii->fh;
     530           0 :     if ( newpos<0 ) newpos =0;
     531           0 :     if ( newpos!=ii->lpos ) {
     532             :         GRect r;
     533           0 :         int diff = newpos-ii->lpos;
     534           0 :         ii->lpos = newpos;
     535           0 :         GScrollBarSetPos(ii->vsb,ii->lpos);
     536           0 :         r.x=0; r.y = EDGE_SPACING; r.width=ii->vwidth; r.height=ii->vheight-2*EDGE_SPACING;
     537           0 :         GDrawScroll(ii->v,&r,0,diff*ii->fh);
     538             :     }
     539           0 : }
     540             : 
     541           0 : static int IIChar(struct instrinfo *ii,GEvent *event) {
     542           0 :     int pos = ii->isel_pos;
     543             : 
     544           0 :     if ( ii->handle_char )
     545           0 : return( (ii->handle_char)(ii,event));
     546             : 
     547           0 :     if ( event->u.chr.keysym == GK_Up || event->u.chr.keysym == GK_KP_Up )
     548           0 :         --pos;
     549           0 :     else if ( event->u.chr.keysym == GK_Down || event->u.chr.keysym == GK_KP_Down )
     550           0 :         ++pos;
     551           0 :     else if ( event->u.chr.keysym == GK_Home || event->u.chr.keysym == GK_KP_Home ||
     552           0 :             event->u.chr.keysym == GK_Begin || event->u.chr.keysym == GK_KP_Begin )
     553           0 :         pos = 0;
     554           0 :     else if ( event->u.chr.keysym == GK_End || event->u.chr.keysym == GK_KP_End ) {
     555           0 :         pos = ii->lheight-1;
     556             :     } else
     557           0 : return( false );
     558           0 :     if ( pos==-2 ) pos = -1;
     559           0 :     if ( pos!=ii->isel_pos ) {
     560           0 :         ii->isel_pos = pos;
     561           0 :         if ( pos!=-1 && (pos<ii->lpos || pos>=ii->lpos+ii->vheight/ii->fh )) {
     562           0 :             ii->lpos = pos-(ii->vheight/(3*ii->fh));
     563           0 :             if ( ii->lpos>=ii->lheight-ii->vheight/ii->fh )
     564           0 :                 ii->lpos = ii->lheight-ii->vheight/ii->fh-1;
     565           0 :             if ( ii->lpos<0 ) ii->lpos = 0;
     566           0 :             GScrollBarSetPos(ii->vsb,ii->lpos);
     567             :         }
     568             :     }
     569           0 :     if ( ii->selection_callback!=NULL ) {
     570             :         int i,l;
     571           0 :         for ( i=l=0; l<pos && i<ii->instrdata->instr_cnt; ++i, ++l ) {
     572           0 :             if ( ii->instrdata->bts[i]==bt_wordhi )
     573           0 :                 ++i;
     574             :         }
     575           0 :         (ii->selection_callback)(ii,i);
     576             :     }
     577           0 :     GDrawRequestExpose(ii->v,NULL,false);
     578           0 : return( true );
     579             : }
     580             : 
     581           0 : int ii_v_e_h(GWindow gw, GEvent *event) {
     582           0 :     struct instrinfo *ii = (struct instrinfo *) GDrawGetUserData(gw);
     583             : 
     584           0 :     switch ( event->type ) {
     585             :       case et_expose:
     586           0 :         instr_expose(ii,gw,&event->u.expose.rect);
     587           0 :       break;
     588             :       case et_char:
     589           0 :         if ( IIChar(ii,event)) {
     590             :             /* All Done */
     591             :             ;
     592           0 :         } else if ( event->u.chr.keysym == GK_Help || event->u.chr.keysym == GK_F1 ) {
     593           0 :             help("ttfinstrs.html");
     594             :         }
     595           0 :       break;
     596             :       case et_mousemove: case et_mousedown: case et_mouseup:
     597           0 :         GGadgetEndPopup();
     598           0 :         if ( event->type==et_mousemove ) {
     599           0 :             instr_mousemove(ii,event->u.mouse.y);
     600           0 :         } else if ( event->type==et_mousedown ) {
     601           0 :             instr_mousedown(ii,event->u.mouse.y);
     602           0 :             if ( event->u.mouse.clicks==2 ) {
     603             :                 /*InstrModCreate(ii)*/
     604             :                 ;
     605             :             }
     606             :         } else {
     607           0 :             instr_mousemove(ii,event->u.mouse.y);
     608           0 :             ii->mousedown = false;
     609             :         }
     610           0 :       break;
     611             :       case et_timer:
     612           0 :       break;
     613             :       case et_focus:
     614           0 :       break;
     615             :     }
     616           0 : return( true );
     617             : }
     618             : 
     619           0 : static int iv_e_h(GWindow gw, GEvent *event) {
     620           0 :     InstrDlg *iv = (InstrDlg *) GDrawGetUserData(gw);
     621             : 
     622           0 :     switch ( event->type ) {
     623             :       case et_expose:
     624           0 :       break;
     625             :       case et_resize:
     626           0 :         instr_resize(iv,event);
     627           0 :       break;
     628             :       case et_char:
     629           0 :         if ( event->u.chr.keysym == GK_Help || event->u.chr.keysym == GK_F1 )
     630           0 :             help("ttfinstrs.html");
     631           0 :       break;
     632             :       case et_controlevent:
     633           0 :         switch ( event->u.control.subtype ) {
     634             :           case et_scrollbarchange:
     635           0 :             instr_scroll(&iv->instrinfo,&event->u.control.u.sb);
     636           0 :           break;
     637             :           case et_buttonactivate:
     638           0 :             if ( event->u.control.g==iv->ok || event->u.control.g==iv->cancel ) {
     639           0 :                 if ( event->u.control.g == iv->ok ) {
     640           0 :                     if ( iv->inedit )
     641           0 :                         if ( !IVParse(iv))
     642           0 :       break;
     643           0 :                     IVOk(iv);
     644             :                 }
     645           0 :                 GDrawDestroyWindow(iv->gw);
     646           0 :             } else if ( event->u.control.g==iv->edit || event->u.control.g==iv->parse ) {
     647           0 :                 int toedit = event->u.control.g==iv->edit;
     648             :                 GRect size;
     649           0 :                 if ( toedit ) {
     650           0 :                     IVBuildEdit(iv);
     651           0 :                     GGadgetGetSize(iv->instrinfo.vsb,&size);
     652           0 :                     size.width = -1;
     653           0 :                     GGadgetSetDesiredSize(iv->text,&size,NULL);
     654           0 :                 } else if ( !IVParse(iv))
     655           0 :       break;
     656           0 :                 GGadgetSetVisible(iv->parse,toedit);
     657             :                 /*GGadgetSetVisible(iv->text,toedit);*/
     658           0 :                 GGadgetSetVisible(iv->edit,!toedit);
     659           0 :                 GGadgetSetVisible(iv->instrinfo.vsb,!toedit);
     660           0 :                 GDrawSetVisible(iv->instrinfo.v,!toedit);
     661           0 :                 GHVBoxFitWindow(iv->topbox);
     662           0 :                 iv->inedit = toedit;
     663             :             }
     664           0 :           break;
     665             :         }
     666           0 :       break;
     667             :       case et_close:
     668           0 :         GDrawDestroyWindow(iv->gw);
     669           0 :       break;
     670             :       case et_destroy: {
     671           0 :         SplineFont *sf = iv->instrdata->sf;
     672             :         struct instrdata *id, *prev;
     673           0 :         for ( prev = NULL, id=sf->instr_dlgs; id!=iv->instrdata && id!=NULL; prev=id, id=id->next );
     674           0 :         if ( prev==NULL )
     675           0 :             sf->instr_dlgs = iv->instrdata->next;
     676             :         else
     677           0 :             prev->next = iv->instrdata->next;
     678           0 :         free(iv->instrdata->instrs);
     679           0 :         free(iv->instrdata->bts);
     680           0 :         free(iv->instrdata);
     681           0 :         free(iv);
     682           0 :       } break;
     683             :     }
     684           0 : return( true );
     685             : }
     686             : 
     687           0 : static void InstrDlgCreate(struct instrdata *id,char *title) {
     688           0 :     InstrDlg *iv = calloc(1,sizeof(*iv));
     689             :     GRect pos;
     690             :     GWindow gw;
     691             :     GWindowAttrs wattrs;
     692             :     FontRequest rq;
     693             :     int as,ds,ld, lh;
     694             :     GGadgetCreateData gcd[11], *butarray[9], *harray[3], *varray[8];
     695             :     GTextInfo label[6];
     696             :     static GFont *font=NULL;
     697             : 
     698           0 :     instrhelpsetup();
     699             : 
     700           0 :     id->next = id->sf->instr_dlgs;
     701           0 :     id->sf->instr_dlgs = id;
     702           0 :     id->id = iv;
     703             : 
     704           0 :     iv->instrdata = id;
     705           0 :     iv->instrinfo.instrdata = id;
     706           0 :     iv->instrinfo.showhex = iv->instrinfo.showaddr = true;
     707           0 :     iv->instrinfo.lstopped = -1;
     708           0 :     instr_info_init(&iv->instrinfo);
     709             : 
     710           0 :     if ( ttf_icon==NULL )
     711           0 :         ttf_icon = GDrawCreateBitmap(NULL,ttf_width,ttf_height,ttf_bits);
     712             : 
     713           0 :     memset(&wattrs,0,sizeof(wattrs));
     714           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_icon;
     715           0 :     wattrs.event_masks = ~(1<<et_charup);
     716           0 :     wattrs.restrict_input_to_me = 1;
     717           0 :     wattrs.undercursor = 1;
     718           0 :     wattrs.cursor = ct_pointer;
     719           0 :     wattrs.utf8_window_title = title;
     720           0 :     wattrs.icon = ttf_icon;
     721           0 :     pos.x = pos.y = 0;
     722           0 :     if ( GIntGetResource(_NUM_Buttonsize)>65 )
     723           0 :         pos.width = GDrawPointsToPixels(NULL,3*GIntGetResource(_NUM_Buttonsize)+40);
     724             :     else
     725           0 :         pos.width = GDrawPointsToPixels(NULL,250);
     726           0 :     iv->oc_height = GDrawPointsToPixels(NULL,37);
     727           0 :     pos.height = GDrawPointsToPixels(NULL,100) + iv->oc_height;
     728           0 :     iv->gw = gw = GDrawCreateTopWindow(NULL,&pos,iv_e_h,iv,&wattrs);
     729             : 
     730           0 :     memset(&label,0,sizeof(label));
     731           0 :     memset(&gcd,0,sizeof(gcd));
     732           0 :     gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 105;
     733           0 :     gcd[0].gd.pos.width = -1;
     734           0 :     label[0].text = (unichar_t *) _("_OK");
     735           0 :     label[0].text_is_1byte = true;
     736           0 :     label[0].text_in_resource = true;
     737           0 :     gcd[0].gd.label = &label[0];
     738           0 :     gcd[0].gd.flags = gg_visible|gg_enabled|gg_but_default;
     739           0 :     gcd[0].creator = GButtonCreate;
     740           0 :     gcd[0].data = iv;
     741             : 
     742           0 :     gcd[1].gd.pos.x = -8; gcd[1].gd.pos.y = 3;
     743           0 :     gcd[1].gd.pos.width = -1;
     744           0 :     label[1].text = (unichar_t *) _("_Cancel");
     745           0 :     label[1].text_is_1byte = true;
     746           0 :     label[1].text_in_resource = true;
     747           0 :     gcd[1].gd.label = &label[1];
     748           0 :     gcd[1].gd.flags = gg_visible|gg_enabled|gg_but_cancel;
     749           0 :     gcd[1].creator = GButtonCreate;
     750           0 :     gcd[1].data = iv;
     751             : 
     752           0 :     gcd[2] = gcd[1];
     753           0 :     label[2].text = (unichar_t *) _("_Edit");
     754           0 :     label[2].text_is_1byte = true;
     755           0 :     label[2].text_in_resource = true;
     756           0 :     gcd[2].gd.flags = gg_visible|gg_enabled;
     757           0 :     gcd[2].gd.label = &label[2];
     758           0 :     gcd[2].creator = GButtonCreate;
     759           0 :     gcd[2].data = iv;
     760             : 
     761           0 :     gcd[3] = gcd[1];
     762           0 :     label[3] = label[2];
     763           0 :     label[3].text = (unichar_t *) _("_Parse");
     764           0 :     gcd[3].gd.flags = gg_enabled;
     765           0 :     gcd[3].gd.label = &label[3];
     766           0 :     gcd[3].creator = GButtonCreate;
     767           0 :     gcd[3].data = iv;
     768             : 
     769           0 :     butarray[0] = GCD_Glue; butarray[1] = &gcd[0];
     770           0 :     butarray[2] = GCD_Glue; butarray[3] = &gcd[2];
     771           0 :     butarray[4] = &gcd[3]; butarray[5] = GCD_Glue;
     772           0 :     butarray[6] = &gcd[1]; butarray[7] = GCD_Glue;
     773           0 :     butarray[8] = NULL;
     774           0 :     gcd[4].gd.flags = gg_enabled|gg_visible;
     775           0 :     gcd[4].gd.u.boxelements = butarray;
     776           0 :     gcd[4].creator = GHBoxCreate;
     777             : 
     778           0 :     gcd[5].gd.pos.x = 0; gcd[5].gd.pos.y = 0;
     779           0 :     gcd[5].gd.pos.width = pos.width; gcd[5].gd.pos.height = pos.height-GDrawPointsToPixels(NULL,40);
     780           0 :     gcd[5].gd.flags = gg_visible|gg_enabled|gg_pos_in_pixels|gg_textarea_wrap|gg_pos_use0;
     781           0 :     gcd[5].creator = GTextAreaCreate;
     782           0 :     gcd[5].data = iv;
     783           0 :     harray[0] = &gcd[5];
     784             : 
     785           0 :     gcd[6].gd.pos.y = 0; gcd[6].gd.pos.height = pos.height-GDrawPointsToPixels(NULL,40);
     786           0 :     gcd[6].gd.pos.width = GDrawPointsToPixels(gw,_GScrollBar_Width);
     787           0 :     gcd[6].gd.pos.x = pos.width-gcd[6].gd.pos.width;
     788           0 :     gcd[6].gd.flags = gg_visible|gg_enabled|gg_pos_in_pixels|gg_sb_vert;
     789           0 :     gcd[6].creator = GScrollBarCreate;
     790           0 :     gcd[6].data = iv;
     791           0 :     harray[1] = &gcd[6]; harray[2] = NULL;
     792             : 
     793           0 :     gcd[7].gd.flags = gg_enabled|gg_visible;
     794           0 :     gcd[7].gd.u.boxelements = harray;
     795           0 :     gcd[7].creator = GHBoxCreate;
     796             : 
     797           0 :     varray[0] = &gcd[7]; varray[1] = NULL;
     798           0 :     varray[2] = &gcd[8]; varray[3] = NULL;
     799           0 :     varray[4] = &gcd[4]; varray[5] = NULL;
     800           0 :     varray[6] = NULL;
     801             : 
     802           0 :     gcd[8].gd.flags = gg_enabled|gg_visible;
     803           0 :     gcd[8].gd.pos.width = 100;
     804           0 :     gcd[8].creator = GLineCreate;
     805             : 
     806           0 :     gcd[9].gd.pos.x = gcd[9].gd.pos.y = 2;
     807           0 :     gcd[9].gd.flags = gg_enabled|gg_visible;
     808           0 :     gcd[9].gd.u.boxelements = varray;
     809           0 :     gcd[9].creator = GHVGroupCreate;
     810             : 
     811           0 :     GGadgetsCreate(gw,&gcd[9]);
     812           0 :     GHVBoxSetExpandableRow(gcd[9].ret,0);
     813           0 :     GHVBoxSetExpandableCol(gcd[7].ret,0);
     814           0 :     GHVBoxSetExpandableCol(gcd[4].ret,gb_expandgluesame);
     815             : 
     816           0 :     iv->ok = gcd[0].ret;
     817           0 :     iv->cancel = gcd[1].ret;
     818           0 :     iv->edit = gcd[2].ret;
     819           0 :     iv->parse = gcd[3].ret;
     820           0 :     iv->text = gcd[5].ret;
     821           0 :     iv->instrinfo.vsb = gcd[6].ret;
     822           0 :     iv->topbox = gcd[9].ret;
     823             : 
     824           0 :     wattrs.mask = wam_events|wam_cursor;
     825           0 :     pos = gcd[5].gd.pos;
     826           0 :     iv->instrinfo.v = GWidgetCreateSubWindow(gw,&pos,ii_v_e_h,&iv->instrinfo,&wattrs);
     827           0 :     GDrawSetVisible(iv->instrinfo.v,true);
     828             : 
     829           0 :     if ( font==NULL ) {
     830           0 :         memset(&rq,0,sizeof(rq));
     831           0 :         rq.utf8_family_name = MONO_UI_FAMILIES;
     832           0 :         rq.point_size = -12;
     833           0 :         rq.weight = 400;
     834           0 :         font = GDrawInstanciateFont(gw,&rq);
     835           0 :         font = GResourceFindFont("TTInstruction.Font",font);
     836             :     }
     837           0 :     iv->instrinfo.gfont = font;
     838           0 :     GDrawSetFont(iv->instrinfo.v,iv->instrinfo.gfont);
     839           0 :     GGadgetSetFont(iv->text,iv->instrinfo.gfont);
     840           0 :     GDrawWindowFontMetrics(iv->instrinfo.v,iv->instrinfo.gfont,&as,&ds,&ld);
     841           0 :     iv->instrinfo.as = as+1;
     842           0 :     iv->instrinfo.fh = iv->instrinfo.as+ds;
     843           0 :     iv->instrinfo.isel_pos = -1;
     844             : 
     845           0 :     lh = iv->instrinfo.lheight;
     846           0 :     if ( lh>40 ) lh = 40;
     847           0 :     if ( lh<4 ) lh = 4;
     848           0 :     GDrawResize(iv->gw,pos.width+gcd[6].gd.pos.width,iv->oc_height+lh*iv->instrinfo.fh+4);
     849             : 
     850           0 :     GDrawSetVisible(gw,true);
     851           0 : }
     852             : 
     853           0 : void SCEditInstructions(SplineChar *sc) {
     854             :     struct instrdata *id;
     855             :     char title[100];
     856             :     CharView *cv;
     857             :     RefChar *ref;
     858             : 
     859             :     /* In a multiple master font, the instructions for all glyphs reside in */
     860             :     /*  the "normal" instance of the font. The instructions are the same for */
     861             :     /*  all instances (the cvt table might be different) */
     862           0 :     if ( sc->parent->mm!=NULL && sc->parent->mm->apple )
     863           0 :         sc = sc->parent->mm->normal->glyphs[sc->orig_pos];
     864             : 
     865           0 :     for ( id = sc->parent->instr_dlgs; id!=NULL && id->sc!=sc; id=id->next );
     866           0 :     if ( id!=NULL ) {
     867           0 :         GDrawSetVisible(id->id->gw,true);
     868           0 :         GDrawRaise(id->id->gw);
     869           0 : return;
     870             :     }
     871             : 
     872           0 :     if ( sc->layers[ly_fore].refs!=NULL && sc->layers[ly_fore].splines!=NULL ) {
     873           0 :         ff_post_error(_("Can't instruct this glyph"),
     874           0 :                 _("TrueType does not support mixed references and contours.\nIf you want instructions for %.30s you should either:\n * Unlink the reference(s)\n * Copy the inline contours into their own (unencoded\n    glyph) and make a reference to that."),
     875             :                 sc->name );
     876           0 : return;
     877             :     }
     878           0 :     for ( ref = sc->layers[ly_fore].refs; ref!=NULL; ref=ref->next ) {
     879           0 :         if ( ref->transform[0]>=2 || ref->transform[0]<-2 ||
     880           0 :                 ref->transform[1]>=2 || ref->transform[1]<-2 ||
     881           0 :                 ref->transform[2]>=2 || ref->transform[2]<-2 ||
     882           0 :                 ref->transform[3]>=2 || ref->transform[3]<-2 )
     883             :     break;
     884             :     }
     885           0 :     if ( ref!=NULL ) {
     886           0 :         ff_post_error(_("Can't instruct this glyph"),
     887           0 :                 _("TrueType does not support references which\nare scaled by more than 200%%.  But %1$.30s\nhas been in %2$.30s. Any instructions\nadded would be meaningless."),
     888           0 :                 ref->sc->name, sc->name );
     889           0 : return;
     890             :     }
     891             : 
     892           0 :     for ( cv=(CharView *) (sc->views); cv!=NULL; cv=(CharView *) (cv->b.next) ) {
     893           0 :         sc = cv->b.sc;
     894           0 :         cv->showpointnumbers = true;
     895           0 :         SCNumberPoints(sc,CVLayer((CharViewBase *) cv));
     896           0 :         GDrawRequestExpose(cv->v,NULL,false);
     897             :     }
     898           0 :     id = calloc(1,sizeof(*id));
     899           0 :     id->instr_cnt = id->max = sc->ttf_instrs_len;
     900           0 :     id->sf = sc->parent;
     901           0 :     id->sc = sc;
     902           0 :     id->instrs = malloc(id->max+1);
     903           0 :     if ( sc->ttf_instrs!=NULL )
     904           0 :         memcpy(id->instrs,sc->ttf_instrs,id->instr_cnt);
     905           0 :     sprintf(title,_("TrueType Instructions for %.50s"),sc->name);
     906           0 :     InstrDlgCreate(id,title);
     907             : }
     908             : 
     909         548 : void SC_MarkInstrDlgAsChanged(SplineChar *sc) {
     910             :     struct instrdata *id;
     911             : 
     912         548 :     for ( id = sc->parent->instr_dlgs; id!=NULL && id->sc!=sc; id=id->next );
     913         548 :     if ( id!=NULL )
     914           0 :         id->changed = true;
     915         548 : }
     916             : 
     917           0 : void IIScrollTo(struct instrinfo *ii,int ip,int mark_stop) {
     918             :     int l, i;
     919             : 
     920           0 :     for ( i=l=0; i<ip && i<ii->instrdata->instr_cnt; ++i, ++l ) {
     921           0 :         if ( ii->instrdata->bts[i]==bt_wordhi || ii->instrdata->bts[i]==bt_wordlo )
     922           0 :             ++i;
     923             :     }
     924           0 :     if ( ip==-1 )
     925           0 :         ii->lstopped = -1;
     926             :     else {
     927           0 :         if ( mark_stop )
     928           0 :             ii->lstopped = l;
     929           0 :         if ( l<ii->lpos || l>=ii->lpos+ii->vheight/ii->fh-1 ) {
     930           0 :             if ( l+ii->vheight/ii->fh-1 >= ii->lheight+1 )
     931           0 :                 l = ii->lheight+2-(ii->vheight/ii->fh);
     932           0 :             if ( l<0 )
     933           0 :                 l = 0;
     934           0 :             ii->lpos = l;
     935           0 :             GScrollBarSetPos(ii->vsb,l);
     936             :         }
     937             :     }
     938           0 :     GDrawRequestExpose(ii->v,NULL,false);
     939           0 : }
     940             : 
     941           0 : void IIReinit(struct instrinfo *ii,int ip) {
     942           0 :     instrhelpsetup();
     943           0 :     free(ii->instrdata->bts);
     944           0 :     ii->instrdata->bts = NULL;
     945           0 :     instr_info_init(ii);
     946           0 :     GScrollBarSetBounds(ii->vsb,0,ii->lheight+2, ii->vheight<ii->fh ? 1 : ii->vheight/ii->fh);
     947           0 :     IIScrollTo(ii,ip,true);
     948           0 : }
     949             : 
     950             : /* ************************************************************************** */
     951             : /* **************************** CVT table editor **************************** */
     952             : /* ************************************************************************** */
     953             : 
     954             : #define ADDR_SPACER     4
     955             : #define EDGE_SPACER     2
     956             : 
     957             : typedef struct shortview /* : tableview */ {
     958             :     struct ttf_table *table;
     959             :     GWindow gw, v;
     960             :     SplineFont *sf;
     961             :     unsigned int destroyed: 1;          /* window has been destroyed */
     962             :     unsigned int changed: 1;
     963             :     GGadget *vsb, *tf;
     964             :     GGadget *ok, *cancel, *setsize;
     965             :     int lpos, lheight;
     966             :     int16 as, fh;
     967             :     int16 vheight, vwidth;
     968             :     int16 sbw, bh;
     969             :     GFont *gfont;
     970             :     int16 chrlen, addrend, valend;
     971             :     int16 active;
     972             :     int16 which;
     973             :     int16 *edits;
     974             :     char **comments;
     975             :     uint8 *data;
     976             :     int32 len;
     977             :     uint32 tag;
     978             : } ShortView;
     979             : 
     980           0 : static int sfinishup(ShortView *sv,int showerr) {
     981           0 :     const unichar_t *ret = _GGadgetGetTitle(sv->tf);
     982             :     unichar_t *end;
     983             :     int val, oldval;
     984             : 
     985           0 :     if ( sv->active==-1 )
     986           0 : return( true );
     987             : 
     988           0 :     if ( sv->which ) {
     989           0 :         if ( *ret=='\0' ) {
     990           0 :             if ( sv->comments[sv->active]!=NULL ) {
     991           0 :                 free(sv->comments[sv->active]);
     992           0 :                 sv->comments[sv->active] = NULL;
     993           0 :                 sv->changed = true;
     994             :             }
     995             :         } else {
     996           0 :             char *new = GGadgetGetTitle8(sv->tf);
     997           0 :             if ( sv->comments[sv->active]==NULL ) {
     998           0 :                 sv->changed = true;
     999             :             } else {
    1000           0 :                 if ( strcmp(sv->comments[sv->active],new)!=0 )
    1001           0 :                     sv->changed = true;
    1002           0 :                 free(sv->comments[sv->active]);
    1003             :             }
    1004           0 :             sv->comments[sv->active] = new;
    1005             :         }
    1006             :     } else {
    1007           0 :         val = u_strtol(ret,&end,10);
    1008           0 :         if ( *ret=='\0' || *end!='\0' || val<-32768 || val>32767 ) {
    1009           0 :             if ( showerr )
    1010           0 :                 ff_post_error(_("Bad Number"),_("Bad Number"));
    1011           0 : return( false );
    1012             :         }
    1013           0 :         oldval = sv->edits[sv->active];
    1014           0 :         if ( val != oldval ) {
    1015           0 :             sv->changed = true;
    1016           0 :             sv->edits[sv->active] = val;
    1017             :         }
    1018             :     }
    1019           0 :     sv->active = -1;
    1020           0 :     GGadgetMove(sv->tf,sv->addrend,-100);
    1021           0 : return( true );
    1022             : }
    1023             : 
    1024           0 : static void SV_SetScrollBar(ShortView *sv) {
    1025             :     int lh;
    1026           0 :     sv->lheight = lh = sv->len/2;
    1027             : 
    1028           0 :     GScrollBarSetBounds(sv->vsb,0,lh,sv->vheight<sv->fh ? 1 : sv->vheight/sv->fh);
    1029           0 :     if ( sv->lpos + sv->vheight/sv->fh > lh ) {
    1030           0 :         int lpos = lh-sv->vheight/sv->fh;
    1031           0 :         if ( lpos<0 ) lpos = 0;
    1032           0 :         if ( sv->lpos!=lpos && sv->active!=-1 )
    1033           0 :             GGadgetMove(sv->tf,sv->addrend,(sv->active-lpos)*sv->fh);
    1034           0 :         sv->lpos = lpos;
    1035             :     }
    1036           0 :     GScrollBarSetPos(sv->vsb,sv->lpos);
    1037           0 : }
    1038             : 
    1039           0 : static int SV_ChangeLength(GGadget *g, GEvent *e) {
    1040           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1041           0 :         ShortView *sv = GDrawGetUserData(GGadgetGetWindow(g));
    1042             :         char buffer[12];
    1043             :         char *ret, *e;
    1044             :         int val,i;
    1045             : 
    1046           0 :         sprintf( buffer, "%d", (int) (sv->len/2) );
    1047           0 :         ret = gwwv_ask_string(_("Change Length"), buffer,_("How many entries should there be in the cvt table?"));
    1048           0 :         if ( ret==NULL )
    1049           0 : return( true );         /* Cancelled */
    1050           0 :         val = strtol(ret,&e,10);
    1051           0 :         if ( *e || val<0 || val>65535 ) {
    1052           0 :             free(ret);
    1053           0 :             ff_post_error(_("Bad Number"),_("Bad Number"));
    1054           0 : return( false );
    1055             :         }
    1056           0 :         free(ret);
    1057           0 :         if ( val*2>sv->len ) {
    1058           0 :             sv->edits = realloc(sv->edits,val*2);
    1059           0 :             for ( i=sv->len/2; i<val; ++i )
    1060           0 :                 sv->edits[i] = 0;
    1061           0 :             sv->comments = realloc(sv->comments,val*sizeof(char *));
    1062           0 :             for ( i=sv->len/2; i<val; ++i )
    1063           0 :                 sv->comments[i] = NULL;
    1064             :         } else {
    1065           0 :             for ( i=val; i<sv->len/2; ++i ) {
    1066           0 :                 free(sv->comments[i]);
    1067           0 :                 sv->comments[i] = NULL;
    1068             :             }
    1069             :         }
    1070           0 :         sv->len = 2*val;
    1071           0 :         SV_SetScrollBar(sv);
    1072           0 :         GDrawRequestExpose(sv->v,NULL,true);
    1073             :     }
    1074           0 : return( true );
    1075             : }
    1076             : 
    1077           0 : static void _SV_DoClose(ShortView *sv) {
    1078             : 
    1079           0 :     sv->destroyed = true;
    1080           0 :     GDrawDestroyWindow(sv->gw);
    1081           0 : }
    1082             : 
    1083           0 : static int SV_Cancel(GGadget *g, GEvent *e) {
    1084           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1085           0 :         ShortView *sv = GDrawGetUserData(GGadgetGetWindow(g));
    1086             : 
    1087           0 :         _SV_DoClose(sv);
    1088             :     }
    1089           0 : return( true );
    1090             : }
    1091             : 
    1092           0 : static int SV_OK(GGadget *g, GEvent *e) {
    1093           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1094           0 :         ShortView *sv = GDrawGetUserData(GGadgetGetWindow(g));
    1095             :         int i;
    1096             :         struct ttf_table *prev, *tab;
    1097           0 :         SplineFont *sf = sv->sf;
    1098             : 
    1099           0 :         if ( !sfinishup(sv,true) )
    1100           0 : return( true );
    1101           0 :         if ( sf->cvt_names!=NULL ) {
    1102           0 :             for ( i=0; sf->cvt_names[i]!=END_CVT_NAMES; ++i )
    1103           0 :                 free(sf->cvt_names[i]);
    1104           0 :             free(sf->cvt_names);
    1105           0 :             sf->cvt_names = NULL;
    1106             :         }
    1107           0 :         if ( sv->len==0 ) {
    1108           0 :             if ( sv->table!=NULL ) {
    1109           0 :                 prev = NULL;
    1110           0 :                 for ( tab=sf->ttf_tables; tab!=NULL && tab!=sv->table; prev=tab, tab=tab->next );
    1111           0 :                 if ( prev!=NULL )
    1112           0 :                     prev->next = tab->next;
    1113             :                 else
    1114           0 :                     sf->ttf_tables = tab->next;
    1115           0 :                 free(sv->table->data);
    1116           0 :                 chunkfree(sv->table,sizeof(struct ttf_table));
    1117           0 :                 sv->table = NULL;
    1118             :             }
    1119             :         } else {
    1120           0 :             if ( sv->table!=NULL )
    1121           0 :                 free(sv->table->data);
    1122             :             else {
    1123           0 :                 tab = chunkalloc(sizeof(struct ttf_table));
    1124           0 :                 tab->next = sf->ttf_tables;
    1125           0 :                 sf->ttf_tables = tab;
    1126           0 :                 tab->tag = sv->tag;
    1127           0 :                 sv->table = tab;
    1128             :             }
    1129           0 :             sv->table->data = malloc(sv->len);
    1130           0 :             sf->cvt_names = malloc(((sv->len>>1)+1)*sizeof(char *));
    1131           0 :             for ( i=0; i<sv->len/2; ++i ) {
    1132           0 :                 sv->table->data[i<<1] = (sv->edits[i]>>8)&0xff;
    1133           0 :                 sv->table->data[(i<<1)+1] = sv->edits[i]&0xff;
    1134           0 :                 sf->cvt_names[i] = sv->comments[i];
    1135           0 :                 sv->comments[i] = NULL;
    1136             :             }
    1137           0 :             sf->cvt_names[i] = END_CVT_NAMES;
    1138           0 :             sv->table->len = sv->len;
    1139             :         }
    1140           0 :         sf->changed = true;
    1141           0 :         _SV_DoClose(sv);
    1142             :     }
    1143           0 : return( true );
    1144             : }
    1145             : 
    1146           0 : static void short_resize(ShortView *sv,GEvent *event) {
    1147             :     GRect pos, gsize;
    1148             :     int width;
    1149             : 
    1150             :     /* height must be a multiple of the line height */
    1151           0 :     if ( (event->u.resize.size.height-2*EDGE_SPACER-sv->bh)%sv->fh!=0 ||
    1152           0 :             (event->u.resize.size.height-2*EDGE_SPACER-sv->fh-sv->bh)<0 ) {
    1153           0 :         int lc = (event->u.resize.size.height+sv->fh/2-EDGE_SPACER)/sv->fh;
    1154           0 :         if ( lc<=0 ) lc = 1;
    1155           0 :         GDrawResize(sv->gw, event->u.resize.size.width,
    1156           0 :                 lc*sv->fh+2*EDGE_SPACER+sv->bh);
    1157           0 : return;
    1158             :     }
    1159             : 
    1160           0 :     pos.width = GDrawPointsToPixels(sv->gw,_GScrollBar_Width);
    1161           0 :     pos.height = event->u.resize.size.height-sv->bh-sv->fh;
    1162           0 :     pos.x = event->u.resize.size.width-pos.width; pos.y = sv->fh;
    1163           0 :     GGadgetResize(sv->vsb,pos.width,pos.height+1);
    1164           0 :     GGadgetMove(sv->vsb,pos.x,pos.y);
    1165           0 :     pos.width = pos.x; pos.x = 0;
    1166           0 :     GDrawResize(sv->v,pos.width,pos.height);
    1167           0 :     GDrawMove(sv->v,0,sv->fh);
    1168             : 
    1169           0 :     sv->vheight = pos.height; sv->vwidth = pos.width;
    1170           0 :     SV_SetScrollBar(sv);
    1171             : 
    1172           0 :     width = pos.width-sv->addrend;
    1173           0 :     if ( width < 5 ) width = 5;
    1174           0 :     GGadgetResize(sv->tf,width,sv->fh);
    1175             : 
    1176           0 :     GGadgetGetSize(sv->ok,&gsize);
    1177           0 :     GGadgetMove(sv->ok,gsize.x,event->u.resize.size.height-GDrawPointsToPixels(sv->gw,33));
    1178           0 :     GGadgetMove(sv->cancel,event->u.resize.size.width-gsize.x-gsize.width,event->u.resize.size.height-GDrawPointsToPixels(sv->gw,30));
    1179           0 :     GGadgetGetSize(sv->setsize,&gsize);
    1180           0 :     GGadgetMove(sv->setsize,(event->u.resize.size.width-gsize.width)/2,
    1181           0 :             event->u.resize.size.height-GDrawPointsToPixels(sv->gw,60));
    1182             :     
    1183           0 :     GDrawRequestExpose(sv->gw,NULL,true);
    1184             : }
    1185             : 
    1186           0 : static void short_expose(ShortView *sv,GWindow pixmap,GRect *rect) {
    1187             :     int low, high;
    1188             :     int x,y;
    1189             :     char cval[8], caddr[8];
    1190             :     int index;
    1191             : 
    1192           0 :     GDrawSetFont(pixmap,sv->gfont);
    1193             : 
    1194           0 :     low = ( (rect->y-EDGE_SPACER)/sv->fh ) * sv->fh + EDGE_SPACER;
    1195           0 :     high = ( (rect->y+rect->height+sv->fh-1-EDGE_SPACER)/sv->fh ) * sv->fh +EDGE_SPACER;
    1196           0 :     if ( high>sv->vheight-EDGE_SPACER ) high = sv->vheight-EDGE_SPACER;
    1197             : 
    1198           0 :     GDrawDrawLine(pixmap,sv->addrend-ADDR_SPACER/2,rect->y,sv->addrend-ADDR_SPACER/2,rect->y+rect->height,0x000000);
    1199           0 :     GDrawDrawLine(pixmap,sv->valend-ADDR_SPACER/2,rect->y,sv->valend-ADDR_SPACER/2,rect->y+rect->height,0x000000);
    1200             : 
    1201           0 :     index = (sv->lpos+(low-EDGE_SPACER)/sv->fh);
    1202           0 :     y = low;
    1203           0 :     for ( ; y<=high && index<sv->len/2; ++index ) {
    1204           0 :         sprintf( caddr, "%d", index );
    1205           0 :         x = sv->addrend - ADDR_SPACER - GDrawGetText8Width(pixmap,caddr,-1);
    1206           0 :         GDrawDrawText8(pixmap,x,y+sv->as,caddr,-1,MAIN_FOREGROUND);
    1207             : 
    1208           0 :         sprintf( cval, "%d", sv->edits[index] );
    1209           0 :         GDrawDrawText8(pixmap,sv->addrend,y+sv->as,cval,-1,MAIN_FOREGROUND);
    1210             : 
    1211           0 :         if ( sv->comments[index]!=NULL )
    1212           0 :             GDrawDrawText8(pixmap,sv->valend,y+sv->as,sv->comments[index],-1,MAIN_FOREGROUND);
    1213           0 :         y += sv->fh;
    1214             :     }
    1215           0 : }
    1216             : 
    1217           0 : static void short_mousemove(ShortView *sv,int pos) {
    1218             :     /*GGadgetPreparePopup(sv->gw,msg);*/
    1219           0 : }
    1220             : 
    1221           0 : static void short_scroll(ShortView *sv,struct sbevent *sb) {
    1222           0 :     int newpos = sv->lpos;
    1223             : 
    1224           0 :     switch( sb->type ) {
    1225             :       case et_sb_top:
    1226           0 :         newpos = 0;
    1227           0 :       break;
    1228             :       case et_sb_uppage:
    1229           0 :         newpos -= sv->vheight/sv->fh;
    1230           0 :       break;
    1231             :       case et_sb_up:
    1232           0 :         --newpos;
    1233           0 :       break;
    1234             :       case et_sb_down:
    1235           0 :         ++newpos;
    1236           0 :       break;
    1237             :       case et_sb_downpage:
    1238           0 :         newpos += sv->vheight/sv->fh;
    1239           0 :       break;
    1240             :       case et_sb_bottom:
    1241           0 :         newpos = sv->lheight-sv->vheight/sv->fh;
    1242           0 :       break;
    1243             :       case et_sb_thumb:
    1244             :       case et_sb_thumbrelease:
    1245           0 :         newpos = sb->pos;
    1246           0 :       break;
    1247             :     }
    1248           0 :     if ( newpos>sv->lheight-sv->vheight/sv->fh )
    1249           0 :         newpos = sv->lheight-sv->vheight/sv->fh;
    1250           0 :     if ( newpos<0 ) newpos =0;
    1251           0 :     if ( newpos!=sv->lpos ) {
    1252           0 :         int diff = newpos-sv->lpos;
    1253           0 :         sv->lpos = newpos;
    1254           0 :         GScrollBarSetPos(sv->vsb,sv->lpos);
    1255           0 :         if ( sv->active!=-1 ) {
    1256             :             GRect pos;
    1257           0 :             GGadgetGetSize(sv->tf,&pos);
    1258           0 :             GGadgetMove(sv->tf,sv->addrend,pos.y+diff*sv->fh);
    1259             :         }
    1260           0 :         GDrawScroll(sv->v,NULL,0,diff*sv->fh);
    1261             :     }
    1262           0 : }
    1263             : 
    1264           0 : static void ShortViewFree(ShortView *sv) {
    1265           0 :     sv->sf->cvt_dlg = NULL;
    1266           0 :     free(sv->edits);
    1267           0 :     free(sv);
    1268           0 : }
    1269             : 
    1270           0 : static int sv_v_e_h(GWindow gw, GEvent *event) {
    1271           0 :     ShortView *sv = (ShortView *) GDrawGetUserData(gw);
    1272             : 
    1273           0 :     switch ( event->type ) {
    1274             :       case et_expose:
    1275           0 :         short_expose(sv,gw,&event->u.expose.rect);
    1276           0 :       break;
    1277             :       case et_char:
    1278           0 :         if ( event->u.chr.keysym == GK_Help || event->u.chr.keysym == GK_F1 )
    1279           0 :             help("ttfinstrs.html#cvt");
    1280           0 :       break;
    1281             :       case et_mousemove: case et_mousedown: case et_mouseup:
    1282           0 :         GGadgetEndPopup();
    1283           0 :         if ( event->type==et_mousemove )
    1284           0 :             short_mousemove(sv,event->u.mouse.y);
    1285           0 :         else if ( event->type == et_mousedown ) {
    1286           0 :             int l = (event->u.mouse.y-EDGE_SPACER)/sv->fh + sv->lpos;
    1287           0 :             int which = event->u.mouse.x > sv->valend;
    1288             :             char buf[20];
    1289           0 :             int old = sv->active;
    1290           0 :             if ( sfinishup(sv,true) && event->u.mouse.x>sv->addrend &&
    1291           0 :                     l<sv->len/2 && l!=old ) {
    1292           0 :                 sv->active = l;
    1293           0 :                 sv->which = which;
    1294           0 :                 if ( !which ) {
    1295             :                     /* Change the value */
    1296           0 :                     GGadgetResize(sv->tf,sv->valend-sv->addrend-EDGE_SPACER,sv->fh);
    1297           0 :                     GGadgetMove(sv->tf, sv->addrend,
    1298           0 :                                             (l-sv->lpos)*sv->fh+EDGE_SPACER+1);
    1299           0 :                     sprintf( buf, "%d", sv->edits[sv->active] );
    1300           0 :                     GGadgetSetTitle8(sv->tf,buf);
    1301             :                 } else {
    1302           0 :                     GGadgetResize(sv->tf,sv->vwidth-sv->valend-EDGE_SPACER,sv->fh);
    1303           0 :                     GGadgetMove(sv->tf, sv->valend,
    1304           0 :                                             (l-sv->lpos)*sv->fh+EDGE_SPACER+1);
    1305           0 :                     GGadgetSetTitle8(sv->tf,sv->comments[l]==NULL?"":sv->comments[l]);
    1306             :                 }
    1307           0 :                 GDrawRequestExpose(sv->v,NULL,true);
    1308           0 :                 GDrawPostEvent(event);  /* And we hope the tf catches it this time */
    1309             :             }
    1310             :         }
    1311           0 :       break;
    1312             :       case et_resize:
    1313           0 :         GDrawRequestExpose(gw,NULL,true);
    1314           0 :       break;
    1315             :       case et_timer:
    1316           0 :       break;
    1317             :       case et_focus:
    1318           0 :       break;
    1319             :     }
    1320           0 : return( true );
    1321             : }
    1322             : 
    1323           0 : static int sv_e_h(GWindow gw, GEvent *event) {
    1324           0 :     ShortView *sv = (ShortView *) GDrawGetUserData(gw);
    1325             :     GRect r;
    1326             :     int x;
    1327             : 
    1328           0 :     switch ( event->type ) {
    1329             :       case et_expose:
    1330           0 :         r.x = r.y = 0; r.width = sv->vwidth+40; r.height = sv->fh-1;
    1331           0 :         GDrawFillRect(gw,&r,0x808080);
    1332           0 :         GDrawSetFont(gw,sv->gfont);
    1333           0 :         x = sv->addrend - ADDR_SPACER - 2 - GDrawGetText8Width(gw,_("Index"),-1);
    1334           0 :         GDrawDrawText8(gw,x,sv->as,_("Index"),-1,0xffffff);
    1335           0 :         GDrawDrawText8(gw,sv->addrend,sv->as,_("Value"),-1,0xffffff);
    1336           0 :         GDrawDrawText8(gw,sv->valend,sv->as,_("Comment"),-1,0xffffff);
    1337             :         
    1338           0 :         GDrawDrawLine(gw,0,sv->fh-1,r.width,sv->fh-1,0x000000);
    1339           0 :         GDrawDrawLine(gw,0,sv->vheight+sv->fh,sv->vwidth,sv->vheight+sv->fh,0x000000);
    1340           0 :       break;
    1341             :       case et_resize:
    1342           0 :         short_resize(sv,event);
    1343           0 :       break;
    1344             :       case et_char:
    1345           0 :         if ( event->u.chr.keysym == GK_Help || event->u.chr.keysym == GK_F1 )
    1346           0 :             help("ttfinstrs.html#cvt");
    1347           0 :       break;
    1348             :       case et_controlevent:
    1349           0 :         switch ( event->u.control.subtype ) {
    1350             :           case et_scrollbarchange:
    1351           0 :             short_scroll(sv,&event->u.control.u.sb);
    1352           0 :           break;
    1353             :         }
    1354           0 :       break;
    1355             :       case et_close:
    1356           0 :         _SV_DoClose(sv);
    1357           0 :       break;
    1358             :       case et_destroy:
    1359           0 :         ShortViewFree(sv);
    1360           0 :       break;
    1361             :     }
    1362           0 : return( true );
    1363             : }
    1364             : 
    1365             : /* cvt table */
    1366           0 : static void cvtCreateEditor(struct ttf_table *tab,SplineFont *sf,uint32 tag) {
    1367           0 :     ShortView *sv = calloc(1,sizeof(ShortView));
    1368             :     char title[60];
    1369             :     GRect pos, subpos, gsize;
    1370             :     GWindow gw;
    1371             :     GWindowAttrs wattrs;
    1372             :     FontRequest rq;
    1373             :     int as,ds,ld, lh;
    1374             :     GGadgetCreateData gcd[9], *butarray[8], *harray[4], *harray2[3], *varray[7];
    1375             :     GTextInfo label[5], lab;
    1376             :     GGadgetData gd;
    1377             :     static unichar_t num[] = { '0',  '\0' };
    1378             :     int numlen;
    1379             :     static GBox tfbox;
    1380             :     int i;
    1381             :     static GFont *font = NULL;
    1382             : 
    1383           0 :     sv->table = tab;
    1384           0 :     sv->sf = sf;
    1385           0 :     sf->cvt_dlg = sv;
    1386           0 :     sv->tag = tag;
    1387             : 
    1388           0 :     if ( tab==NULL && sf->mm!=NULL && sf->mm->apple )
    1389           0 :         tab = SFFindTable(sf->mm->normal,tag);
    1390           0 :     if ( tab!=NULL ) {
    1391           0 :         sv->len = tab->len;
    1392           0 :         sv->edits = malloc(tab->len+1);
    1393           0 :         sv->comments = calloc((tab->len/2+1),sizeof(char *));
    1394           0 :         for ( i=0; i<tab->len/2; ++i )
    1395           0 :             sv->edits[i] = (tab->data[i<<1]<<8) | tab->data[(i<<1)+1];
    1396           0 :         if ( sf->cvt_names!=NULL )
    1397           0 :             for ( i=0; i<tab->len/2 && sf->cvt_names[i]!=END_CVT_NAMES; ++i )
    1398           0 :                 sv->comments[i] = copy(sf->cvt_names[i]);
    1399             :     } else {
    1400           0 :         sv->edits = malloc(2);
    1401           0 :         sv->len = 0;
    1402           0 :         sv->comments = calloc(1,sizeof(char *));
    1403             :     }
    1404             : 
    1405           0 :     title[0] = (tag>>24)&0xff;
    1406           0 :     title[1] = (tag>>16)&0xff;
    1407           0 :     title[2] = (tag>>8 )&0xff;
    1408           0 :     title[3] = (tag    )&0xff;
    1409           0 :     title[4] = ' ';
    1410           0 :     strncpy(title+5, sf->fontname, sizeof(title)/sizeof(title[0])-6);
    1411             : 
    1412           0 :     memset(&wattrs,0,sizeof(wattrs));
    1413           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_icon;
    1414           0 :     wattrs.event_masks = ~(1<<et_charup);
    1415           0 :     wattrs.undercursor = 1;
    1416           0 :     wattrs.cursor = ct_pointer;
    1417           0 :     wattrs.utf8_window_title = title;
    1418           0 :     wattrs.icon = ttf_icon;
    1419           0 :     pos.x = pos.y = 0;
    1420           0 :     if ( GIntGetResource(_NUM_Buttonsize)>60 )
    1421           0 :         pos.width = GDrawPointsToPixels(NULL,2*GIntGetResource(_NUM_Buttonsize)+30);
    1422             :     else
    1423           0 :         pos.width = GDrawPointsToPixels(NULL,150);
    1424           0 :     pos.height = GDrawPointsToPixels(NULL,200);
    1425           0 :     sv->gw = gw = GDrawCreateTopWindow(NULL,&pos,sv_e_h,sv,&wattrs);
    1426             : 
    1427           0 :     memset(&gcd,0,sizeof(gcd));
    1428           0 :     memset(&label,0,sizeof(label));
    1429             : 
    1430           0 :     gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 105;
    1431           0 :     gcd[0].gd.pos.width = -1;
    1432           0 :     label[0].text = (unichar_t *) _("_OK");
    1433           0 :     label[0].text_is_1byte = true;
    1434           0 :     label[0].text_in_resource = true;
    1435           0 :     gcd[0].gd.label = &label[0];
    1436           0 :     gcd[0].gd.flags = gg_visible|gg_enabled|gg_but_default;
    1437           0 :     gcd[0].creator = GButtonCreate;
    1438           0 :     gcd[0].data = sv;
    1439           0 :     gcd[0].gd.handle_controlevent = SV_OK;
    1440             : 
    1441           0 :     gcd[1].gd.pos.x = -8; gcd[1].gd.pos.y = 3;
    1442           0 :     gcd[1].gd.pos.width = -1;
    1443           0 :     label[1].text = (unichar_t *) _("_Cancel");
    1444           0 :     label[1].text_is_1byte = true;
    1445           0 :     label[1].text_in_resource = true;
    1446           0 :     gcd[1].gd.label = &label[1];
    1447           0 :     gcd[1].gd.flags = gg_visible|gg_enabled|gg_but_cancel;
    1448           0 :     gcd[1].creator = GButtonCreate;
    1449           0 :     gcd[1].data = sv;
    1450           0 :     gcd[1].gd.handle_controlevent = SV_Cancel;
    1451             : 
    1452           0 :     gcd[2] = gcd[1];
    1453           0 :     label[2].text = (unichar_t *) _("Change Length");
    1454           0 :     label[2].text_is_1byte = true;
    1455           0 :     label[2].text_in_resource = true;
    1456           0 :     gcd[2].gd.flags = gg_visible|gg_enabled;
    1457           0 :     gcd[2].gd.label = &label[2];
    1458           0 :     gcd[2].creator = GButtonCreate;
    1459           0 :     gcd[2].data = sv;
    1460           0 :     gcd[2].gd.handle_controlevent = SV_ChangeLength;
    1461             : 
    1462           0 :     butarray[0] = GCD_Glue; butarray[1] = &gcd[0]; butarray[2] = GCD_Glue; 
    1463           0 :     butarray[3] = GCD_Glue; butarray[4] = &gcd[1]; butarray[5] = GCD_Glue;
    1464           0 :     butarray[6] = NULL;
    1465             : 
    1466           0 :     harray[0] = GCD_Glue; harray[1] = &gcd[2]; harray[2] = GCD_Glue;
    1467           0 :     harray[3] = NULL;
    1468             : 
    1469           0 :     gcd[3].gd.flags = gg_enabled|gg_visible;
    1470           0 :     gcd[3].gd.u.boxelements = butarray;
    1471           0 :     gcd[3].creator = GHBoxCreate;
    1472             : 
    1473           0 :     gcd[4].gd.flags = gg_enabled|gg_visible;
    1474           0 :     gcd[4].gd.u.boxelements = harray;
    1475           0 :     gcd[4].creator = GHBoxCreate;
    1476             : 
    1477           0 :     sv->bh = GDrawPointsToPixels(gw,64);
    1478             : 
    1479           0 :     gcd[5].gd.pos.y = sv->fh; gcd[5].gd.pos.height = pos.height-sv->bh;
    1480           0 :     gcd[5].gd.pos.width = GDrawPointsToPixels(gw,_GScrollBar_Width);
    1481           0 :     gcd[5].gd.pos.x = pos.width-gcd[5].gd.pos.width;
    1482           0 :     gcd[5].gd.flags = gg_visible|gg_enabled|gg_pos_in_pixels|gg_sb_vert;
    1483           0 :     gcd[5].gd.handle_controlevent = NULL;
    1484           0 :     gcd[5].creator = GScrollBarCreate;
    1485           0 :     gcd[5].data = sv;
    1486           0 :     harray2[0] = GCD_Glue; harray2[1] = &gcd[5]; harray2[2] = NULL;
    1487             : 
    1488           0 :     gcd[6].gd.flags = gg_enabled|gg_visible;
    1489           0 :     gcd[6].gd.u.boxelements = harray2;
    1490           0 :     gcd[6].creator = GHBoxCreate;
    1491             : 
    1492           0 :     varray[0] = &gcd[6]; varray[1] = NULL;
    1493           0 :     varray[2] = &gcd[4]; varray[3] = NULL;
    1494           0 :     varray[4] = &gcd[3]; varray[5] = NULL;
    1495           0 :     varray[6] = NULL;
    1496             : 
    1497             :     /*gcd[7].gd.pos.x = gcd[7].gd.pos.y = 2;*/
    1498           0 :     gcd[7].gd.flags = gg_enabled|gg_visible;
    1499           0 :     gcd[7].gd.u.boxelements = varray;
    1500           0 :     gcd[7].creator = GHVBoxCreate;
    1501             : 
    1502           0 :     GGadgetsCreate(gw,&gcd[7]);
    1503           0 :     GHVBoxSetExpandableRow(gcd[7].ret,0);
    1504           0 :     GHVBoxSetExpandableCol(gcd[6].ret,0);
    1505           0 :     GHVBoxSetExpandableCol(gcd[3].ret,gb_expandgluesame);
    1506           0 :     GHVBoxSetExpandableCol(gcd[4].ret,gb_expandglue);
    1507             : 
    1508           0 :     sv->vsb = gcd[5].ret;
    1509           0 :     sv->ok = gcd[0].ret;
    1510           0 :     sv->cancel = gcd[1].ret;
    1511           0 :     sv->setsize = gcd[2].ret;
    1512           0 :     GGadgetGetSize(sv->vsb,&gsize);
    1513           0 :     sv->sbw = gsize.width;
    1514             : 
    1515           0 :     wattrs.mask = wam_events|wam_cursor;
    1516           0 :     subpos.x = 0; subpos.y = sv->fh;
    1517           0 :     subpos.width = 100; subpos.height = pos.height - sv->bh - sv->fh;
    1518           0 :     sv->v = GWidgetCreateSubWindow(gw,&subpos,sv_v_e_h,sv,&wattrs);
    1519           0 :     GDrawSetVisible(sv->v,true);
    1520             : 
    1521           0 :     if ( font==NULL ) {
    1522           0 :         memset(&rq,0,sizeof(rq));
    1523           0 :         rq.utf8_family_name = MONO_UI_FAMILIES;
    1524           0 :         rq.point_size = -12;
    1525           0 :         rq.weight = 400;
    1526           0 :         font = GDrawInstanciateFont(gw,&rq);
    1527           0 :         font = GResourceFindFont("CVT.Font",font);
    1528             :     }
    1529           0 :     sv->gfont = font;
    1530           0 :     GDrawSetFont(sv->v,sv->gfont);
    1531           0 :     GDrawSetFont(sv->gw,sv->gfont);
    1532           0 :     GDrawWindowFontMetrics(sv->gw,sv->gfont,&as,&ds,&ld);
    1533           0 :     sv->as = as+1;
    1534           0 :     sv->fh = sv->as+ds;
    1535             : 
    1536           0 :     sv->chrlen = numlen = GDrawGetTextWidth(sv->v,num,1);
    1537           0 :     sv->addrend = 6*numlen + ADDR_SPACER + EDGE_SPACER;
    1538           0 :     sv->valend = sv->addrend + 7*numlen + ADDR_SPACER + EDGE_SPACER;
    1539             : 
    1540           0 :     tfbox.main_background = tfbox.main_foreground = COLOR_DEFAULT;
    1541           0 :     memset(&gd,0,sizeof(gd));
    1542           0 :     gd.pos.y = -100; gd.pos.height = sv->fh;
    1543           0 :     gd.pos.x = sv->addrend;
    1544           0 :     memset(&lab,'\0',sizeof(lab));
    1545           0 :     lab.text = num+1;
    1546           0 :     lab.font = sv->gfont;
    1547           0 :     gd.label = &lab;
    1548           0 :     gd.box = &tfbox;
    1549           0 :     gd.flags = gg_visible|gg_enabled|gg_sb_vert|gg_dontcopybox;
    1550           0 :     sv->tf = GTextFieldCreate(sv->v,&gd,NULL);
    1551           0 :     sv->active = -1;
    1552             : 
    1553           0 :     lh = sv->len/2;
    1554           0 :     if ( lh>40 ) lh = 40;
    1555           0 :     if ( lh<4 ) lh = 4;
    1556           0 :     if ( pos.width<sv->valend+6*numlen+EDGE_SPACER+sv->sbw )
    1557           0 :         pos.width = sv->valend+6*numlen+EDGE_SPACER+sv->sbw;
    1558           0 :     GDrawResize(sv->gw,pos.width,lh*sv->fh+2*EDGE_SPACER);
    1559             : 
    1560           0 :     GDrawSetVisible(gw,true);
    1561           0 : }
    1562             : 
    1563           1 : int SF_CloseAllInstrs(SplineFont *sf) {
    1564             :     struct instrdata *id, *next;
    1565             :     int changed;
    1566             :     char name[12], *npt;
    1567             :     static char *buts[3];
    1568             :     static int done = false;
    1569             : 
    1570           1 :     if ( !done ) {
    1571           1 :         buts[0] = _("_OK");
    1572           1 :         buts[1] = _("_Cancel");
    1573           1 :         done = true;
    1574             :     }
    1575             : 
    1576           1 :     for ( id = sf->instr_dlgs; id!=NULL; id=next ) {
    1577           0 :         next = id->next;
    1578           0 :         changed = id->changed;
    1579           0 :         if ( !changed && id->id->inedit ) {
    1580           0 :             if ( !IVParse(id->id))
    1581           0 :                 changed = true;
    1582             :             else
    1583           0 :                 changed = id->changed;
    1584             :         }
    1585           0 :         if ( changed ) {
    1586           0 :             if ( id->tag==0 )
    1587           0 :                 npt = id->sc->name;
    1588             :             else {
    1589           0 :                 name[0] = name[5] = '\'';
    1590           0 :                 name[1] = id->tag>>24; name[2] = (id->tag>>16)&0xff; name[3] = (id->tag>>8)&0xff; name[4] = id->tag&0xff;
    1591           0 :                 name[6] = 0;
    1592           0 :                 npt = name;
    1593             :             }
    1594           0 :             GDrawRaise(id->id->gw);
    1595           0 :             if ( gwwv_ask(_("Instructions were changed"),(const char **) buts,0,1,_("The instructions for %.80s have changed. Do you want to lose those changes?"),npt)==1 )
    1596           0 : return( false );
    1597             :         }
    1598           0 :         GDrawDestroyWindow(id->id->gw);
    1599             :     }
    1600           1 :     if ( sf->cvt_dlg!=NULL ) {
    1601           0 :         if ( sf->cvt_dlg->changed ) {
    1602           0 :             name[0] = name[5] = '\'';
    1603           0 :             name[1] = id->tag>>24; name[2] = (id->tag>>16)&0xff; name[3] = (id->tag>>8)&0xff; name[4] = id->tag&0xff;
    1604           0 :             name[6] = 0;
    1605           0 :             npt = name;
    1606           0 :             GDrawRaise(sf->cvt_dlg->gw);
    1607           0 :             if ( gwwv_ask(_("Instructions were changed"),(const char **) buts,0,1,_("The instructions for %.80s have changed. Do you want to lose those changes?"),npt)==1 )
    1608           0 : return( false );
    1609             :         }
    1610           0 :         GDrawDestroyWindow(sf->cvt_dlg->gw);
    1611             :     }
    1612           1 :     if ( !no_windowing_ui ) {
    1613           0 :         GDrawSync(NULL);
    1614           0 :         GDrawProcessPendingEvents(NULL);
    1615             :     }
    1616           1 : return( true );
    1617             : }
    1618             : 
    1619             : /* Maxp table editor (or that subset of it that ff can't figure out) */
    1620             : struct maxp_data {
    1621             :     GWindow gw;
    1622             :     SplineFont *sf;
    1623             :     struct ttf_table *tab;
    1624             :     int done;
    1625             : };
    1626             : 
    1627             : #define CID_Zones       1006
    1628             : #define CID_TPoints     1007
    1629             : #define CID_Storage     1008
    1630             : #define CID_FDefs       1009
    1631             : #define CID_IDefs       1010
    1632             : #define CID_SEl         1011
    1633             : 
    1634           0 : static void MP_DoClose(struct maxp_data *mp) {
    1635           0 :     mp->done = true;
    1636           0 : }
    1637             : 
    1638           0 : static int Maxp_Cancel(GGadget *g, GEvent *e) {
    1639             : 
    1640           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1641           0 :         MP_DoClose(GDrawGetUserData(GGadgetGetWindow(g)));
    1642             :     }
    1643           0 : return( true );
    1644             : }
    1645             : 
    1646           0 : static int Maxp_OK(GGadget *g, GEvent *e) {
    1647             :     struct maxp_data *mp;
    1648           0 :     int zones, tp, store, stack, fd, id, err=0;
    1649             : 
    1650           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1651           0 :         mp = GDrawGetUserData(GGadgetGetWindow(g));
    1652           0 :         zones = GetInt8(mp->gw,CID_Zones,_("Zones"),&err);
    1653           0 :         tp = GetInt8(mp->gw,CID_TPoints,_("Twilight Zone Point Count"),&err);
    1654           0 :         store = GetInt8(mp->gw,CID_Storage,_("Storage"),&err);
    1655           0 :         stack = GetInt8(mp->gw,CID_SEl,_("Max Stack Depth"),&err);
    1656           0 :         fd = GetInt8(mp->gw,CID_FDefs,_("Max # Functions"),&err);
    1657           0 :         id = GetInt8(mp->gw,CID_IDefs,_("Max Instruction Defines"),&err);
    1658           0 :         if ( err )
    1659           0 : return( true );
    1660           0 :         mp->done = true;
    1661           0 :         if ( mp->tab==NULL ) {
    1662           0 :             mp->tab = chunkalloc(sizeof(struct ttf_table));
    1663           0 :             mp->tab->tag = CHR('m','a','x','p');
    1664           0 :             mp->tab->len = 32;
    1665           0 :             mp->tab->data = calloc(32,1);
    1666           0 :             mp->tab->next = mp->sf->ttf_tables;
    1667           0 :             mp->sf->ttf_tables = mp->tab;
    1668           0 :         } else if ( mp->tab->len<32 ) {
    1669           0 :             free(mp->tab->data);
    1670           0 :             mp->tab->len = 32;
    1671           0 :             mp->tab->data = calloc(32,1);
    1672             :         }
    1673           0 :         mp->tab->data[14] = zones>>8; mp->tab->data[15] = zones&0xff;
    1674           0 :         mp->tab->data[16] = tp>>8; mp->tab->data[17] = tp&0xff;
    1675           0 :         mp->tab->data[18] = store>>8; mp->tab->data[19] = store&0xff;
    1676           0 :         mp->tab->data[20] = fd>>8; mp->tab->data[21] = fd&0xff;
    1677           0 :         mp->tab->data[22] = id>>8; mp->tab->data[23] = id&0xff;
    1678           0 :         mp->tab->data[24] = stack>>8; mp->tab->data[25] = stack&0xff;
    1679           0 :         mp->sf->changed = true;
    1680           0 :         mp->done = true;
    1681             :     }
    1682           0 : return( true );
    1683             : }
    1684             : 
    1685           0 : static int mp_e_h(GWindow gw, GEvent *event) {
    1686           0 :     struct maxp_data *mp = (struct maxp_data *) GDrawGetUserData(gw);
    1687             : 
    1688           0 :     switch ( event->type ) {
    1689             :       case et_char:
    1690           0 :         if ( event->u.chr.keysym == GK_Help || event->u.chr.keysym == GK_F1 )
    1691           0 :             help("ttfinstrs.html#maxp");
    1692             :         else
    1693           0 : return( false );
    1694           0 :       break;
    1695             :       case et_close:
    1696           0 :         MP_DoClose(mp);
    1697           0 :       break;
    1698             :     }
    1699           0 : return( true );
    1700             : }
    1701             : 
    1702           0 : static void maxpCreateEditor(struct ttf_table *tab,SplineFont *sf,uint32 tag) {
    1703             :     char title[60];
    1704             :     GRect pos;
    1705             :     GWindow gw;
    1706             :     GWindowAttrs wattrs;
    1707             :     struct maxp_data mp;
    1708             :     GGadgetCreateData gcd[17], boxes[4], *hvarray[16], *butarray[8], *varray[7];
    1709             :     GTextInfo label[17];
    1710             :     uint8 dummy[32], *data;
    1711             :     char buffer[6][20];
    1712             :     int k, hv;
    1713             : 
    1714           0 :     if ( tab==NULL && sf->mm!=NULL && sf->mm->apple ) {
    1715           0 :         sf = sf->mm->normal;
    1716           0 :         tab = SFFindTable(sf,tag);
    1717             :     }
    1718           0 :     memset(&mp,0,sizeof(mp));
    1719           0 :     mp.sf = sf;
    1720           0 :     mp.tab = tab;
    1721           0 :     if ( tab==NULL || tab->len<32 ) {
    1722           0 :         memset(dummy,0,sizeof(dummy));
    1723           0 :         dummy[15]=2;    /* default Zones to 2 */
    1724           0 :         data = dummy;
    1725             :     } else
    1726           0 :         data = tab->data;
    1727             : 
    1728           0 :     title[0] = (tag>>24)&0xff;
    1729           0 :     title[1] = (tag>>16)&0xff;
    1730           0 :     title[2] = (tag>>8 )&0xff;
    1731           0 :     title[3] = (tag    )&0xff;
    1732           0 :     title[4] = ' ';
    1733           0 :     strncpy(title+5, sf->fontname, sizeof(title)-6);
    1734             : 
    1735           0 :     memset(&wattrs,0,sizeof(wattrs));
    1736           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    1737           0 :     wattrs.event_masks = ~(1<<et_charup);
    1738           0 :     wattrs.undercursor = 1;
    1739           0 :     wattrs.cursor = ct_pointer;
    1740           0 :     wattrs.utf8_window_title = title;
    1741           0 :     wattrs.restrict_input_to_me = 1;
    1742           0 :     wattrs.undercursor = 1;
    1743           0 :     wattrs.is_dlg = true;
    1744           0 :     pos.x = pos.y = 0;
    1745           0 :     pos.width = GDrawPointsToPixels(NULL,260);
    1746           0 :     pos.height = GDrawPointsToPixels(NULL,125);
    1747           0 :     mp.gw = gw = GDrawCreateTopWindow(NULL,&pos,mp_e_h,&mp,&wattrs);
    1748             : 
    1749           0 :     memset(label,0,sizeof(label));
    1750           0 :     memset(gcd,0,sizeof(gcd));
    1751           0 :     memset(boxes,0,sizeof(boxes));
    1752             : 
    1753           0 :         k=hv=0;
    1754           0 :         label[k].text = (unichar_t *) _("_Zones:");
    1755           0 :         label[k].text_is_1byte = true;
    1756           0 :         label[k].text_in_resource = true;
    1757           0 :         gcd[k].gd.label = &label[k];
    1758           0 :         gcd[k].gd.pos.x = 5; gcd[k].gd.pos.y = 16; 
    1759           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1760           0 :         gcd[k].gd.cid = CID_Zones+1000;
    1761           0 :         gcd[k++].creator = GLabelCreate;
    1762           0 :         hvarray[hv++] = &gcd[k-1];
    1763             : 
    1764           0 :         sprintf( buffer[0], "%d", (data[14]<<8)|data[14+1] );
    1765           0 :         label[k].text = (unichar_t *) buffer[0];
    1766           0 :         label[k].text_is_1byte = true;
    1767           0 :         gcd[k].gd.label = &label[k];
    1768           0 :         gcd[k].gd.pos.x = 60; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
    1769           0 :         gcd[k].gd.pos.width = 50;
    1770           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1771           0 :         gcd[k].gd.cid = CID_Zones;
    1772           0 :         gcd[k++].creator = GTextFieldCreate;
    1773           0 :         hvarray[hv++] = &gcd[k-1];
    1774             : 
    1775           0 :         label[k].text = (unichar_t *) _("_Twilight Pnt Cnt:");
    1776           0 :         label[k].text_is_1byte = true;
    1777           0 :         label[k].text_in_resource = true;
    1778           0 :         gcd[k].gd.label = &label[k];
    1779           0 :         gcd[k].gd.pos.x = 120; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y; 
    1780           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1781           0 :         gcd[k].gd.cid = CID_TPoints+1000;
    1782           0 :         gcd[k++].creator = GLabelCreate;
    1783           0 :         hvarray[hv++] = &gcd[k-1];
    1784             : 
    1785           0 :         sprintf( buffer[1], "%d", (data[16]<<8)|data[16+1] );
    1786           0 :         label[k].text = (unichar_t *) buffer[1];
    1787           0 :         label[k].text_is_1byte = true;
    1788           0 :         gcd[k].gd.label = &label[k];
    1789           0 :         gcd[k].gd.pos.x = 202; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
    1790           0 :         gcd[k].gd.pos.width = 50;
    1791           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1792           0 :         gcd[k].gd.cid = CID_TPoints;
    1793           0 :         gcd[k++].creator = GTextFieldCreate;
    1794           0 :         hvarray[hv++] = &gcd[k-1]; hvarray[hv++] = NULL;
    1795             : 
    1796           0 :         label[k].text = (unichar_t *) _("St_orage:");
    1797           0 :         label[k].text_in_resource = true;
    1798           0 :         label[k].text_is_1byte = true;
    1799           0 :         gcd[k].gd.label = &label[k];
    1800           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-3].gd.pos.y+24+6; 
    1801           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1802           0 :         gcd[k].gd.cid = CID_Storage;
    1803           0 :         gcd[k++].creator = GLabelCreate;
    1804           0 :         hvarray[hv++] = &gcd[k-1];
    1805             : 
    1806           0 :         sprintf( buffer[2], "%d", (data[18]<<8)|data[18+1] );
    1807           0 :         label[k].text = (unichar_t *) buffer[2];
    1808           0 :         label[k].text_is_1byte = true;
    1809           0 :         gcd[k].gd.label = &label[k];
    1810           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
    1811           0 :         gcd[k].gd.pos.width = 50;
    1812           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1813           0 :         gcd[k].gd.cid = CID_Storage;
    1814           0 :         gcd[k++].creator = GTextFieldCreate;
    1815           0 :         hvarray[hv++] = &gcd[k-1];
    1816             : 
    1817           0 :         label[k].text = (unichar_t *) _("Max _Stack Depth:");
    1818           0 :         label[k].text_in_resource = true;
    1819           0 :         label[k].text_is_1byte = true;
    1820           0 :         gcd[k].gd.label = &label[k];
    1821           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y; 
    1822           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1823           0 :         gcd[k].gd.cid = CID_SEl+1000;
    1824           0 :         gcd[k++].creator = GLabelCreate;
    1825           0 :         hvarray[hv++] = &gcd[k-1];
    1826             : 
    1827           0 :         sprintf( buffer[3], "%d", (data[24]<<8)|data[24+1] );
    1828           0 :         label[k].text = (unichar_t *) buffer[3];
    1829           0 :         label[k].text_is_1byte = true;
    1830           0 :         gcd[k].gd.label = &label[k];
    1831           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
    1832           0 :         gcd[k].gd.pos.width = 50;
    1833           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1834           0 :         gcd[k].gd.cid = CID_SEl;
    1835           0 :         gcd[k++].creator = GTextFieldCreate;
    1836           0 :         hvarray[hv++] = &gcd[k-1]; hvarray[hv++] = NULL;
    1837             : 
    1838           0 :         label[k].text = (unichar_t *) _("_FDEF");
    1839           0 :         label[k].text_in_resource = true;
    1840           0 :         label[k].text_is_1byte = true;
    1841           0 :         gcd[k].gd.label = &label[k];
    1842           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-3].gd.pos.y+24+6; 
    1843           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1844           0 :         gcd[k].gd.cid = CID_FDefs+1000;
    1845           0 :         gcd[k++].creator = GLabelCreate;
    1846           0 :         hvarray[hv++] = &gcd[k-1];
    1847             : 
    1848           0 :         sprintf( buffer[4], "%d", (data[20]<<8)|data[20+1] );
    1849           0 :         label[k].text = (unichar_t *) buffer[4];
    1850           0 :         label[k].text_is_1byte = true;
    1851           0 :         gcd[k].gd.label = &label[k];
    1852           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;  gcd[k].gd.pos.width = 50;
    1853           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1854           0 :         gcd[k].gd.cid = CID_FDefs;
    1855           0 :         gcd[k++].creator = GTextFieldCreate;
    1856           0 :         hvarray[hv++] = &gcd[k-1];
    1857             : 
    1858           0 :         label[k].text = (unichar_t *) _("_IDEFs");
    1859           0 :         label[k].text_in_resource = true;
    1860           0 :         label[k].text_is_1byte = true;
    1861           0 :         gcd[k].gd.label = &label[k];
    1862           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y; 
    1863           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1864           0 :         gcd[k].gd.cid = CID_IDefs+1000;
    1865           0 :         gcd[k++].creator = GLabelCreate;
    1866           0 :         hvarray[hv++] = &gcd[k-1];
    1867             : 
    1868           0 :         sprintf( buffer[5], "%d", (data[22]<<8)|data[22+1] );
    1869           0 :         label[k].text = (unichar_t *) buffer[5];
    1870           0 :         label[k].text_is_1byte = true;
    1871           0 :         gcd[k].gd.label = &label[k];
    1872           0 :         gcd[k].gd.pos.x = gcd[k-4].gd.pos.x; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;  gcd[k].gd.pos.width = 50;
    1873           0 :         gcd[k].gd.flags = gg_enabled|gg_visible;
    1874           0 :         gcd[k].gd.cid = CID_IDefs;
    1875           0 :         gcd[k++].creator = GTextFieldCreate;
    1876           0 :         hvarray[hv++] = &gcd[k-1]; hvarray[hv++] = NULL; hvarray[hv++] = NULL;
    1877             : 
    1878           0 :         boxes[2].gd.flags = gg_enabled|gg_visible;
    1879           0 :         boxes[2].gd.u.boxelements = hvarray;
    1880           0 :         boxes[2].creator = GHVBoxCreate;
    1881           0 :         varray[0] = &boxes[2]; varray[1] = NULL;
    1882           0 :         varray[2] = GCD_Glue; varray[3] = NULL;
    1883             : 
    1884           0 :     gcd[k].gd.pos.x = 20-3; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+35-3;
    1885           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
    1886           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
    1887           0 :     label[k].text = (unichar_t *) _("_OK");
    1888           0 :     label[k].text_in_resource = true;
    1889           0 :     label[k].text_is_1byte = true;
    1890           0 :     gcd[k].gd.label = &label[k];
    1891           0 :     gcd[k].gd.handle_controlevent = Maxp_OK;
    1892           0 :     gcd[k++].creator = GButtonCreate;
    1893           0 :     butarray[0] = GCD_Glue; butarray[1] = &gcd[k-1]; butarray[2] = GCD_Glue;
    1894             : 
    1895           0 :     gcd[k].gd.pos.x = -20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
    1896           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
    1897           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    1898           0 :     label[k].text = (unichar_t *) _("_Cancel");
    1899           0 :     label[k].text_is_1byte = true;
    1900           0 :     label[k].text_in_resource = true;
    1901           0 :     gcd[k].gd.label = &label[k];
    1902           0 :     gcd[k].gd.handle_controlevent = Maxp_Cancel;
    1903           0 :     gcd[k++].creator = GButtonCreate;
    1904           0 :     butarray[3] = GCD_Glue; butarray[4] = &gcd[k-1]; butarray[5] = GCD_Glue;
    1905           0 :     butarray[6] = NULL;
    1906             : 
    1907           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
    1908           0 :     boxes[3].gd.u.boxelements = butarray;
    1909           0 :     boxes[3].creator = GHBoxCreate;
    1910           0 :     varray[4] = &boxes[3]; varray[5] = NULL;
    1911           0 :     varray[6] = NULL;
    1912             : 
    1913           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    1914           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
    1915           0 :     boxes[0].gd.u.boxelements = varray;
    1916           0 :     boxes[0].creator = GHVGroupCreate;
    1917             : 
    1918           0 :     GGadgetsCreate(gw,boxes);
    1919           0 :     GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
    1920           0 :     GHVBoxSetExpandableCol(boxes[3].ret,gb_expandgluesame);
    1921           0 :     GHVBoxFitWindow(boxes[0].ret);
    1922           0 :     GDrawSetVisible(gw,true);
    1923           0 :     while ( !mp.done )
    1924           0 :         GDrawProcessOneEvent(NULL);
    1925           0 :     GDrawDestroyWindow(gw);
    1926           0 : }
    1927             : 
    1928           0 : void SFEditTable(SplineFont *sf, uint32 tag) {
    1929             :     struct instrdata *id;
    1930             :     struct ttf_table *tab;
    1931             :     char name[12];
    1932             :     char title[100];
    1933             : 
    1934             :     /* In multiple master fonts the 'fpgm' and 'prep' tables are stored in the*/
    1935             :     /*  normal instance of the font. The other instances must share it */
    1936             :     /* On the other hand, everyone can have their own cvt table */
    1937           0 :     if ( tag!=CHR('c','v','t',' ') )
    1938           0 :         if ( sf->mm!=NULL && sf->mm->apple )
    1939           0 :             sf = sf->mm->normal;
    1940             : 
    1941           0 :     tab = SFFindTable(sf,tag);
    1942           0 :     if ( tag==CHR('m','a','x','p') ) {
    1943           0 :         maxpCreateEditor(tab,sf,tag);
    1944           0 :     } else if ( tag!=CHR('c','v','t',' ') ) {
    1945           0 :         for ( id = sf->instr_dlgs; id!=NULL && id->tag!=tag; id=id->next );
    1946           0 :         if ( id!=NULL ) {
    1947           0 :             GDrawSetVisible(id->id->gw,true);
    1948           0 :             GDrawRaise(id->id->gw);
    1949           0 : return;
    1950             :         }
    1951             : 
    1952           0 :         id = calloc(1,sizeof(*id));
    1953           0 :         id->sf = sf;
    1954           0 :         id->tag = tag;
    1955           0 :         id->instr_cnt = id->max = tab==NULL ? 0 : tab->len;
    1956           0 :         id->instrs = malloc(id->max+1);
    1957           0 :         if ( tab!=NULL && tab->data!=NULL )
    1958           0 :             memcpy(id->instrs,tab->data,id->instr_cnt);
    1959             :         else
    1960           0 :             id->instrs[0]='\0';
    1961           0 :         name[0] = name[5] = '\'';
    1962           0 :         name[1] = tag>>24; name[2] = (tag>>16)&0xff; name[3] = (tag>>8)&0xff; name[4] = tag&0xff;
    1963           0 :         name[6] = 0;
    1964           0 :         sprintf(title,_("TrueType Instructions for %.50s"),name);
    1965           0 :         InstrDlgCreate(id,title);
    1966             :     } else {
    1967           0 :         if ( sf->cvt_dlg!=NULL ) {
    1968           0 :             GDrawSetVisible(sf->cvt_dlg->gw,true);
    1969           0 :             GDrawRaise(sf->cvt_dlg->gw);
    1970           0 : return;
    1971             :         }
    1972           0 :         cvtCreateEditor(tab,sf,tag);
    1973             :     }
    1974             : }

Generated by: LCOV version 1.10