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

          Line data    Source code
       1             : /* Copyright (C) 2000-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 "lookups.h"
      30             : #include "parsettf.h"
      31             : #include "spiro.h"
      32             : #include "splineorder2.h"
      33             : #include "splineutil.h"
      34             : #include "splineutil2.h"
      35             : #include "tottfgpos.h"
      36             : #include <ustring.h>
      37             : #include <math.h>
      38             : #include <utype.h>
      39             : #include <gkeysym.h>
      40             : #include <dlist.h>
      41             : 
      42             : #define RAD2DEG (180/3.1415926535897932)
      43             : #define TCnt    3
      44             : 
      45             : typedef struct gidata {
      46             :     struct dlistnode ln;
      47             :     CharView *cv;
      48             :     SplineChar *sc;
      49             :     RefChar *rf;
      50             :     ImageList *img;
      51             :     AnchorPoint *ap;
      52             :     SplinePoint *cursp;
      53             :     spiro_cp *curcp;
      54             :     SplinePointList *curspl;
      55             :     SplinePointList *oldstate;
      56             :     AnchorPoint *oldaps;
      57             :     GWindow gw;
      58             :     int done, first, changed;
      59             :     int prevchanged, nextchanged;
      60             :     int normal_start, normal_end;
      61             :     int interp_start, interp_end;
      62             :     GGadgetCreateData* gcd;
      63             :     GGadget *group1ret, *group2ret;
      64             :     int nonmodal;
      65             : } GIData;
      66             : 
      67             : #define CID_BaseX       2001
      68             : #define CID_BaseY       2002
      69             : #define CID_NextXOff    2003
      70             : #define CID_NextYOff    2004
      71             : #define CID_NextPos     2005
      72             : #define CID_PrevXOff    2006
      73             : #define CID_PrevYOff    2007
      74             : #define CID_PrevPos     2008
      75             : #define CID_NextDef     2009
      76             : #define CID_PrevDef     2010
      77             : #define CID_NextR       2014
      78             : #define CID_NextTheta   2015
      79             : #define CID_PrevR       2016
      80             : #define CID_PrevTheta   2017
      81             : #define CID_HintMask    2020
      82             : #define CID_ActiveHints 2030
      83             : #define CID_NextX       2031
      84             : #define CID_NextY       2032
      85             : #define CID_PrevX       2033
      86             : #define CID_PrevY       2034
      87             : #define CID_BasePos     2035
      88             : #define CID_Normal      2036
      89             : #define CID_Interpolated 2037
      90             : #define CID_NeverInterpolate    2038
      91             : /* Also use CID_Next, CID_Prev below */
      92             : #define CID_NextC       2041
      93             : #define CID_PrevC       2042
      94             : #define CID_PrevCurvature       2043
      95             : #define CID_NextCurvature       2044
      96             : #define CID_DeltaCurvature      2045
      97             : #define CID_Curve       2050            /* Next four must be in order */
      98             : #define CID_Corner      2051
      99             : #define CID_Tangent     2052
     100             : #define CID_HVCurve     2053
     101             : #define CID_SpiroLeft   2054
     102             : #define CID_SpiroRight  2055
     103             : #define CID_TabSet      2100
     104             : 
     105             : #define CID_X           3001
     106             : #define CID_Y           3002
     107             : #define CID_NameList    3003
     108             : #define CID_Mark        3004
     109             : #define CID_BaseChar    3005
     110             : #define CID_BaseLig     3006
     111             : #define CID_BaseMark    3007
     112             : #define CID_CursEntry   3008
     113             : #define CID_CursExit    3009
     114             : #define CID_LigIndex    3010
     115             : #define CID_Next        3011
     116             : #define CID_Prev        3012
     117             : #define CID_Delete      3013
     118             : #define CID_New         3014
     119             : #define CID_MatchPt     3015
     120             : 
     121             : #define RI_Width        225
     122             : #define RI_Height       246
     123             : #define CID_Match_Pt_Base       1010
     124             : #define CID_Match_Pt_Ref        1011
     125             : 
     126             : #define II_Width        130
     127             : #define II_Height       70
     128             : 
     129             : #define PI_Width        228
     130             : #define PI_Height       434
     131             : 
     132             : #define AI_Width        160
     133             : #define AI_Height       258
     134             : 
     135           0 : static int GI_Cancel(GGadget *g, GEvent *e) {
     136           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     137           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     138           0 :         ci->done = true;
     139             :     }
     140           0 : return( true );
     141             : }
     142             : 
     143           0 : static int GI_TransChange(GGadget *g, GEvent *e) {
     144           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
     145           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     146           0 :         ci->changed = true;
     147             :     }
     148           0 : return( true );
     149             : }
     150             : 
     151           0 : static int GI_MatchPtChange(GGadget *g, GEvent *e) {
     152           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
     153           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     154           0 :         const unichar_t *t1 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Base));
     155           0 :         const unichar_t *t2 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Ref));
     156           0 :         while ( *t1==' ' ) ++t1;
     157           0 :         while ( *t2==' ' ) ++t2;
     158           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,1004),*t1=='\0' && *t2=='\0' );
     159           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,1005),*t1=='\0' && *t2=='\0' );
     160           0 :         if ( isdigit(*t1) && isdigit(*t2)) {
     161             :             BasePoint inbase, inref;
     162             :             int basept, refpt;
     163           0 :             basept = u_strtol(t1,NULL,10);
     164           0 :             refpt = u_strtol(t2,NULL,10);
     165           0 :             if ( ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),basept,&inbase,ci->rf)==-1 &&
     166           0 :                     ttfFindPointInSC(ci->rf->sc,CVLayer((CharViewBase *) ci->cv),refpt,&inref,NULL)==-1 ) {
     167             :                 char buffer[40];
     168           0 :                 sprintf(buffer,"%g",(double) (inbase.x-inref.x));
     169           0 :                 GGadgetSetTitle8(GWidgetGetControl(ci->gw,1004),buffer);
     170           0 :                 sprintf(buffer,"%g",(double) (inbase.y-inref.y));
     171           0 :                 GGadgetSetTitle8(GWidgetGetControl(ci->gw,1005),buffer);
     172             :             }
     173             :         }
     174             :     }
     175           0 : return( true );
     176             : }
     177             : 
     178           0 : static int GI_ROK_Do(GIData *ci) {
     179           0 :     int errs=false,i;
     180             :     real trans[6];
     181             :     SplinePointList *spl, *new;
     182           0 :     RefChar *ref = ci->rf, *subref;
     183           0 :     int usemy = GGadgetIsChecked(GWidgetGetControl(ci->gw,6+1000));
     184           0 :     int round = GGadgetIsChecked(GWidgetGetControl(ci->gw,7+1000));
     185           0 :     int basept=-1, refpt=-1;
     186             :     BasePoint inbase, inref;
     187             : 
     188           0 :     for ( i=0; i<6; ++i ) {
     189           0 :         trans[i] = GetReal8(ci->gw,1000+i,_("Transformation Matrix"),&errs);
     190           0 :         if ( !errs &&
     191           0 :                 ((i<4 && (trans[i]>30 || trans[i]<-30)) ||
     192           0 :                  (i>=4 && (trans[i]>16000 || trans[i]<-16000))) ) {
     193             :             /* Don't want the user to insert an enormous scale factor or */
     194             :             /*  it will move points outside the legal range. */
     195           0 :             GTextFieldSelect(GWidgetGetControl(ci->gw,1000+i),0,-1);
     196           0 :             ff_post_error(_("Value out of range"),_("Value out of range"));
     197           0 :             errs = true;
     198             :         }
     199           0 :         if ( errs )
     200           0 : return( false );
     201             :     }
     202           0 :     if ( !ci->cv->b.sc->layers[ly_fore].order2 )
     203             :         /* No point matching */;
     204             :     else {
     205             :         const unichar_t *txt;
     206           0 :         txt = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Base));
     207           0 :         while ( isspace(*txt)) ++txt;
     208           0 :         if ( *txt!='\0' )
     209           0 :             basept = GetInt8(ci->gw,CID_Match_Pt_Base,_("_Base:"),&errs);
     210           0 :         txt = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Ref));
     211           0 :         while ( isspace(*txt)) ++txt;
     212           0 :         if ( *txt!='\0' )
     213           0 :             refpt = GetInt8(ci->gw,CID_Match_Pt_Ref,_("Ref:"),&errs);
     214           0 :         if ( errs )
     215           0 : return( false );
     216           0 :         if ( (basept!=-1) ^ (refpt!=-1) ) {
     217           0 :             ff_post_error(_("Bad Point Match"),_("Both points must be specified, or neither"));
     218             :         }
     219           0 :         if ( basept!=-1 ) {
     220           0 :             if ( ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),basept,&inbase,ci->rf)!=-1 ) {
     221           0 :                 ff_post_error(_("Bad Point Match"),_("Couldn't find base point"));
     222           0 : return( false );
     223           0 :             } else if ( ttfFindPointInSC(ci->rf->sc,CVLayer((CharViewBase *) ci->cv),refpt,&inref,NULL)!=-1 ) {
     224           0 :                 ff_post_error(_("Bad Point Match"),_("Couldn't find point in reference"));
     225           0 : return( false );
     226             :             }
     227             :             /* Override user specified value */
     228           0 :             trans[4] = inbase.x-inref.x;
     229           0 :             trans[5] = inbase.y-inref.y;
     230             :         }
     231             :     }
     232             : 
     233           0 :     for ( i=0; i<6 && ref->transform[i]==trans[i]; ++i );
     234           0 :     if ( i==6 &&
     235           0 :             usemy==ref->use_my_metrics &&
     236           0 :             round==ref->round_translation_to_grid &&
     237           0 :             (basept!=-1)==ref->point_match &&
     238           0 :             (basept==-1 ||
     239           0 :                 (ref->match_pt_base==basept && ref->match_pt_ref==refpt))) {
     240           0 :         ref->point_match_out_of_date = false;
     241           0 : return( true );         /* Didn't really change */
     242             :     }
     243             : 
     244           0 :     for ( i=0; i<6; ++i )
     245           0 :         ref->transform[i] = trans[i];
     246           0 :     SplinePointListsFree(ref->layers[0].splines);
     247           0 :     ref->layers[0].splines = SplinePointListTransform(SplinePointListCopy(ref->sc->layers[ly_fore].splines),trans,tpt_AllPoints);
     248           0 :     spl = NULL;
     249           0 :     if ( ref->layers[0].splines!=NULL )
     250           0 :         for ( spl = ref->layers[0].splines; spl->next!=NULL; spl = spl->next );
     251           0 :     for ( subref = ref->sc->layers[ly_fore].refs; subref!=NULL; subref=subref->next ) {
     252           0 :         new = SplinePointListTransform(SplinePointListCopy(subref->layers[0].splines),trans,tpt_AllPoints);
     253           0 :         if ( spl==NULL )
     254           0 :             ref->layers[0].splines = new;
     255             :         else
     256           0 :             spl->next = new;
     257           0 :         if ( new!=NULL )
     258           0 :             for ( spl = new; spl->next!=NULL; spl = spl->next );
     259             :     }
     260           0 :     ref->use_my_metrics = usemy;
     261           0 :     ref->round_translation_to_grid = round;
     262           0 :     ref->point_match = basept!=-1;
     263           0 :     ref->match_pt_base = basept; ref->match_pt_ref = refpt;
     264           0 :     ref->point_match_out_of_date = false;
     265             : 
     266           0 :     SplineSetFindBounds(ref->layers[0].splines,&ref->bb);
     267           0 :     CVCharChangedUpdate(&ci->cv->b);
     268           0 : return( true );
     269             : }
     270             : 
     271           0 : static int GI_ROK(GGadget *g, GEvent *e) {
     272           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     273           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     274           0 :         if ( GI_ROK_Do(ci))
     275           0 :             ci->done = true;
     276             :     }
     277           0 : return( true );
     278             : }
     279             : 
     280           0 : static int GI_Show(GGadget *g, GEvent *e) {
     281           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     282           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     283           0 :         if ( ci->changed ) {
     284             :             char *buts[4];
     285             :             int ans;
     286           0 :             buts[0] = _("C_hange");
     287           0 :             buts[1] = _("_Retain");
     288           0 :             buts[2] = _("_Cancel");
     289           0 :             buts[3] = NULL;
     290           0 :             ans = gwwv_ask(_("Transformation Matrix Changed"),(const char **)buts,0,2,_("You have changed the transformation matrix, do you wish to use the new version?"));
     291           0 :             if ( ans==2 )
     292           0 : return( true );
     293           0 :             else if ( ans==0 ) {
     294           0 :                 if ( !GI_ROK_Do(ci))
     295           0 : return( true );
     296             :             }
     297             :         }
     298           0 :         ci->done = true;
     299           0 :         CharViewCreate(ci->rf->sc,(FontView *) (ci->cv->b.fv),-1);
     300             :     }
     301           0 : return( true );
     302             : }
     303             : 
     304           0 : static int gi_e_h(GWindow gw, GEvent *event) {
     305           0 :     if ( event->type==et_close ) {
     306           0 :         GIData *ci = GDrawGetUserData(gw);
     307           0 :         ci->done = true;
     308           0 :     } else if ( event->type==et_char ) {
     309           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     310           0 :             help("getinfo.html");
     311           0 : return( true );
     312             :         }
     313           0 : return( false );
     314           0 :     } else if ( event->type == et_map ) {
     315             :         /* Above palettes */
     316           0 :         GDrawRaise(gw);
     317             :     }
     318           0 : return( true );
     319             : }
     320             : 
     321           0 : static void RefGetInfo(CharView *cv, RefChar *ref) {
     322             :     static GIData gi;
     323             :     GRect pos;
     324             :     GWindowAttrs wattrs;
     325             :     GGadgetCreateData gcd[33], boxes[7];
     326             :     GGadgetCreateData *varray[19], *hvarray[16], *harray1[6], *harray2[4],
     327             :             *harray3[7], *hvarray2[4][6];
     328             :     GTextInfo label[33];
     329             :     char tbuf[6][40], bbbuf[4][40];
     330             :     char basebuf[20], refbuf[20];
     331             :     char namebuf[100];
     332             :     char ubuf[40];
     333             :     int i,j,l;
     334             : 
     335           0 :     gi.cv = cv;
     336           0 :     gi.sc = cv->b.sc;
     337           0 :     gi.rf = ref;
     338           0 :     gi.changed = false;
     339           0 :     gi.done = false;
     340             : 
     341           0 :         memset(&wattrs,0,sizeof(wattrs));
     342           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     343           0 :         wattrs.event_masks = ~(1<<et_charup);
     344           0 :         wattrs.restrict_input_to_me = 1;
     345           0 :         wattrs.undercursor = 1;
     346           0 :         wattrs.cursor = ct_pointer;
     347           0 :         wattrs.utf8_window_title = _("Reference Info");
     348           0 :         wattrs.is_dlg = true;
     349           0 :         pos.x = pos.y = 0;
     350           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,RI_Width));
     351           0 :         pos.height = GDrawPointsToPixels(NULL,
     352           0 :                 ref->sc->unicodeenc!=-1?RI_Height+12:RI_Height);
     353           0 :         gi.gw = GDrawCreateTopWindow(NULL,&pos,gi_e_h,&gi,&wattrs);
     354             : 
     355           0 :         memset(&gcd,0,sizeof(gcd));
     356           0 :         memset(&label,0,sizeof(label));
     357           0 :         memset(&boxes,0,sizeof(boxes));
     358             : 
     359           0 :         snprintf( namebuf, sizeof(namebuf),
     360           0 :                 _("Reference to character %1$.20s at %2$d"),
     361           0 :                 ref->sc->name, (int) cv->b.fv->map->backmap[ref->sc->orig_pos]);
     362           0 :         label[0].text = (unichar_t *) namebuf;
     363           0 :         label[0].text_is_1byte = true;
     364           0 :         gcd[0].gd.label = &label[0];
     365           0 :         gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5;
     366           0 :         gcd[0].gd.flags = gg_enabled|gg_visible;
     367           0 :         gcd[0].creator = GLabelCreate;
     368           0 :         l = 0;
     369           0 :         varray[l++] = &gcd[0];
     370           0 :         j = 1;
     371             : 
     372           0 :         if ( ref->sc->unicodeenc!=-1 ) {
     373           0 :             sprintf( ubuf, " Unicode: U+%04x", ref->sc->unicodeenc );
     374           0 :             label[1].text = (unichar_t *) ubuf;
     375           0 :             label[1].text_is_1byte = true;
     376           0 :             gcd[1].gd.label = &label[1];
     377           0 :             gcd[1].gd.pos.x = 5; gcd[1].gd.pos.y = 17;
     378           0 :             gcd[1].gd.flags = gg_enabled|gg_visible;
     379           0 :             gcd[1].creator = GLabelCreate;
     380           0 :             varray[l++] = &gcd[1];
     381           0 :             j=2;
     382             :         }
     383             : 
     384           0 :         label[j].text = (unichar_t *) _("Transformed by:");
     385           0 :         label[j].text_is_1byte = true;
     386           0 :         gcd[j].gd.label = &label[j];
     387           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
     388           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     389           0 :         gcd[j].gd.popup_msg = (unichar_t *) _("The transformation matrix specifies how the points in\nthe source glyph should be transformed before\nthey are drawn in the current glyph.\n x(new) = tm[1,1]*x + tm[2,1]*y + tm[3,1]\n y(new) = tm[1,2]*x + tm[2,2]*y + tm[3,2]");
     390           0 :         gcd[j].creator = GLabelCreate;
     391           0 :         varray[l++] = &gcd[j];
     392           0 :         ++j;
     393             : 
     394           0 :         for ( i=0; i<6; ++i ) {
     395           0 :             if ( !(i&1) ) hvarray[5*(i/2)] = GCD_Glue;
     396           0 :             sprintf(tbuf[i],"%g", (double) ref->transform[i]);
     397           0 :             label[i+j].text = (unichar_t *) tbuf[i];
     398           0 :             label[i+j].text_is_1byte = true;
     399           0 :             gcd[i+j].gd.label = &label[i+j];
     400           0 :             gcd[i+j].gd.pos.x = 20+((i&1)?85:0); gcd[i+j].gd.pos.width=75;
     401           0 :             gcd[i+j].gd.pos.y = gcd[j-1].gd.pos.y+14+(i/2)*26;
     402           0 :             gcd[i+j].gd.flags = gg_enabled|gg_visible;
     403           0 :             gcd[i+j].gd.cid = i+1000;
     404           0 :             gcd[i+j].gd.handle_controlevent = GI_TransChange;
     405           0 :             gcd[i+j].creator = (i>=4 ? GNumericFieldCreate : GTextFieldCreate);
     406           0 :             hvarray[5*(i/2)+1+(i&1)] = &gcd[i+j];
     407           0 :             if ( (i&1) ) { hvarray[5*(i/2)+3] = GCD_Glue; hvarray[5*(i/2)+4] = NULL; }
     408             :         }
     409           0 :         if ( ref->point_match )
     410           0 :             gcd[4+j].gd.flags = gcd[5+j].gd.flags = gg_visible;
     411           0 :         hvarray[15] = NULL;
     412             : 
     413           0 :         boxes[2].gd.flags = gg_enabled|gg_visible;
     414           0 :         boxes[2].gd.u.boxelements = hvarray;
     415           0 :         boxes[2].creator = GHVBoxCreate;
     416           0 :         varray[l++] = &boxes[2];
     417             : 
     418           0 :         label[6+j].text = (unichar_t *) _("_Use My Metrics");
     419           0 :         label[6+j].text_in_resource = true;
     420           0 :         label[6+j].text_is_1byte = true;
     421           0 :         gcd[6+j].gd.label = &label[6+j];
     422           0 :         gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+21;
     423           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup | (ref->use_my_metrics?gg_cb_on:0);
     424           0 :         gcd[i+j].gd.cid = 6+1000;
     425           0 :         gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that the width\nof the composite glyph should be the same as the width of this reference.");
     426           0 :         varray[l++] = &gcd[6+j];
     427           0 :         gcd[6+j++].creator = GCheckBoxCreate;
     428             : 
     429           0 :         label[6+j].text = (unichar_t *) _("_Round To Grid");
     430           0 :         label[6+j].text_in_resource = true;
     431           0 :         label[6+j].text_is_1byte = true;
     432           0 :         gcd[6+j].gd.label = &label[6+j];
     433           0 :         gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+14;
     434           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup | (ref->round_translation_to_grid?gg_cb_on:0);
     435           0 :         gcd[i+j].gd.cid = 7+1000;
     436           0 :         gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that if the reference\nis translated, then the translation should be rounded during grid fitting.");
     437           0 :         varray[l++] = &gcd[6+j];
     438           0 :         gcd[6+j++].creator = GCheckBoxCreate;
     439             : 
     440           0 :         label[6+j].text = (unichar_t *) _("TrueType Point _Matching:");
     441           0 :         label[6+j].text_in_resource = true;
     442           0 :         label[6+j].text_is_1byte = true;
     443           0 :         gcd[6+j].gd.label = &label[6+j];
     444           0 :         gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+17;
     445           0 :         gcd[6+j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible|gg_utf8_popup) : (gg_visible|gg_utf8_popup);
     446           0 :         gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
     447           0 :         varray[l++] = &gcd[6+j];
     448           0 :         gcd[6+j++].creator = GLabelCreate;
     449             : 
     450           0 :         label[6+j].text = (unichar_t *) _("_Base:");
     451           0 :         label[6+j].text_is_1byte = true;
     452           0 :         label[6+j].text_in_resource = true;
     453           0 :         gcd[6+j].gd.label = &label[6+j];
     454           0 :         gcd[6+j].gd.pos.x = 8; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+19;
     455           0 :         gcd[6+j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible|gg_utf8_popup) : (gg_visible|gg_utf8_popup);
     456           0 :         gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
     457           0 :         harray1[0] = &gcd[6+j];
     458           0 :         gcd[6+j++].creator = GLabelCreate;
     459             : 
     460           0 :         if ( ref->point_match ) {
     461           0 :             sprintf(basebuf,"%d", ref->match_pt_base);
     462           0 :             label[6+j].text = (unichar_t *) basebuf;
     463           0 :             label[6+j].text_is_1byte = true;
     464           0 :             gcd[6+j].gd.label = &label[6+j];
     465             :         }
     466           0 :         gcd[6+j].gd.pos.x = 40; gcd[6+j].gd.pos.width=50;
     467           0 :         gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y-4;
     468           0 :         gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
     469           0 :         gcd[6+j].gd.cid = CID_Match_Pt_Base;
     470           0 :         gcd[6+j].gd.handle_controlevent = GI_MatchPtChange;
     471           0 :         harray1[1] = &gcd[6+j];
     472           0 :         gcd[6+j++].creator = GTextFieldCreate;
     473             : 
     474           0 :         label[6+j].text = (unichar_t *) _("Ref:");
     475           0 :         label[6+j].text_is_1byte = true;
     476           0 :         gcd[6+j].gd.label = &label[6+j];
     477           0 :         gcd[6+j].gd.pos.x = 95; gcd[6+j].gd.pos.y = gcd[6+j-2].gd.pos.y;
     478           0 :         gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
     479           0 :         gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
     480           0 :         harray1[2] = &gcd[6+j];
     481           0 :         gcd[6+j++].creator = GLabelCreate;
     482             : 
     483           0 :         if ( ref->point_match ) {
     484           0 :             sprintf(refbuf,"%d", ref->match_pt_ref);
     485           0 :             label[6+j].text = (unichar_t *) refbuf;
     486           0 :             label[6+j].text_is_1byte = true;
     487           0 :             gcd[6+j].gd.label = &label[6+j];
     488             :         }
     489           0 :         gcd[6+j].gd.pos.x = 127; gcd[6+j].gd.pos.width=50;
     490           0 :         gcd[6+j].gd.pos.y = gcd[6+j-2].gd.pos.y;
     491           0 :         gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
     492           0 :         gcd[6+j].gd.cid = CID_Match_Pt_Ref;
     493           0 :         gcd[6+j].gd.handle_controlevent = GI_MatchPtChange;
     494           0 :         harray1[3] = &gcd[6+j];
     495           0 :         gcd[6+j++].creator = GTextFieldCreate;
     496           0 :         harray1[4] = GCD_Glue; harray1[5] = NULL;
     497             : 
     498           0 :         boxes[3].gd.flags = gg_enabled|gg_visible;
     499           0 :         boxes[3].gd.u.boxelements = harray1;
     500           0 :         boxes[3].creator = GHBoxCreate;
     501           0 :         varray[l++] = &boxes[3];
     502             : 
     503           0 :         varray[l++] = GCD_Glue;
     504             : 
     505           0 :         gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = RI_Height+(j==10?12:0)-70;
     506           0 :         gcd[6+j].gd.pos.width = RI_Width-10;
     507           0 :         gcd[6+j].gd.flags = gg_visible | gg_enabled;
     508           0 :         varray[l++] = &gcd[6+j];
     509           0 :         gcd[6+j++].creator = GLineCreate;
     510             : 
     511           0 :         label[6+j].text = (unichar_t *) _("Bounding Box:");
     512           0 :         label[6+j].text_is_1byte = true;
     513           0 :         gcd[6+j].gd.label = &label[6+j];
     514           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     515           0 :         gcd[6+j].creator = GLabelCreate;
     516           0 :         varray[l++] = &gcd[6+j];
     517           0 :         ++j;
     518             : 
     519           0 :         hvarray2[0][0] = GCD_Glue; hvarray2[0][1] = GCD_Glue;
     520             : 
     521           0 :         label[6+j].text = (unichar_t *) _("Min");
     522           0 :         label[6+j].text_is_1byte = true;
     523           0 :         gcd[6+j].gd.label = &label[6+j];
     524           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     525           0 :         gcd[6+j].creator = GLabelCreate;
     526           0 :         hvarray2[0][2] = &gcd[6+j++];
     527             : 
     528           0 :         label[6+j].text = (unichar_t *) _("Max");
     529           0 :         label[6+j].text_is_1byte = true;
     530           0 :         gcd[6+j].gd.label = &label[6+j];
     531           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     532           0 :         gcd[6+j].creator = GLabelCreate;
     533           0 :         hvarray2[0][3] = &gcd[6+j++]; hvarray2[0][4] = GCD_Glue; hvarray2[0][5] = NULL;
     534             : 
     535           0 :         hvarray2[1][0] = hvarray2[1][4] = GCD_Glue; hvarray2[1][5] = NULL;
     536           0 :         hvarray2[2][0] = hvarray2[2][4] = GCD_Glue; hvarray2[2][5] = NULL;
     537             : 
     538           0 :         label[6+j].text = (unichar_t *) _("X:");
     539           0 :         label[6+j].text_is_1byte = true;
     540           0 :         gcd[6+j].gd.label = &label[6+j];
     541           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     542           0 :         gcd[6+j].creator = GLabelCreate;
     543           0 :         hvarray2[1][1] = &gcd[6+j++];
     544             : 
     545           0 :         label[6+j].text = (unichar_t *) _("Y:");
     546           0 :         label[6+j].text_is_1byte = true;
     547           0 :         gcd[6+j].gd.label = &label[6+j];
     548           0 :         gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     549           0 :         gcd[6+j].creator = GLabelCreate;
     550           0 :         hvarray2[2][1] = &gcd[6+j++];
     551             : 
     552           0 :         for ( i=0; i<4; ++i ) {
     553           0 :             sprintf(bbbuf[i],"%g", (double) ((&ref->bb.minx)[i]));
     554           0 :             label[6+j].text = (unichar_t *) bbbuf[i];
     555           0 :             label[6+j].text_is_1byte = true;
     556           0 :             gcd[6+j].gd.label = &label[6+j];
     557           0 :             gcd[6+j].gd.flags = gg_enabled|gg_visible;
     558           0 :             gcd[6+j].creator = GLabelCreate;
     559           0 :             hvarray2[1+i/2][2+(i&1)] = &gcd[6+j++];
     560             :         }
     561           0 :         hvarray2[3][0] = NULL;
     562             : 
     563           0 :         boxes[4].gd.flags = gg_enabled|gg_visible;
     564           0 :         boxes[4].gd.u.boxelements = hvarray2[0];
     565           0 :         boxes[4].creator = GHVBoxCreate;
     566           0 :         varray[l++] = &boxes[4];
     567             : 
     568           0 :         gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = RI_Height+(j==10?12:0)-70;
     569           0 :         gcd[6+j].gd.pos.width = RI_Width-10;
     570           0 :         gcd[6+j].gd.flags = gg_visible | gg_enabled;
     571           0 :         varray[l++] = &gcd[6+j];
     572           0 :         gcd[6+j++].creator = GLineCreate;
     573             : 
     574           0 :         gcd[6+j].gd.pos.x = (RI_Width-GIntGetResource(_NUM_Buttonsize))/2;
     575           0 :         gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+6;
     576           0 :         gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
     577           0 :         gcd[6+j].gd.flags = gg_visible | gg_enabled ;
     578           0 :         label[6+j].text = (unichar_t *) _("_Show");
     579           0 :         label[6+j].text_is_1byte = true;
     580           0 :         label[6+j].text_in_resource = true;
     581           0 :         gcd[6+j].gd.mnemonic = 'S';
     582           0 :         gcd[6+j].gd.label = &label[6+j];
     583           0 :         gcd[6+j].gd.handle_controlevent = GI_Show;
     584           0 :         harray2[0] = GCD_Glue; harray2[1] = &gcd[6+j]; harray2[2] = GCD_Glue; harray2[3] = NULL;
     585           0 :         gcd[6+j++].creator = GButtonCreate;
     586             : 
     587           0 :         boxes[5].gd.flags = gg_enabled|gg_visible;
     588           0 :         boxes[5].gd.u.boxelements = harray2;
     589           0 :         boxes[5].creator = GHBoxCreate;
     590           0 :         varray[l++] = &boxes[5];
     591             : 
     592           0 :         gcd[6+j] = gcd[6+j-2];
     593           0 :         varray[l++] = &gcd[6+j++];
     594             : 
     595           0 :         gcd[6+j].gd.pos.x = 30-3; gcd[6+j].gd.pos.y = RI_Height+(j==13?12:0)-30-3;
     596           0 :         gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
     597           0 :         gcd[6+j].gd.flags = gg_visible | gg_enabled | gg_but_default;
     598           0 :         label[6+j].text = (unichar_t *) _("_OK");
     599           0 :         label[6+j].text_is_1byte = true;
     600           0 :         label[6+j].text_in_resource = true;
     601           0 :         gcd[6+j].gd.mnemonic = 'O';
     602           0 :         gcd[6+j].gd.label = &label[6+j];
     603           0 :         gcd[6+j].gd.handle_controlevent = GI_ROK;
     604           0 :         gcd[6+j++].creator = GButtonCreate;
     605             : 
     606           0 :         gcd[6+j].gd.pos.x = -30; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+3;
     607           0 :         gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
     608           0 :         gcd[6+j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     609           0 :         label[6+j].text = (unichar_t *) _("_Cancel");
     610           0 :         label[6+j].text_is_1byte = true;
     611           0 :         label[6+j].text_in_resource = true;
     612           0 :         gcd[6+j].gd.mnemonic = 'C';
     613           0 :         gcd[6+j].gd.label = &label[6+j];
     614           0 :         gcd[6+j].gd.handle_controlevent = GI_Cancel;
     615           0 :         gcd[6+j].creator = GButtonCreate;
     616             : 
     617           0 :         harray3[0] = GCD_Glue; harray3[1] = &gcd[6+j-1]; harray3[2] = GCD_Glue;
     618           0 :          harray3[3] = GCD_Glue; harray3[4] = &gcd[6+j]; harray3[5] = GCD_Glue;
     619           0 :          harray3[6] = NULL;
     620           0 :         boxes[6].gd.flags = gg_enabled|gg_visible;
     621           0 :         boxes[6].gd.u.boxelements = harray3;
     622           0 :         boxes[6].creator = GHBoxCreate;
     623           0 :         varray[l++] = &boxes[6];
     624           0 :         varray[l] = NULL;
     625             : 
     626           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
     627           0 :         boxes[0].gd.u.boxelements = varray;
     628           0 :         boxes[0].creator = GVBoxCreate;
     629             : 
     630           0 :         GGadgetsCreate(gi.gw,boxes);
     631           0 :         GWidgetIndicateFocusGadget(gcd[j].ret);
     632           0 :     GHVBoxSetExpandableRow(boxes[0].ret,0);
     633           0 :     GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
     634           0 :     GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
     635           0 :     GHVBoxSetPadding(boxes[3].ret,6,2);
     636           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
     637           0 :     GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
     638           0 :     GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
     639           0 :     GHVBoxFitWindow(boxes[0].ret);
     640             : 
     641           0 :     GWidgetHidePalettes();
     642           0 :     GDrawSetVisible(gi.gw,true);
     643           0 :     while ( !gi.done )
     644           0 :         GDrawProcessOneEvent(NULL);
     645           0 :     GDrawDestroyWindow(gi.gw);
     646           0 : }
     647             : 
     648           0 : static void ImgGetInfo(CharView *cv, ImageList *img) {
     649             :     static GIData gi;
     650             :     GRect pos;
     651             :     GWindowAttrs wattrs;
     652             :     GGadgetCreateData gcd[12], boxes[3], *varray[11], *harray[6];
     653             :     GTextInfo label[12];
     654             :     char posbuf[100], scalebuf[100], sizebuf[100];
     655           0 :     struct _GImage *base = img->image->list_len==0?
     656           0 :             img->image->u.image:img->image->u.images[0];
     657             : 
     658           0 :     gi.cv = cv;
     659           0 :     gi.sc = cv->b.sc;
     660           0 :     gi.img = img;
     661           0 :     gi.done = false;
     662             : 
     663           0 :         memset(&wattrs,0,sizeof(wattrs));
     664           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     665           0 :         wattrs.event_masks = ~(1<<et_charup);
     666           0 :         wattrs.restrict_input_to_me = 1;
     667           0 :         wattrs.undercursor = 1;
     668           0 :         wattrs.cursor = ct_pointer;
     669           0 :         wattrs.utf8_window_title = _("Image Info");
     670           0 :         wattrs.is_dlg = true;
     671           0 :         pos.x = pos.y = 0;
     672           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,II_Width));
     673           0 :         pos.height = GDrawPointsToPixels(NULL,II_Height);
     674           0 :         gi.gw = GDrawCreateTopWindow(NULL,&pos,gi_e_h,&gi,&wattrs);
     675             : 
     676           0 :         memset(&gcd,0,sizeof(gcd));
     677           0 :         memset(&label,0,sizeof(label));
     678             : 
     679           0 :         sprintf( posbuf, _("Image at:      (%.0f,%.0f)"), (double) img->xoff,
     680           0 :                 (double) (img->yoff-GImageGetHeight(img->image)*img->yscale));
     681           0 :         label[0].text = (unichar_t *) posbuf;
     682           0 :         label[0].text_is_1byte = true;
     683           0 :         gcd[0].gd.label = &label[0];
     684           0 :         gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5;
     685           0 :         gcd[0].gd.flags = gg_enabled|gg_visible;
     686           0 :         gcd[0].creator = GLabelCreate;
     687           0 :         varray[0] = &gcd[0]; varray[1] = NULL;
     688             : 
     689           0 :         sprintf( scalebuf, _("Scaled by:    (%.2f,%.2f)"), (double) img->xscale, (double) img->yscale );
     690           0 :         label[1].text = (unichar_t *) scalebuf;
     691           0 :         label[1].text_is_1byte = true;
     692           0 :         gcd[1].gd.label = &label[1];
     693           0 :         gcd[1].gd.pos.x = 5; gcd[1].gd.pos.y = 19;
     694           0 :         gcd[1].gd.flags = gg_enabled|gg_visible;
     695           0 :         gcd[1].creator = GLabelCreate;
     696           0 :         varray[2] = &gcd[1]; varray[3] = NULL;
     697             : 
     698           0 :         sprintf( sizebuf, _("Image Size:  %d x %d  pixels"), (int) base->width, (int) base->height );
     699           0 :         label[2].text = (unichar_t *) sizebuf;
     700           0 :         label[2].text_is_1byte = true;
     701           0 :         gcd[2].gd.label = &label[2];
     702           0 :         gcd[2].gd.pos.x = 5; gcd[2].gd.pos.y = 19;
     703           0 :         gcd[2].gd.flags = gg_enabled|gg_visible;
     704           0 :         gcd[2].creator = GLabelCreate;
     705           0 :         varray[4] = &gcd[2]; varray[5] = NULL;
     706           0 :         varray[6] = GCD_Glue; varray[7] = NULL;
     707             : 
     708           0 :         gcd[3].gd.pos.x = (II_Width-GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor)-6)/2; gcd[3].gd.pos.y = II_Height-32-3;
     709           0 :         gcd[3].gd.pos.width = -1; gcd[3].gd.pos.height = 0;
     710           0 :         gcd[3].gd.flags = gg_visible | gg_enabled | gg_but_default | gg_but_cancel;
     711           0 :         label[3].text = (unichar_t *) _("_OK");
     712           0 :         label[3].text_is_1byte = true;
     713           0 :         label[3].text_in_resource = true;
     714           0 :         gcd[3].gd.mnemonic = 'O';
     715           0 :         gcd[3].gd.label = &label[3];
     716           0 :         gcd[3].gd.handle_controlevent = GI_Cancel;
     717           0 :         gcd[3].creator = GButtonCreate;
     718           0 :         harray[0] = GCD_Glue; harray[1] = &gcd[3]; harray[2] = GCD_Glue; harray[3] = NULL;
     719           0 :         varray[8] = &boxes[2]; varray[9] = NULL;
     720           0 :         varray[10] = NULL;
     721             : 
     722           0 :         memset(boxes,0,sizeof(boxes));
     723           0 :         boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     724           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
     725           0 :         boxes[0].gd.u.boxelements = varray;
     726           0 :         boxes[0].creator = GHVGroupCreate;
     727             : 
     728           0 :         boxes[2].gd.flags = gg_enabled|gg_visible;
     729           0 :         boxes[2].gd.u.boxelements = harray;
     730           0 :         boxes[2].creator = GHBoxCreate;
     731             : 
     732           0 :         GGadgetsCreate(gi.gw,boxes);
     733           0 :         GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
     734           0 :         GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
     735           0 :         GHVBoxFitWindow(boxes[0].ret);
     736             : 
     737           0 :     GWidgetHidePalettes();
     738           0 :     GDrawSetVisible(gi.gw,true);
     739           0 :     while ( !gi.done )
     740           0 :         GDrawProcessOneEvent(NULL);
     741           0 :     GDrawDestroyWindow(gi.gw);
     742           0 : }
     743             : 
     744           0 : static AnchorClass *_AnchorClassUnused(SplineChar *sc,int *waslig, int classmatch) {
     745             :     AnchorClass *an, *maybe;
     746             :     int val, maybelig;
     747             :     SplineFont *sf;
     748             :     int ismarkglyph, isligatureglyph;
     749             :     PST *pst;
     750             :     /* Are there any anchors with this name? If so can't reuse it */
     751             :     /*  unless they are ligature anchors */
     752             :     /*  or 'curs' anchors, which allow exactly two points (entry, exit) */
     753             :     /*  or 'mkmk' anchors, which allow a mark to be both a base and an attach */
     754             : 
     755           0 :     ismarkglyph = (sc->width==0) || sc->glyph_class==(3+1) ||
     756           0 :             ( sc->unicodeenc!=-1 && sc->unicodeenc<0x10000 && iscombining(sc->unicodeenc)) ||
     757           0 :             ( sc->anchor!=NULL && (sc->anchor->type == at_mark || sc->anchor->type == at_basemark));
     758           0 :     for ( pst = sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
     759           0 :     isligatureglyph = (pst!=NULL) || sc->glyph_class==2+1;
     760             : 
     761           0 :     *waslig = false; maybelig = false; maybe = NULL;
     762           0 :     sf = sc->parent;
     763           0 :     if ( sf->cidmaster!=NULL ) sf = sf->cidmaster;
     764           0 :     for ( an=sf->anchor; an!=NULL; an=an->next ) {
     765           0 :         if ( classmatch ) {
     766           0 :             if (( an->type == act_mklg && !isligatureglyph && !ismarkglyph ) ||
     767           0 :                     ( an->type == act_mkmk && !ismarkglyph ))
     768           0 :     continue;
     769             :         }
     770           0 :         val = IsAnchorClassUsed(sc,an);
     771           0 :         if ( val>=0 ) {
     772           0 :             *waslig = val;
     773           0 : return( an );
     774           0 :         } else if ( val!=-1 && maybe==NULL ) {
     775           0 :             maybe = an;
     776           0 :             maybelig = val;
     777             :         }
     778             :     }
     779           0 :     *waslig = maybelig;
     780           0 : return( maybe );
     781             : }
     782             : 
     783           0 : AnchorClass *AnchorClassUnused(SplineChar *sc,int *waslig) {
     784           0 : return( _AnchorClassUnused(sc,waslig,false));
     785             : }
     786             : 
     787           0 : static AnchorPoint *AnchorPointNew(CharView *cv) {
     788             :     AnchorClass *an;
     789             :     AnchorPoint *ap;
     790             :     int waslig;
     791           0 :     SplineChar *sc = cv->b.sc;
     792             :     PST *pst;
     793             : 
     794           0 :     an = _AnchorClassUnused(sc,&waslig,true);
     795           0 :     if ( an==NULL )
     796           0 :         an = AnchorClassUnused(sc,&waslig);
     797             : 
     798           0 :     if ( an==NULL )
     799           0 : return(NULL);
     800           0 :     ap = chunkalloc(sizeof(AnchorPoint));
     801           0 :     ap->anchor = an;
     802           0 :     ap->me.x = cv->p.cx; /* cv->p.cx = 0; */
     803           0 :     ap->me.y = cv->p.cy; /* cv->p.cy = 0; */
     804           0 :     ap->type = an->type==act_mark ? at_basechar :
     805           0 :                 an->type==act_mkmk ? at_basemark :
     806           0 :                 an->type==act_mklg ? at_baselig :
     807           0 :                 an->type==act_curs ? at_centry :
     808             :                                      at_basechar;
     809           0 :     for ( pst = cv->b.sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
     810           0 :     if ( waslig<-1 && an->type==act_mkmk ) {
     811           0 :         ap->type = waslig==-2 ? at_basemark : at_mark;
     812           0 :     } else if ( waslig==-2  && an->type==act_curs )
     813           0 :         ap->type = at_cexit;
     814           0 :     else if ( waslig==-3 || an->type==act_curs )
     815           0 :         ap->type = at_centry;
     816           0 :     else if (( sc->unicodeenc!=-1 && sc->unicodeenc<0x10000 &&
     817           0 :             iscombining(sc->unicodeenc)) || sc->width==0 || sc->glyph_class==(3+1) /* mark class+1 */)
     818           0 :         ap->type = at_mark;
     819           0 :     else if ( an->type==act_mkmk )
     820           0 :         ap->type = at_basemark;
     821           0 :     else if (( pst!=NULL || waslig || sc->glyph_class==2+1) && an->type==act_mklg )
     822           0 :         ap->type = at_baselig;
     823           0 :     if (( ap->type==at_basechar || ap->type==at_baselig ) && an->type==act_mkmk )
     824           0 :         ap->type = at_basemark;
     825           0 :     ap->next = sc->anchor;
     826           0 :     if ( waslig>=0 )
     827           0 :         ap->lig_index = waslig;
     828           0 :     sc->anchor = ap;
     829           0 : return( ap );
     830             : }
     831             : 
     832           0 : static void AI_SelectList(GIData *ci,AnchorPoint *ap) {
     833             :     int i;
     834             :     AnchorClass *an;
     835           0 :     SplineFont *sf = ci->sc->parent;
     836             : 
     837           0 :     if ( sf->cidmaster ) sf = sf->cidmaster;
     838             : 
     839           0 :     for ( i=0, an=sf->anchor; an!=ap->anchor; ++i, an=an->next );
     840           0 :     GGadgetSelectOneListItem(GWidgetGetControl(ci->gw,CID_NameList),i);
     841           0 : }
     842             : 
     843           0 : static void AI_DisplayClass(GIData *ci,AnchorPoint *ap) {
     844           0 :     AnchorClass *ac = ap->anchor;
     845             :     AnchorPoint *aps;
     846             :     int saw[at_max];
     847             : 
     848           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseChar),ac->type==act_mark || ac->type==act_unknown);
     849           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseLig),ac->type==act_mklg);
     850           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseMark),ac->type==act_mkmk);
     851           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursEntry),ac->type==act_curs);
     852           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursExit),ac->type==act_curs);
     853           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Mark),ac->type!=act_curs);
     854             : 
     855           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
     856             : 
     857           0 :     if ( ac->type==act_mkmk && (ap->type==at_basechar || ap->type==at_baselig)) {
     858           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseMark),true);
     859           0 :         ap->type = at_basemark;
     860           0 :     } else if ( ac->type==act_mark && ap->type==at_basemark ) {
     861           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseChar),true);
     862           0 :         ap->type = at_basechar;
     863           0 :     } else if ( ac->type==act_curs && ap->type!=at_centry && ap->type!=at_cexit ) {
     864           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursEntry),true);
     865           0 :         ap->type = at_centry;
     866             :     }
     867             : 
     868           0 :     memset(saw,0,sizeof(saw));
     869           0 :     for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) if ( aps!=ap ) {
     870           0 :         if ( aps->anchor==ac ) saw[aps->type] = true;
     871             :     }
     872           0 :     if ( ac->type==act_curs ) {
     873           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursEntry),!saw[at_centry]);
     874           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursExit),!saw[at_cexit]);
     875             :     } else {
     876           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Mark),!saw[at_mark]);
     877           0 :         if ( saw[at_basechar]) GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseChar),false);
     878           0 :         if ( saw[at_basemark]) GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseMark),false);
     879             :     }
     880           0 : }
     881             : 
     882           0 : static void AI_DisplayIndex(GIData *ci,AnchorPoint *ap) {
     883             :     char buffer[12];
     884             : 
     885           0 :     sprintf(buffer,"%d", ap->lig_index );
     886             : 
     887           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_LigIndex),buffer);
     888           0 : }
     889             : 
     890           0 : static void AI_DisplayRadio(GIData *ci,enum anchor_type type) {
     891           0 :     switch ( type ) {
     892             :       case at_mark:
     893           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Mark),true);
     894           0 :       break;
     895             :       case at_basechar:
     896           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseChar),true);
     897           0 :       break;
     898             :       case at_baselig:
     899           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseLig),true);
     900           0 :       break;
     901             :       case at_basemark:
     902           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseMark),true);
     903           0 :       break;
     904             :       case at_centry:
     905           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursEntry),true);
     906           0 :       break;
     907             :       case at_cexit:
     908           0 :         GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursExit),true);
     909           0 :       break;
     910             :     }
     911           0 : }
     912             : 
     913           0 : static void AI_Display(GIData *ci,AnchorPoint *ap) {
     914             :     char val[40];
     915             :     unichar_t uval[40];
     916             :     AnchorPoint *aps;
     917             : 
     918           0 :     if ( ap==NULL) {
     919           0 :         SCUpdateAll(ci->sc);
     920           0 : return;
     921             :     }
     922             : 
     923           0 :     ci->ap = ap;
     924           0 :     for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next )
     925           0 :         aps->selected = false;
     926           0 :     ap->selected = true;
     927           0 :     sprintf(val,"%g",(double) ap->me.x);
     928           0 :     uc_strcpy(uval,val);
     929           0 :     GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_X),uval);
     930           0 :     sprintf(val,"%g",(double) ap->me.y);
     931           0 :     uc_strcpy(uval,val);
     932           0 :     GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_Y),uval);
     933           0 :     sprintf(val,"%d",ap->type==at_baselig?ap->lig_index:0);
     934           0 :     uc_strcpy(uval,val);
     935           0 :     GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_LigIndex),uval);
     936           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
     937           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Next),ap->next!=NULL);
     938           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Prev),ci->sc->anchor!=ap);
     939           0 :     if ( ap->has_ttf_pt )
     940           0 :         sprintf(val,"%d",ap->ttf_pt_index);
     941             :     else
     942           0 :         val[0] = '\0';
     943           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_MatchPt),val);
     944           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_X),!ap->has_ttf_pt);
     945           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Y),!ap->has_ttf_pt);
     946             : 
     947           0 :     AI_DisplayClass(ci,ap);
     948           0 :     AI_DisplayRadio(ci,ap->type);
     949             : 
     950           0 :     AI_SelectList(ci,ap);
     951           0 :     SCUpdateAll(ci->sc);
     952             : }
     953             : 
     954           0 : static int AI_Next(GGadget *g, GEvent *e) {
     955           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     956           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     957             : 
     958           0 :         if ( ci->ap->next==NULL )
     959           0 : return( true );
     960           0 :         AI_Display(ci,ci->ap->next);
     961             :     }
     962           0 : return( true );
     963             : }
     964             : 
     965           0 : static int AI_Prev(GGadget *g, GEvent *e) {
     966           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     967           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     968             :         AnchorPoint *ap, *prev;
     969             : 
     970           0 :         prev = NULL;
     971           0 :         for ( ap=ci->sc->anchor; ap!=ci->ap; ap = ap->next )
     972           0 :             prev = ap;
     973           0 :         if ( prev==NULL )
     974           0 : return( true );
     975           0 :         AI_Display(ci,prev);
     976             :     }
     977           0 : return( true );
     978             : }
     979             : 
     980             : static int AI_Ok(GGadget *g, GEvent *e);
     981           0 : static int AI_Delete(GGadget *g, GEvent *e) {
     982           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     983           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
     984             :         AnchorPoint *ap, *prev, *delete_it;
     985             : 
     986           0 :         prev=NULL;
     987           0 :         for ( ap=ci->sc->anchor; ap!=ci->ap; ap=ap->next )
     988           0 :             prev = ap;
     989           0 :         if ( prev==NULL && ci->ap->next==NULL ) {
     990             :             static char *buts[3];
     991           0 :             buts[0] = _("_Yes"); buts[1] = _("_No"); buts[2] = NULL;
     992           0 :             if ( gwwv_ask(_("Last Anchor Point"),(const char **) buts,0,1, _("You are deleting the last anchor point in this character.\nDoing so will cause this dialog to close, is that what you want?"))==1 ) {
     993           0 :                 AI_Ok(g,e);
     994           0 : return( true );
     995             :             }
     996             :         }
     997             : 
     998           0 :         delete_it = ci->ap;
     999             : 
    1000           0 :         if ((prev == NULL) && (ci->ap->next == NULL)) {
    1001           0 :             ci->sc->anchor = NULL;
    1002           0 :             AnchorPointsFree(delete_it);
    1003           0 :             AI_Ok(g,e);
    1004           0 :             SCUpdateAll(ci->sc);
    1005             :         }
    1006           0 :         else if (ci->ap->next == NULL) {
    1007           0 :             prev->next = NULL;
    1008           0 :             AnchorPointsFree(delete_it);
    1009           0 :             AI_Display(ci,prev);
    1010             :         }
    1011           0 :         else if (prev == NULL) {
    1012           0 :             ci->sc->anchor = delete_it->next;
    1013           0 :             delete_it->next = NULL;
    1014           0 :             AnchorPointsFree(delete_it);
    1015           0 :             AI_Display(ci,ci->sc->anchor);
    1016             :         }
    1017             :         else {
    1018           0 :             prev->next = delete_it->next;
    1019           0 :             delete_it->next = NULL;
    1020           0 :             AnchorPointsFree(delete_it);
    1021           0 :             AI_Display(ci,prev->next);
    1022             :         }
    1023             : 
    1024           0 :         _CVCharChangedUpdate(&ci->cv->b,2);
    1025             :     }
    1026           0 : return( true );
    1027             : }
    1028             : 
    1029           0 : static GTextInfo **AnchorClassesLList(SplineFont *sf) {
    1030             :     AnchorClass *an;
    1031             :     int cnt;
    1032             :     GTextInfo **ti;
    1033             : 
    1034           0 :     if ( sf->cidmaster ) sf=sf->cidmaster;
    1035             : 
    1036           0 :     for ( cnt=0, an=sf->anchor; an!=NULL; ++cnt, an=an->next );
    1037           0 :     ti = calloc(cnt+1,sizeof(GTextInfo*));
    1038           0 :     for ( cnt=0, an=sf->anchor; an!=NULL; ++cnt, an=an->next ) {
    1039           0 :         ti[cnt] = calloc(1,sizeof(GTextInfo));
    1040           0 :         ti[cnt]->text = utf82u_copy(an->name);
    1041           0 :         ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
    1042           0 :         ti[cnt]->userdata = an;
    1043             :     }
    1044           0 :     ti[cnt] = calloc(1,sizeof(GTextInfo));
    1045           0 : return( ti );
    1046             : }
    1047             : 
    1048           0 : static int AI_NewClass(GGadget *g, GEvent *e) {
    1049           0 :     GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1050           0 :     SplineFont *sf = ci->sc->parent;
    1051             :     AnchorClass *ac;
    1052             :     GTextInfo **ti;
    1053             :     int j;
    1054           0 :     char *name = gwwv_ask_string(_("Anchor Class Name"),"",_("Please enter the name of a Anchor point class to create"));
    1055           0 :     if ( name==NULL )
    1056           0 : return( true );
    1057           0 :     ac = SFFindOrAddAnchorClass(sf,name,NULL);
    1058           0 :     GGadgetSetList(GWidgetGetControl(ci->gw,CID_NameList),
    1059             :     ti = AnchorClassesLList(sf),false);
    1060           0 :     for ( j=0; ti[j]->text!=NULL && ti[j]->userdata!=ac; ++j )
    1061           0 :         GGadgetSelectOneListItem(GWidgetGetControl(ci->gw,CID_NameList),j);
    1062           0 : return( true );
    1063             : }
    1064             : 
    1065           0 : static int AI_New(GGadget *g, GEvent *e) {
    1066           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1067           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1068             :         int waslig;
    1069             :         AnchorPoint *ap;
    1070           0 :         SplineFont *sf = ci->sc->parent;
    1071             : 
    1072           0 :         if ( sf->cidmaster ) sf = sf->cidmaster;
    1073             : 
    1074           0 :         if ( AnchorClassUnused(ci->sc,&waslig)==NULL ) {
    1075           0 :             if ( !AI_NewClass(g, e) )
    1076           0 : return( false );
    1077             :         }
    1078           0 :         ap = AnchorPointNew(ci->cv);
    1079           0 :         if ( ap==NULL )
    1080           0 : return( true );
    1081           0 :         AI_Display(ci,ap);
    1082             :     }
    1083           0 : return( true );
    1084             : }
    1085             : 
    1086           0 : static int AI_TypeChanged(GGadget *g, GEvent *e) {
    1087           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    1088           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1089           0 :         AnchorPoint *ap = ci->ap;
    1090             : 
    1091           0 :         if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Mark)) )
    1092           0 :             ap->type = at_mark;
    1093           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseChar)) )
    1094           0 :             ap->type = at_basechar;
    1095           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseLig)) )
    1096           0 :             ap->type = at_baselig;
    1097           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseMark)) )
    1098           0 :             ap->type = at_basemark;
    1099           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_CursEntry)) )
    1100           0 :             ap->type = at_centry;
    1101           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_CursExit)) )
    1102           0 :             ap->type = at_cexit;
    1103           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
    1104           0 :         _CVCharChangedUpdate(&ci->cv->b,2);
    1105             :     }
    1106           0 : return( true );
    1107             : }
    1108             : 
    1109           0 : static void AI_TestOrdering(GIData *ci,real x) {
    1110           0 :     AnchorPoint *aps, *ap=ci->ap;
    1111           0 :     AnchorClass *ac = ap->anchor;
    1112             :     int isr2l;
    1113             : 
    1114           0 :     isr2l = SCRightToLeft(ci->sc);
    1115           0 :     for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) {
    1116           0 :         if ( aps->anchor==ac && aps!=ci->ap ) {
    1117           0 :             if (( aps->lig_index<ap->lig_index &&
    1118           0 :                     ((!isr2l && aps->me.x>x) ||
    1119           0 :                      ( isr2l && aps->me.x<x))) ||
    1120           0 :                 ( aps->lig_index>ap->lig_index &&
    1121           0 :                     (( isr2l && aps->me.x>x) ||
    1122           0 :                      (!isr2l && aps->me.x<x))) ) {
    1123           0 :                 ff_post_error(_("Out Of Order"),_("Marks within a ligature should be ordered with the direction of writing.\nThis one and %d are out of order."),aps->lig_index);
    1124           0 : return;
    1125             :             }
    1126             :         }
    1127             :     }
    1128           0 : return;
    1129             : }
    1130             : 
    1131           0 : static int AI_LigIndexChanged(GGadget *g, GEvent *e) {
    1132           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1133           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1134             :         int index, max;
    1135           0 :         int err=false;
    1136           0 :         AnchorPoint *ap = ci->ap, *aps;
    1137             : 
    1138           0 :         index = GetCalmReal8(ci->gw,CID_LigIndex,_("Lig Index:"),&err);
    1139           0 :         if ( index<0 || err )
    1140           0 : return( true );
    1141           0 :         if ( *_GGadgetGetTitle(g)=='\0' )
    1142           0 : return( true );
    1143           0 :         max = 0;
    1144           0 :         AI_TestOrdering(ci,ap->me.x);
    1145           0 :         for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) {
    1146           0 :             if ( aps->anchor==ap->anchor && aps!=ap ) {
    1147           0 :                 if ( aps->lig_index==index ) {
    1148           0 :                     ff_post_error(_("Index in use"),_("This ligature index is already in use"));
    1149           0 : return( true );
    1150           0 :                 } else if ( aps->lig_index>max )
    1151           0 :                     max = aps->lig_index;
    1152             :             }
    1153             :         }
    1154           0 :         if ( index>max+10 ) {
    1155             :             char buf[20];
    1156           0 :             ff_post_error(_("Too Big"),_("This index is much larger than the closest neighbor"));
    1157           0 :             sprintf(buf,"%d", max+1);
    1158           0 :             GGadgetSetTitle8(g,buf);
    1159           0 :             index = max+1;
    1160             :         }
    1161           0 :         ap->lig_index = index;
    1162           0 :         _CVCharChangedUpdate(&ci->cv->b,2);
    1163             :     }
    1164           0 : return( true );
    1165             : }
    1166             : 
    1167           0 : static int AI_ANameChanged(GGadget *g, GEvent *e) {
    1168           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
    1169           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1170             :         AnchorPoint *ap;
    1171           0 :         GTextInfo *ti = GGadgetGetListItemSelected(g);
    1172           0 :         AnchorClass *an = ti->userdata;
    1173           0 :         int change=0, max=0;
    1174             :         int ntype;
    1175             :         int sawentry, sawexit;
    1176             : 
    1177           0 :         if ( an==ci->ap->anchor )
    1178           0 : return( true );                 /* No op */
    1179             : 
    1180           0 :         ntype = ci->ap->type;
    1181           0 :         if ( an->type==act_curs ) {
    1182           0 :             if ( ntype!=at_centry && ntype!=at_cexit )
    1183           0 :                 ntype = at_centry;
    1184           0 :         } else if ( an->type==act_mkmk ) {
    1185           0 :             if ( ntype!=at_basemark && ntype!=at_mark )
    1186           0 :                 ntype = at_basemark;
    1187           0 :         } else if ( ntype==at_centry || ntype==at_cexit || ntype==at_basemark ||
    1188           0 :                 ntype==at_baselig || ntype == at_basechar ) {
    1189             :             PST *pst;
    1190           0 :             for ( pst = ci->sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
    1191           0 :             if (ci->sc->glyph_class==3+1 ||
    1192           0 :                     (ci->sc->unicodeenc!=-1 && ci->sc->unicodeenc<0x10000 &&
    1193           0 :                     iscombining(ci->sc->unicodeenc)))
    1194           0 :                 ntype = at_mark;
    1195           0 :             else if (( pst!=NULL || ci->sc->glyph_class==2+1 ) && an->type==act_mklg )
    1196           0 :                 ntype = at_baselig;
    1197             :             else
    1198           0 :                 ntype = at_basechar;
    1199             :         }
    1200             : 
    1201           0 :         sawentry = sawexit = false;
    1202           0 :         for ( ap=ci->sc->anchor; ap!=NULL; ap = ap->next ) {
    1203           0 :             if ( ap!=ci->ap && ap->anchor==an ) {
    1204           0 :                 if ( an->type==act_curs ) {
    1205           0 :                     if ( ap->type == at_centry ) sawentry = true;
    1206           0 :                     else if ( ap->type== at_cexit ) sawexit = true;
    1207           0 :                 } else if ( an->type==act_mkmk ) {
    1208           0 :                     if ( ap->type == at_mark ) sawentry = true;
    1209           0 :                     else if ( ap->type== at_basemark ) sawexit = true;
    1210             :                 } else {
    1211           0 :                     if ( ap->type!=at_baselig )
    1212           0 :         break;
    1213           0 :                     if ( ap->lig_index==ci->ap->lig_index )
    1214           0 :                         change = true;
    1215           0 :                     else if ( ap->lig_index>max )
    1216           0 :                         max = ap->lig_index;
    1217             :                 }
    1218           0 :             } else if ( ap!=ci->ap && ap->anchor->subtable==an->subtable &&
    1219           0 :                     ap->type==at_mark )
    1220           0 :         break;
    1221             :         }
    1222           0 :         if ( ap!=NULL || (sawentry && sawexit)) {
    1223           0 :             AI_SelectList(ci,ci->ap);
    1224           0 :             ff_post_error(_("Class already used"),_("This anchor class already is associated with a point in this character"));
    1225             :         } else {
    1226           0 :             ci->ap->anchor = an;
    1227           0 :             if ( an->type==act_curs ) {
    1228           0 :                 if ( sawentry ) ntype = at_cexit;
    1229           0 :                 else if ( sawexit ) ntype = at_centry;
    1230           0 :             } else if ( an->type==act_mkmk ) {
    1231           0 :                 if ( sawentry ) ntype = at_basemark;
    1232           0 :                 else if ( sawexit ) ntype = at_mark;
    1233             :             }
    1234           0 :             if ( ci->ap->type!=ntype ) {
    1235           0 :                 ci->ap->type = ntype;
    1236           0 :                 AI_DisplayRadio(ci,ntype);
    1237             :             }
    1238           0 :             if ( ci->ap->type!=at_baselig )
    1239           0 :                 ci->ap->lig_index = 0;
    1240           0 :             else if ( change ) {
    1241           0 :                 ci->ap->lig_index = max+1;
    1242           0 :                 AI_DisplayIndex(ci,ci->ap);
    1243             :             }
    1244           0 :             AI_DisplayClass(ci,ci->ap);
    1245           0 :             AI_TestOrdering(ci,ci->ap->me.x);
    1246             :         }
    1247           0 :         _CVCharChangedUpdate(&ci->cv->b,2);
    1248             :     }
    1249           0 : return( true );
    1250             : }
    1251             : 
    1252           0 : static int AI_PosChanged(GGadget *g, GEvent *e) {
    1253           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1254           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1255           0 :         real dx=0, dy=0;
    1256           0 :         int err=false;
    1257           0 :         AnchorPoint *ap = ci->ap;
    1258             : 
    1259           0 :         if ( GGadgetGetCid(g)==CID_X ) {
    1260           0 :             dx = GetCalmReal8(ci->gw,CID_X,_("_X"),&err)-ap->me.x;
    1261           0 :             AI_TestOrdering(ci,ap->me.x+dx);
    1262             :         } else
    1263           0 :             dy = GetCalmReal8(ci->gw,CID_Y,_("_Y"),&err)-ap->me.y;
    1264           0 :         if ( (dx==0 && dy==0) || err )
    1265           0 : return( true );
    1266           0 :         ap->me.x += dx;
    1267           0 :         ap->me.y += dy;
    1268           0 :         _CVCharChangedUpdate(&ci->cv->b,2);
    1269             :     }
    1270           0 : return( true );
    1271             : }
    1272             : 
    1273           0 : static int AI_MatchChanged(GGadget *g, GEvent *e) {
    1274           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1275           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1276           0 :         const unichar_t *t1 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_MatchPt));
    1277             :         unichar_t *end;
    1278           0 :         AnchorPoint *ap = ci->ap;
    1279             : 
    1280           0 :         while ( *t1==' ' ) ++t1;
    1281           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_X),*t1=='\0');
    1282           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Y),*t1=='\0');
    1283           0 :         if ( isdigit(*t1)) {
    1284             :             BasePoint here;
    1285             :             int pt;
    1286           0 :             pt = u_strtol(t1,&end,10);
    1287           0 :             if ( *end=='\0' && ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),pt,&here,NULL)==-1 ) {
    1288             :                 char buffer[40];
    1289           0 :                 sprintf(buffer,"%g",(double) here.x);
    1290           0 :                 GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_X),buffer);
    1291           0 :                 sprintf(buffer,"%g",(double) here.y);
    1292           0 :                 GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_Y),buffer);
    1293           0 :                 ap->me = here;
    1294           0 :                 ap->has_ttf_pt = true;
    1295           0 :                 ap->ttf_pt_index = pt;
    1296           0 :                 _CVCharChangedUpdate(&ci->cv->b,2);
    1297             :             }
    1298             :         } else
    1299           0 :             ap->has_ttf_pt = false;
    1300             :     }
    1301           0 : return( true );
    1302             : }
    1303             : 
    1304           0 : static void AI_DoCancel(GIData *ci) {
    1305           0 :     CharView *cv = ci->cv;
    1306           0 :     ci->done = true;
    1307           0 :     AnchorPointsFree(cv->b.sc->anchor);
    1308           0 :     cv->b.sc->anchor = ci->oldaps;
    1309           0 :     ci->oldaps = NULL;
    1310           0 :     CVRemoveTopUndo(&cv->b);
    1311           0 :     SCUpdateAll(cv->b.sc);
    1312           0 : }
    1313             : 
    1314           0 : static int ai_e_h(GWindow gw, GEvent *event) {
    1315           0 :     if ( event->type==et_close ) {
    1316           0 :         AI_DoCancel( GDrawGetUserData(gw));
    1317           0 :     } else if ( event->type==et_char ) {
    1318           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
    1319           0 :             help("getinfo.html");
    1320           0 : return( true );
    1321             :         }
    1322           0 : return( false );
    1323           0 :     } else if ( event->type == et_map ) {
    1324             :         /* Above palettes */
    1325           0 :         GDrawRaise(gw);
    1326             :     }
    1327           0 : return( true );
    1328             : }
    1329             : 
    1330           0 : static int AI_Cancel(GGadget *g, GEvent *e) {
    1331           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1332           0 :         AI_DoCancel( GDrawGetUserData(GGadgetGetWindow(g)));
    1333             :     }
    1334           0 : return( true );
    1335             : }
    1336             : 
    1337           0 : static int AI_Ok(GGadget *g, GEvent *e) {
    1338           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1339           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1340           0 :         ci->done = true;
    1341             :         /* All the work has been done as we've gone along */
    1342             :         /* Well, we should reorder the list... */
    1343           0 :         SCOrderAP(ci->cv->b.sc);
    1344             :     }
    1345           0 : return( true );
    1346             : }
    1347             : 
    1348           0 : void ApGetInfo(CharView *cv, AnchorPoint *ap) {
    1349             :     static GIData gi;
    1350             :     GRect pos;
    1351             :     GWindowAttrs wattrs;
    1352             :     GGadgetCreateData gcd[25], boxes[10], *varray[21], *harray1[5], *harray2[3],
    1353             :         *hvarray[13], *harray3[4], *harray4[6], *harray5[6], *harray6[7];
    1354             :     GTextInfo label[25];
    1355             :     int j;
    1356             :     SplineFont *sf;
    1357             :     GTextInfo **ti;
    1358             : 
    1359           0 :     memset(&gi,0,sizeof(gi));
    1360           0 :     gi.cv = cv;
    1361           0 :     gi.sc = cv->b.sc;
    1362           0 :     gi.oldaps = AnchorPointsCopy(cv->b.sc->anchor);
    1363           0 :     CVPreserveState(&cv->b);
    1364           0 :     if ( ap==NULL ) {
    1365           0 :         ap = AnchorPointNew(cv);
    1366           0 :         if ( ap==NULL )
    1367           0 : return;
    1368             :     }
    1369             : 
    1370           0 :     gi.ap = ap;
    1371           0 :     gi.changed = false;
    1372           0 :     gi.done = false;
    1373             : 
    1374           0 :         memset(&wattrs,0,sizeof(wattrs));
    1375           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    1376           0 :         wattrs.event_masks = ~(1<<et_charup);
    1377           0 :         wattrs.restrict_input_to_me = 1;
    1378           0 :         wattrs.undercursor = 1;
    1379           0 :         wattrs.cursor = ct_pointer;
    1380           0 :         wattrs.utf8_window_title = _("Anchor Point Info");
    1381           0 :         wattrs.is_dlg = true;
    1382           0 :         pos.x = pos.y = 0;
    1383           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,AI_Width));
    1384           0 :         pos.height = GDrawPointsToPixels(NULL,AI_Height);
    1385           0 :         gi.gw = GDrawCreateTopWindow(NULL,&pos,ai_e_h,&gi,&wattrs);
    1386             : 
    1387           0 :         memset(&gcd,0,sizeof(gcd));
    1388           0 :         memset(&label,0,sizeof(label));
    1389           0 :         memset(&boxes,0,sizeof(boxes));
    1390             : 
    1391           0 :         j=0;
    1392           0 :         label[j].text = (unichar_t *) ap->anchor->name;
    1393           0 :         label[j].text_is_1byte = true;
    1394           0 :         gcd[j].gd.label = &label[j];
    1395           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = 5;
    1396           0 :         gcd[j].gd.pos.width = AI_Width-10;
    1397           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1398           0 :         gcd[j].gd.cid = CID_NameList;
    1399           0 :         sf = cv->b.sc->parent;
    1400           0 :         if ( sf->cidmaster ) sf = sf->cidmaster;
    1401           0 :         gcd[j].gd.handle_controlevent = AI_ANameChanged;
    1402           0 :         gcd[j].creator = GListButtonCreate;
    1403           0 :         varray[0] = &gcd[j]; varray[1] = NULL;
    1404           0 :         ++j;
    1405             : 
    1406           0 :         label[j].text = (unichar_t *) _("_X:");
    1407           0 :         label[j].text_is_1byte = true;
    1408           0 :         label[j].text_in_resource = true;
    1409           0 :         gcd[j].gd.label = &label[j];
    1410           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+34;
    1411           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1412           0 :         gcd[j].creator = GLabelCreate;
    1413           0 :         harray1[0] = &gcd[j];
    1414           0 :         ++j;
    1415             : 
    1416           0 :         gcd[j].gd.pos.x = 23; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4;
    1417           0 :         gcd[j].gd.pos.width = 50;
    1418           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1419           0 :         gcd[j].gd.cid = CID_X;
    1420           0 :         gcd[j].gd.handle_controlevent = AI_PosChanged;
    1421           0 :         gcd[j].creator = GNumericFieldCreate;
    1422           0 :         harray1[1] = &gcd[j];
    1423           0 :         ++j;
    1424             : 
    1425           0 :         label[j].text = (unichar_t *) _("_Y:");
    1426           0 :         label[j].text_is_1byte = true;
    1427           0 :         label[j].text_in_resource = true;
    1428           0 :         gcd[j].gd.label = &label[j];
    1429           0 :         gcd[j].gd.pos.x = 85; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y;
    1430           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1431           0 :         gcd[j].creator = GLabelCreate;
    1432           0 :         harray1[2] = &gcd[j];
    1433           0 :         ++j;
    1434             : 
    1435           0 :         gcd[j].gd.pos.x = 103; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y;
    1436           0 :         gcd[j].gd.pos.width = 50;
    1437           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1438           0 :         gcd[j].gd.cid = CID_Y;
    1439           0 :         gcd[j].gd.handle_controlevent = AI_PosChanged;
    1440           0 :         gcd[j].creator = GNumericFieldCreate;
    1441           0 :         harray1[3] = &gcd[j]; harray1[4] = NULL;
    1442           0 :         ++j;
    1443             : 
    1444           0 :         boxes[2].gd.flags = gg_enabled|gg_visible;
    1445           0 :         boxes[2].gd.u.boxelements = harray1;
    1446           0 :         boxes[2].creator = GHBoxCreate;
    1447           0 :         varray[2] = &boxes[2]; varray[3] = NULL;
    1448             : 
    1449           0 :         label[j].text = (unichar_t *) _("Matching TTF Point:");
    1450           0 :         label[j].text_is_1byte = true;
    1451           0 :         gcd[j].gd.label = &label[j];
    1452           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y+24;
    1453           0 :         gcd[j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible) : gg_visible;
    1454           0 :         gcd[j].creator = GLabelCreate;
    1455           0 :         harray2[0] = &gcd[j];
    1456           0 :         ++j;
    1457             : 
    1458           0 :         gcd[j].gd.pos.x = 103; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
    1459           0 :         gcd[j].gd.pos.width = 50;
    1460           0 :         gcd[j].gd.flags = gcd[j-1].gd.flags;
    1461           0 :         gcd[j].gd.cid = CID_MatchPt;
    1462           0 :         gcd[j].gd.handle_controlevent = AI_MatchChanged;
    1463           0 :         gcd[j].creator = GTextFieldCreate;
    1464           0 :         harray2[1] = &gcd[j]; harray2[2] = NULL;
    1465           0 :         ++j;
    1466             : 
    1467           0 :         boxes[3].gd.flags = gg_enabled|gg_visible;
    1468           0 :         boxes[3].gd.u.boxelements = harray2;
    1469           0 :         boxes[3].creator = GHBoxCreate;
    1470           0 :         varray[4] = &boxes[3]; varray[5] = NULL;
    1471             : 
    1472           0 :         label[j].text = (unichar_t *) _("Mark");
    1473           0 :         label[j].text_is_1byte = true;
    1474           0 :         gcd[j].gd.label = &label[j];
    1475           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
    1476           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1477           0 :         gcd[j].gd.cid = CID_Mark;
    1478           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1479           0 :         gcd[j].creator = GRadioCreate;
    1480           0 :         hvarray[0] = &gcd[j];
    1481           0 :         ++j;
    1482             : 
    1483           0 :         label[j].text = (unichar_t *) _("Base Glyph");
    1484           0 :         label[j].text_is_1byte = true;
    1485           0 :         gcd[j].gd.label = &label[j];
    1486           0 :         gcd[j].gd.pos.x = 70; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1487           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1488           0 :         gcd[j].gd.cid = CID_BaseChar;
    1489           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1490           0 :         gcd[j].creator = GRadioCreate;
    1491           0 :         hvarray[1] = &gcd[j]; hvarray[2] = NULL;
    1492           0 :         ++j;
    1493             : 
    1494           0 :         label[j].text = (unichar_t *) _("Base Lig");
    1495           0 :         label[j].text_is_1byte = true;
    1496           0 :         gcd[j].gd.label = &label[j];
    1497           0 :         gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
    1498           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1499           0 :         gcd[j].gd.cid = CID_BaseLig;
    1500           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1501           0 :         gcd[j].creator = GRadioCreate;
    1502           0 :         hvarray[3] = &gcd[j];
    1503           0 :         ++j;
    1504             : 
    1505           0 :         label[j].text = (unichar_t *) _("Base Mark");
    1506           0 :         label[j].text_is_1byte = true;
    1507           0 :         gcd[j].gd.label = &label[j];
    1508           0 :         gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1509           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1510           0 :         gcd[j].gd.cid = CID_BaseMark;
    1511           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1512           0 :         gcd[j].creator = GRadioCreate;
    1513           0 :         hvarray[4] = &gcd[j]; hvarray[5] = NULL;
    1514           0 :         ++j;
    1515             : 
    1516             : /* GT: Cursive Entry. This defines a point on the glyph that should be matched */
    1517             : /* GT: with the "Cursive Exit" point of the preceding glyph.  */
    1518             : /* GT: This is a special way of joining letters which was developed for Urdu */
    1519             : /* GT: fonts. Essentially every glyph has an entry point and an exit point. */
    1520             : /* GT: When written the glyphs in sequence are aligned so that the exit point */
    1521             : /* GT: of each glyph matches the entry point of the following. It means you */
    1522             : /* GT: get a join such as might be expected for script. Urdu is odd because */
    1523             : /* GT: letters within a word crawl diagonally up the page, but with each word */
    1524             : /* GT: the writing point starts at the baseline. */
    1525           0 :         label[j].text = (unichar_t *) _("CursEntry");
    1526           0 :         label[j].text_is_1byte = true;
    1527           0 :         gcd[j].gd.label = &label[j];
    1528           0 :         gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
    1529           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1530           0 :         gcd[j].gd.cid = CID_CursEntry;
    1531           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1532           0 :         gcd[j].creator = GRadioCreate;
    1533           0 :         hvarray[6] = &gcd[j];
    1534           0 :         ++j;
    1535             : 
    1536             : /* GT: Cursive Exit. This defines a point on the glyph that should be matched */
    1537             : /* GT: with the "Cursive Entry" point of the following glyph. This allows */
    1538             : /* GT: scripts such as Urdu to work */
    1539           0 :         label[j].text = (unichar_t *) _("CursExit");
    1540           0 :         label[j].text_is_1byte = true;
    1541           0 :         gcd[j].gd.label = &label[j];
    1542           0 :         gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1543           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1544           0 :         gcd[j].gd.cid = CID_CursExit;
    1545           0 :         gcd[j].gd.handle_controlevent = AI_TypeChanged;
    1546           0 :         gcd[j].creator = GRadioCreate;
    1547           0 :         hvarray[7] = &gcd[j]; hvarray[8] = NULL; hvarray[9] = NULL;
    1548           0 :         ++j;
    1549             : 
    1550           0 :         boxes[4].gd.flags = gg_enabled|gg_visible;
    1551           0 :         boxes[4].gd.u.boxelements = hvarray;
    1552           0 :         boxes[4].creator = GHVBoxCreate;
    1553           0 :         varray[6] = &boxes[4]; varray[7] = NULL;
    1554             : 
    1555           0 :         label[j].text = (unichar_t *) _("Lig Index:");
    1556           0 :         label[j].text_is_1byte = true;
    1557           0 :         gcd[j].gd.label = &label[j];
    1558           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+26;
    1559           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1560           0 :         gcd[j].creator = GLabelCreate;
    1561           0 :         harray3[0] = &gcd[j];
    1562           0 :         ++j;
    1563             : 
    1564           0 :         gcd[j].gd.pos.x = 65; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4;
    1565           0 :         gcd[j].gd.pos.width = 50;
    1566           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1567           0 :         gcd[j].gd.cid = CID_LigIndex;
    1568           0 :         gcd[j].gd.handle_controlevent = AI_LigIndexChanged;
    1569           0 :         gcd[j].creator = GNumericFieldCreate;
    1570           0 :         harray3[1] = &gcd[j]; harray3[2] = NULL;
    1571           0 :         ++j;
    1572             : 
    1573           0 :         boxes[5].gd.flags = gg_enabled|gg_visible;
    1574           0 :         boxes[5].gd.u.boxelements = harray3;
    1575           0 :         boxes[5].creator = GHBoxCreate;
    1576           0 :         varray[8] = &boxes[5]; varray[9] = NULL;
    1577             : 
    1578           0 :         label[j].text = (unichar_t *) S_("AnchorPoint|_New");
    1579           0 :         label[j].text_is_1byte = true;
    1580           0 :         label[j].text_in_resource = true;
    1581           0 :         gcd[j].gd.label = &label[j];
    1582           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+30;
    1583           0 :         gcd[j].gd.pos.width = -1;
    1584           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1585           0 :         gcd[j].gd.cid = CID_New;
    1586           0 :         gcd[j].gd.handle_controlevent = AI_New;
    1587           0 :         gcd[j].creator = GButtonCreate;
    1588           0 :         harray4[0] = &gcd[j]; harray4[1] = GCD_Glue;
    1589           0 :         ++j;
    1590             : 
    1591           0 :         label[j].text = (unichar_t *) S_("AnchorClass|New _Class");
    1592           0 :         label[j].text_is_1byte = true;
    1593           0 :         label[j].text_in_resource = true;
    1594           0 :         gcd[j].gd.label = &label[j];
    1595           0 :         gcd[j].gd.pos.x = 30; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1596           0 :         gcd[j].gd.pos.width = -1;
    1597           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1598           0 :         gcd[j].gd.cid = CID_New;
    1599           0 :         gcd[j].gd.handle_controlevent = AI_NewClass;
    1600           0 :         gcd[j].creator = GButtonCreate;
    1601           0 :         harray4[2] = &gcd[j]; harray4[3] = GCD_Glue;
    1602           0 :         ++j;
    1603             : 
    1604           0 :         label[j].text = (unichar_t *) _("_Delete");
    1605           0 :         label[j].text_is_1byte = true;
    1606           0 :         label[j].text_in_resource = true;
    1607           0 :         gcd[j].gd.label = &label[j];
    1608           0 :         gcd[j].gd.pos.x = -5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1609           0 :         gcd[j].gd.pos.width = -1;
    1610           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1611           0 :         gcd[j].gd.cid = CID_Delete;
    1612           0 :         gcd[j].gd.handle_controlevent = AI_Delete;
    1613           0 :         gcd[j].creator = GButtonCreate;
    1614           0 :         harray4[4] = &gcd[j]; harray4[5] = NULL;
    1615           0 :         ++j;
    1616             : 
    1617           0 :         boxes[6].gd.flags = gg_enabled|gg_visible;
    1618           0 :         boxes[6].gd.u.boxelements = harray4;
    1619           0 :         boxes[6].creator = GHBoxCreate;
    1620           0 :         varray[10] = &boxes[6]; varray[11] = NULL;
    1621             : 
    1622           0 :         label[j].text = (unichar_t *) _("< _Prev");
    1623           0 :         label[j].text_is_1byte = true;
    1624           0 :         label[j].text_in_resource = true;
    1625           0 :         gcd[j].gd.label = &label[j];
    1626           0 :         gcd[j].gd.pos.x = 15; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
    1627           0 :         gcd[j].gd.pos.width = -1;
    1628           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1629           0 :         gcd[j].gd.cid = CID_Prev;
    1630           0 :         gcd[j].gd.handle_controlevent = AI_Prev;
    1631           0 :         gcd[j].creator = GButtonCreate;
    1632           0 :         harray5[0] = GCD_Glue; harray5[1] = &gcd[j]; harray5[2] = GCD_Glue;
    1633           0 :         ++j;
    1634             : 
    1635           0 :         label[j].text = (unichar_t *) _("_Next >");
    1636           0 :         label[j].text_is_1byte = true;
    1637           0 :         label[j].text_in_resource = true;
    1638           0 :         gcd[j].gd.label = &label[j];
    1639           0 :         gcd[j].gd.pos.x = -15; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    1640           0 :         gcd[j].gd.pos.width = -1;
    1641           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1642           0 :         gcd[j].gd.cid = CID_Next;
    1643           0 :         gcd[j].gd.handle_controlevent = AI_Next;
    1644           0 :         gcd[j].creator = GButtonCreate;
    1645           0 :         harray5[3] = &gcd[j]; harray5[4] = GCD_Glue; harray5[5] = NULL;
    1646           0 :         ++j;
    1647             : 
    1648           0 :         boxes[7].gd.flags = gg_enabled|gg_visible;
    1649           0 :         boxes[7].gd.u.boxelements = harray5;
    1650           0 :         boxes[7].creator = GHBoxCreate;
    1651           0 :         varray[12] = &boxes[7]; varray[13] = NULL;
    1652             : 
    1653           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+26;
    1654           0 :         gcd[j].gd.pos.width = AI_Width-10;
    1655           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    1656           0 :         gcd[j].creator = GLineCreate;
    1657           0 :         varray[14] = GCD_Glue; varray[15] = NULL;
    1658           0 :         varray[16] = &gcd[j]; varray[17] = NULL;
    1659           0 :         ++j;
    1660             : 
    1661           0 :         label[j].text = (unichar_t *) _("_OK");
    1662           0 :         label[j].text_is_1byte = true;
    1663           0 :         label[j].text_in_resource = true;
    1664           0 :         gcd[j].gd.label = &label[j];
    1665           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+4;
    1666           0 :         gcd[j].gd.pos.width = -1;
    1667           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_but_default;
    1668           0 :         gcd[j].gd.handle_controlevent = AI_Ok;
    1669           0 :         gcd[j].creator = GButtonCreate;
    1670           0 :         harray6[0] = &gcd[j]; harray6[1] = GCD_Glue;
    1671           0 :         ++j;
    1672             : 
    1673           0 :         label[j].text = (unichar_t *) _("_Cancel");
    1674           0 :         label[j].text_is_1byte = true;
    1675           0 :         label[j].text_in_resource = true;
    1676           0 :         gcd[j].gd.label = &label[j];
    1677           0 :         gcd[j].gd.pos.x = -5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+3;
    1678           0 :         gcd[j].gd.pos.width = -1;
    1679           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_but_cancel;
    1680           0 :         gcd[j].gd.handle_controlevent = AI_Cancel;
    1681           0 :         gcd[j].creator = GButtonCreate;
    1682           0 :         harray6[2] = &gcd[j]; harray6[3] = NULL;
    1683           0 :         ++j;
    1684             : 
    1685           0 :         boxes[8].gd.flags = gg_enabled|gg_visible;
    1686           0 :         boxes[8].gd.u.boxelements = harray6;
    1687           0 :         boxes[8].creator = GHBoxCreate;
    1688           0 :         varray[18] = &boxes[8]; varray[19] = NULL;
    1689           0 :         varray[20] = NULL;
    1690             : 
    1691           0 :         boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    1692           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
    1693           0 :         boxes[0].gd.u.boxelements = varray;
    1694           0 :         boxes[0].creator = GHVGroupCreate;
    1695             : 
    1696           0 :         GGadgetsCreate(gi.gw,boxes);
    1697           0 :         GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
    1698           0 :         GHVBoxSetExpandableCol(boxes[8].ret,gb_expandgluesame);
    1699           0 :         GHVBoxSetExpandableCol(boxes[7].ret,gb_expandgluesame);
    1700           0 :         GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
    1701           0 :         GHVBoxFitWindow(boxes[0].ret);
    1702             : 
    1703           0 :         GGadgetSetList(GWidgetGetControl(gi.gw,CID_NameList),
    1704           0 :                     ti = AnchorClassesLList(gi.sc->parent),false);
    1705           0 :         for ( j=0; ti[j]->text!=NULL && ti[j]->userdata!=ap->anchor; ++j )
    1706           0 :         GGadgetSelectOneListItem(GWidgetGetControl(gi.gw,CID_NameList),j);
    1707             : 
    1708           0 :         AI_Display(&gi,ap);
    1709           0 :         GWidgetIndicateFocusGadget(GWidgetGetControl(gi.gw,CID_X));
    1710             : 
    1711           0 :     GWidgetHidePalettes();
    1712           0 :     GDrawSetVisible(gi.gw,true);
    1713           0 :     while ( !gi.done )
    1714           0 :         GDrawProcessOneEvent(NULL);
    1715           0 :     GDrawDestroyWindow(gi.gw);
    1716           0 :     AnchorPointsFree(gi.oldaps);
    1717             : }
    1718             : 
    1719           0 : void PI_ShowHints(SplineChar *sc, GGadget *list, int set) {
    1720             :     StemInfo *h;
    1721             :     int32 i, len;
    1722             : 
    1723           0 :     if ( !set ) {
    1724           0 :         for ( h = sc->hstem; h!=NULL; h=h->next )
    1725           0 :             h->active = false;
    1726           0 :         for ( h = sc->vstem; h!=NULL; h=h->next )
    1727           0 :             h->active = false;
    1728             :     } else {
    1729           0 :         GTextInfo **ti = GGadgetGetList(list,&len);
    1730           0 :         for ( h = sc->hstem, i=0; h!=NULL && i<len; h=h->next, ++i )
    1731           0 :             h->active = ti[i]->selected;
    1732           0 :         for ( h = sc->vstem; h!=NULL && i<len; h=h->next, ++i )
    1733           0 :             h->active = ti[i]->selected;
    1734             :     }
    1735           0 :     SCOutOfDateBackground(sc);
    1736           0 :     SCUpdateAll(sc);
    1737           0 : }
    1738             : 
    1739           0 : static void _PI_ShowHints(GIData *ci,int set) {
    1740           0 :     PI_ShowHints(ci->cv->b.sc,GWidgetGetControl(ci->gw,CID_HintMask),set);
    1741           0 : }
    1742             : 
    1743           0 : static void PI_DoCancel(GIData *ci) {
    1744           0 :     CharView *cv = ci->cv;
    1745           0 :     ci->done = true;
    1746           0 :     if ( cv->b.drawmode==dm_fore )
    1747           0 :         MDReplace(cv->b.sc->md,cv->b.sc->layers[ly_fore].splines,ci->oldstate);
    1748           0 :     SplinePointListsFree(cv->b.layerheads[cv->b.drawmode]->splines);
    1749           0 :     cv->b.layerheads[cv->b.drawmode]->splines = ci->oldstate;
    1750           0 :     CVRemoveTopUndo(&cv->b);
    1751           0 :     SCClearSelPt(cv->b.sc);
    1752           0 :     _PI_ShowHints(ci,false);
    1753           0 :     SCUpdateAll(cv->b.sc);
    1754           0 : }
    1755             : 
    1756           0 : static int pi_e_h(GWindow gw, GEvent *event) {
    1757           0 :     if ( event->type==et_close ) {
    1758           0 :         GIData  *d = GDrawGetUserData(gw);
    1759           0 :         if( d->nonmodal ) {
    1760           0 :             PI_Destroy((struct dlistnode *)d);
    1761             :         } else {
    1762           0 :             PI_DoCancel( GDrawGetUserData(gw));
    1763             :         }
    1764           0 :     } else if ( event->type==et_char ) {
    1765           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
    1766           0 :             help("getinfo.html");
    1767           0 : return( true );
    1768             :         }
    1769           0 : return( false );
    1770           0 :     } else if ( event->type == et_map ) {
    1771             :         /* Above palettes */
    1772           0 :         GDrawRaise(gw);
    1773             :     }
    1774           0 : return( true );
    1775             : }
    1776             : 
    1777             : static void PIFillup(GIData *ci, int except_cid);
    1778             : 
    1779           0 : static void PI_FigureNext(GIData *ci) {
    1780           0 :     if ( ci->prevchanged ) {
    1781           0 :         SplinePoint *cursp = ci->cursp;
    1782           0 :         if ( !ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 && (cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve)) {
    1783             :             double dx, dy, len, len2;
    1784           0 :             dx = cursp->prevcp.x - cursp->me.x;
    1785           0 :             dy = cursp->prevcp.y - cursp->me.y;
    1786           0 :             len = sqrt(dx*dx+dy*dy);
    1787           0 :             if ( len!=0 ) {
    1788           0 :                 len2 = sqrt((cursp->nextcp.x-cursp->me.x)*(cursp->nextcp.x-cursp->me.x)+
    1789           0 :                         (cursp->nextcp.y-cursp->me.y)*(cursp->nextcp.y-cursp->me.y));
    1790           0 :                 cursp->nextcp.x=cursp->me.x-dx*len2/len;
    1791           0 :                 cursp->nextcp.y=cursp->me.y-dy*len2/len;
    1792           0 :                 if ( cursp->next!=NULL )
    1793           0 :                     SplineRefigure(cursp->next);
    1794           0 :                 CVCharChangedUpdate(&ci->cv->b);
    1795           0 :                 PIFillup(ci,-1);
    1796             :             }
    1797             :         }
    1798             :     }
    1799           0 :     ci->prevchanged = false;
    1800           0 : }
    1801             : 
    1802           0 : static void PI_FigurePrev(GIData *ci) {
    1803           0 :     if ( ci->nextchanged ) {
    1804           0 :         SplinePoint *cursp = ci->cursp;
    1805           0 :         if ( !ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 && (cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve)) {
    1806             :             double dx, dy, len, len2;
    1807           0 :             dx = cursp->nextcp.x - cursp->me.x;
    1808           0 :             dy = cursp->nextcp.y - cursp->me.y;
    1809           0 :             len = sqrt(dx*dx+dy*dy);
    1810           0 :             if ( len!=0 ) {
    1811           0 :                 len2 = sqrt((cursp->prevcp.x-cursp->me.x)*(cursp->prevcp.x-cursp->me.x)+
    1812           0 :                         (cursp->prevcp.y-cursp->me.y)*(cursp->prevcp.y-cursp->me.y));
    1813           0 :                 cursp->prevcp.x=cursp->me.x-dx*len2/len;
    1814           0 :                 cursp->prevcp.y=cursp->me.y-dy*len2/len;
    1815           0 :                 if ( cursp->prev!=NULL )
    1816           0 :                     SplineRefigure(cursp->prev);
    1817           0 :                 CVCharChangedUpdate(&ci->cv->b);
    1818           0 :                 PIFillup(ci,-1);
    1819             :             }
    1820             :         }
    1821             :     }
    1822           0 :     ci->nextchanged = false;
    1823           0 : }
    1824             : 
    1825           0 : static void PI_FigureHintMask(GIData *ci) {
    1826             :     int32 i, len;
    1827           0 :     GTextInfo **ti = GGadgetGetList(GWidgetGetControl(ci->gw,CID_HintMask),&len);
    1828             : 
    1829           0 :     for ( i=0; i<len; ++i )
    1830           0 :         if ( ti[i]->selected )
    1831           0 :     break;
    1832             : 
    1833           0 :     if ( i==len ) {
    1834           0 :         chunkfree(ci->cursp->hintmask,sizeof(HintMask));
    1835           0 :         ci->cursp->hintmask = NULL;
    1836             :     } else {
    1837           0 :         if ( ci->cursp->hintmask==NULL )
    1838           0 :             ci->cursp->hintmask = chunkalloc(sizeof(HintMask));
    1839             :         else
    1840           0 :             memset(ci->cursp->hintmask,0,sizeof(HintMask));
    1841           0 :         for ( i=0; i<len; ++i )
    1842           0 :             if ( ti[i]->selected )
    1843           0 :                 (*ci->cursp->hintmask)[i>>3] |= (0x80>>(i&7));
    1844             :     }
    1845           0 : }
    1846             : 
    1847           0 : static void PI_FixStuff(GIData *ci) {
    1848           0 :     SplinePoint *sp = ci->cursp;
    1849             : 
    1850           0 :     PI_FigureHintMask(ci);
    1851           0 :     PI_FigureNext(ci);
    1852           0 :     PI_FigurePrev(ci);
    1853             : 
    1854           0 :     if ( sp->pointtype == pt_hvcurve ) {
    1855           0 :         if (
    1856           0 :                 ((sp->nextcp.x==sp->me.x && sp->prevcp.x==sp->me.x && sp->nextcp.y!=sp->me.y) ||
    1857           0 :                  (sp->nextcp.y==sp->me.y && sp->prevcp.y==sp->me.y && sp->nextcp.x!=sp->me.x)))
    1858             :             /* Do Nothing */;
    1859             :         else
    1860           0 :             sp->pointtype = pt_curve;
    1861           0 :     } else if ( sp->pointtype == pt_tangent )
    1862           0 :         SplinePointCategorize(sp);      /* Users can change cps so it isn't a tangent, so check */
    1863           0 : }
    1864             : 
    1865           0 : void PI_Destroy(struct dlistnode *node) {
    1866           0 :     GIData *d = (GIData *)node;
    1867           0 :     GDrawDestroyWindow(d->gw);
    1868           0 :     dlist_erase(&d->cv->pointInfoDialogs,(struct dlistnode *)d);
    1869           0 :     free(d);
    1870           0 : }
    1871             : 
    1872           0 : static void PI_Close(GGadget *g) {
    1873           0 :     GWindow gw = GGadgetGetWindow(g);
    1874           0 :     GIData  *d = GDrawGetUserData(gw);
    1875           0 :     PI_Destroy((struct dlistnode *)d);
    1876           0 : }
    1877             : 
    1878           0 : static int PI_Cancel(GGadget *g, GEvent *e) {
    1879           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1880           0 :         PI_DoCancel( GDrawGetUserData(GGadgetGetWindow(g)));
    1881           0 :         PI_Close(g);
    1882             :     }
    1883           0 : return( true );
    1884             : }
    1885             : 
    1886           0 : static int PI_Ok(GGadget *g, GEvent *e) {
    1887           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1888           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    1889             : 
    1890           0 :         PI_FixStuff(ci);
    1891           0 :         _PI_ShowHints(ci,false);
    1892             : 
    1893           0 :         ci->done = true;
    1894             :         /* All the work has been done as we've gone along */
    1895           0 :         PI_Close(g);
    1896             :     }
    1897             : 
    1898           0 : return( true );
    1899             : }
    1900             : 
    1901           0 : static void mysprintf( char *buffer, char *format, real v) {
    1902             :     char *pt;
    1903             : 
    1904           0 :     if ( v<.0001 && v>-.0001 && v!=0 )
    1905           0 :         sprintf( buffer, "%e", (double) v );
    1906           0 :     else if ( v<1 && v>0 )
    1907           0 :         sprintf( buffer, "%f", (double) v );
    1908           0 :     else if ( v<0 && v>-1 )
    1909           0 :         sprintf( buffer, "%.5f", (double) v );
    1910             :     else
    1911           0 :         sprintf( buffer, format, (double) v );
    1912           0 :     pt = buffer + strlen(buffer);
    1913           0 :     while ( pt>buffer && pt[-1]=='0' )
    1914           0 :         *--pt = '\0';
    1915           0 :     if ( pt>buffer && pt[-1]=='.' )
    1916           0 :         pt[-1] = '\0';
    1917           0 : }
    1918             : 
    1919           0 : static void mysprintf2( char *buffer, real v1, real v2) {
    1920             :     char *pt;
    1921             : 
    1922           0 :     mysprintf(buffer,"%.2f", v1);
    1923           0 :     pt = buffer+strlen(buffer);
    1924           0 :     *pt++ = ',';
    1925           0 :     mysprintf(pt,"%.2f", v2);
    1926           0 : }
    1927             : 
    1928           0 : static void PIFillup(GIData *ci, int except_cid) {
    1929             :     char buffer[51];
    1930             :     double dx, dy;
    1931             :     double kappa, kappa2;
    1932             :     int emsize;
    1933             : 
    1934           0 :     mysprintf(buffer, "%.2f", ci->cursp->me.x );
    1935           0 :     if ( except_cid!=CID_BaseX )
    1936           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseX),buffer);
    1937             : 
    1938           0 :     mysprintf(buffer, "%.2f", ci->cursp->me.y );
    1939           0 :     if ( except_cid!=CID_BaseY )
    1940           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseY),buffer);
    1941             : 
    1942           0 :     dx = ci->cursp->nextcp.x-ci->cursp->me.x;
    1943           0 :     dy = ci->cursp->nextcp.y-ci->cursp->me.y;
    1944           0 :     mysprintf(buffer, "%.2f", dx );
    1945           0 :     if ( except_cid!=CID_NextXOff )
    1946           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextXOff),buffer);
    1947             : 
    1948           0 :     mysprintf(buffer, "%.2f", dy );
    1949           0 :     if ( except_cid!=CID_NextYOff )
    1950           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextYOff),buffer);
    1951             : 
    1952           0 :     if ( except_cid!=CID_NextR ) {
    1953           0 :         mysprintf(buffer, "%.2f", sqrt( dx*dx+dy*dy ));
    1954           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextR),buffer);
    1955             :     }
    1956             : 
    1957           0 :     if ( except_cid!=CID_NextTheta ) {
    1958           0 :         if ( ci->cursp->pointtype==pt_tangent && ci->cursp->prev!=NULL ) {
    1959           0 :             dx = ci->cursp->me.x-ci->cursp->prev->from->me.x;
    1960           0 :             dy = ci->cursp->me.y-ci->cursp->prev->from->me.y;
    1961             :         }
    1962           0 :         mysprintf(buffer, "%.1f", atan2(dy,dx)*RAD2DEG);
    1963           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextTheta),buffer);
    1964             :     }
    1965             : 
    1966           0 :     mysprintf2(buffer, ci->cursp->nextcp.x,ci->cursp->nextcp.y );
    1967           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextPos),buffer);
    1968             : 
    1969           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NextDef), ci->cursp->nextcpdef );
    1970             : 
    1971           0 :     dx = ci->cursp->prevcp.x-ci->cursp->me.x;
    1972           0 :     dy = ci->cursp->prevcp.y-ci->cursp->me.y;
    1973           0 :     mysprintf(buffer, "%.2f", dx );
    1974           0 :     if ( except_cid!=CID_PrevXOff )
    1975           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevXOff),buffer);
    1976             : 
    1977           0 :     mysprintf(buffer, "%.2f", dy );
    1978           0 :     if ( except_cid!=CID_PrevYOff )
    1979           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevYOff),buffer);
    1980             : 
    1981           0 :     if ( except_cid!=CID_PrevR ) {
    1982           0 :         mysprintf(buffer, "%.2f", sqrt( dx*dx+dy*dy ));
    1983           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevR),buffer);
    1984             :     }
    1985             : 
    1986           0 :     if ( except_cid!=CID_PrevTheta ) {
    1987           0 :         if ( ci->cursp->pointtype==pt_tangent && ci->cursp->next!=NULL ) {
    1988           0 :             dx = ci->cursp->me.x-ci->cursp->next->to->me.x;
    1989           0 :             dy = ci->cursp->me.y-ci->cursp->next->to->me.y;
    1990             :         }
    1991           0 :         mysprintf(buffer, "%.1f", atan2(dy,dx)*RAD2DEG);
    1992           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevTheta),buffer);
    1993             :     }
    1994             : 
    1995           0 :     mysprintf2(buffer, ci->cursp->prevcp.x,ci->cursp->prevcp.y );
    1996           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevPos),buffer);
    1997             : 
    1998             : 
    1999           0 :     mysprintf2(buffer, ci->cursp->me.x,ci->cursp->me.y );
    2000           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BasePos),buffer);
    2001             : 
    2002           0 :     mysprintf(buffer, "%.2f", ci->cursp->nextcp.x );
    2003           0 :     if ( except_cid!=CID_NextX )
    2004           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextX),buffer);
    2005             : 
    2006           0 :     mysprintf(buffer, "%.2f", ci->cursp->nextcp.y );
    2007           0 :     if ( except_cid!=CID_NextY )
    2008           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextY),buffer);
    2009             : 
    2010           0 :     mysprintf(buffer, "%.2f", ci->cursp->prevcp.x );
    2011           0 :     if ( except_cid!=CID_PrevX )
    2012           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevX),buffer);
    2013             : 
    2014           0 :     mysprintf(buffer, "%.2f", ci->cursp->prevcp.y );
    2015           0 :     if ( except_cid!=CID_PrevY )
    2016           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevY),buffer);
    2017             : 
    2018             : 
    2019           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_PrevDef), ci->cursp->prevcpdef );
    2020             : 
    2021           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve), ci->cursp->pointtype==pt_curve );
    2022           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_HVCurve), ci->cursp->pointtype==pt_hvcurve );
    2023           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Corner), ci->cursp->pointtype==pt_corner );
    2024           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Tangent), ci->cursp->pointtype==pt_tangent );
    2025             : 
    2026           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevTheta), ci->cursp->pointtype!=pt_tangent );
    2027           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextTheta), ci->cursp->pointtype!=pt_tangent );
    2028             : 
    2029           0 :     kappa = SplineCurvature(ci->cursp->next,0);
    2030           0 :     kappa2 = SplineCurvature(ci->cursp->prev,1);
    2031           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevCurvature), kappa2!=CURVATURE_ERROR );
    2032           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextCurvature), kappa!=CURVATURE_ERROR );
    2033           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_DeltaCurvature),
    2034             :             kappa!=CURVATURE_ERROR && kappa2!=CURVATURE_ERROR );
    2035           0 :     emsize = ci->cv->b.sc->parent->ascent + ci->cv->b.sc->parent->descent;
    2036             :     /* If we normalize by the em-size, the curvature is often more */
    2037             :     /*  readable */
    2038           0 :     if ( kappa!=CURVATURE_ERROR )
    2039           0 :         sprintf( buffer, _("Curvature: %g"), kappa*emsize );
    2040             :     else
    2041           0 :         strcpy( buffer, _("Curvature: ?"));
    2042           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextCurvature),buffer);
    2043           0 :     if ( kappa2!=CURVATURE_ERROR )
    2044           0 :         sprintf( buffer, _("Curvature: %g"), kappa2*emsize );
    2045             :     else
    2046           0 :         strncpy( buffer, _("Curvature: ?"),sizeof(buffer)-1 );
    2047           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevCurvature),buffer);
    2048           0 :     if ( kappa!=CURVATURE_ERROR && kappa2!=CURVATURE_ERROR )
    2049           0 :         sprintf( buffer, "∆: %g", (kappa-kappa2)*emsize );
    2050             :     else
    2051           0 :         strcpy( buffer, "∆: ?");
    2052           0 :     GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_DeltaCurvature),buffer);
    2053           0 : }
    2054             : 
    2055           0 : static void PIShowHide(GIData *ci) {
    2056           0 :     int normal = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Normal));
    2057             :     int i;
    2058             : 
    2059           0 :     for ( i=ci->normal_start; i<ci->normal_end; ++i )
    2060           0 :         if ( ci->gcd[i].ret!=NULL )
    2061           0 :             GGadgetSetVisible(ci->gcd[i].ret,normal);
    2062           0 :     GGadgetSetVisible(ci->group1ret,normal);
    2063           0 :     GGadgetSetVisible(ci->group2ret,normal);
    2064           0 :     for ( i=ci->interp_start; i<ci->interp_end; ++i )
    2065           0 :         if ( ci->gcd[i].ret!=NULL )
    2066           0 :             GGadgetSetVisible(ci->gcd[i].ret,!normal);
    2067           0 :     GWidgetFlowGadgets(GGadgetGetWindow(GWidgetGetControl(ci->gw,CID_Normal)));
    2068           0 : }
    2069             : 
    2070           0 : void PIChangePoint(GIData *ci) {
    2071           0 :     int aspect = GTabSetGetSel(GWidgetGetControl(ci->gw,CID_TabSet));
    2072           0 :     GGadget *list = GWidgetGetControl(ci->gw,CID_HintMask);
    2073             :     int32 i, len;
    2074             :     HintMask *hm;
    2075             :     SplinePoint *sp;
    2076             :     SplineSet *spl;
    2077             :     int interpolate;
    2078             : 
    2079           0 :     GGadgetGetList(list,&len);
    2080             : 
    2081           0 :     PIFillup(ci,0);
    2082             : 
    2083           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Interpolated),
    2084           0 :             !ci->cursp->dontinterpolate && !(ci->cursp->nonextcp && ci->cursp->noprevcp) );
    2085           0 :     interpolate = SPInterpolate(ci->cursp) && ci->cv->b.layerheads[ci->cv->b.drawmode]->order2;
    2086           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Normal), !interpolate );
    2087           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Interpolated), interpolate );
    2088           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NeverInterpolate), ci->cursp->dontinterpolate );
    2089           0 :     PIShowHide(ci);
    2090             : 
    2091           0 :     if ( ci->cursp->hintmask==NULL ) {
    2092           0 :         for ( i=0; i<len; ++i )
    2093           0 :             GGadgetSelectListItem(list,i,false);
    2094             :     } else {
    2095           0 :         for ( i=0; i<len && i<HntMax; ++i )
    2096           0 :             GGadgetSelectListItem(list,i, (*ci->cursp->hintmask)[i>>3]&(0x80>>(i&7))?true:false );
    2097             :     }
    2098           0 :     _PI_ShowHints(ci,aspect==1);
    2099             : 
    2100           0 :     list = GWidgetGetControl(ci->gw,CID_ActiveHints);
    2101           0 :     hm = NULL;
    2102             :     /* Figure out what hintmask is active at the current point */
    2103             :     /* Note: we must walk each ss backwards because we reverse the splineset */
    2104             :     /*  when we output postscript */
    2105           0 :     for ( spl = ci->sc->layers[ly_fore].splines; spl!=NULL; spl=spl->next ) {
    2106           0 :         for ( sp=spl->first; ; ) {
    2107           0 :             if ( sp->hintmask )
    2108           0 :                 hm = sp->hintmask;
    2109           0 :             if ( sp==ci->cursp )
    2110           0 :         break;
    2111           0 :             if ( sp->prev==NULL )
    2112           0 :         break;
    2113           0 :             sp = sp->prev->from;
    2114           0 :             if ( sp==spl->first )
    2115           0 :         break;
    2116           0 :         }
    2117           0 :         if ( sp==ci->cursp )
    2118           0 :     break;
    2119             :     }
    2120           0 :     if ( hm==NULL ) {
    2121           0 :         for ( i=0; i<len; ++i )
    2122           0 :             GGadgetSelectListItem(list,i,false);
    2123             :     } else {
    2124           0 :         for ( i=0; i<len && i<HntMax; ++i )
    2125           0 :             GGadgetSelectListItem(list,i, (*hm)[i>>3]&(0x80>>(i&7))?true:false );
    2126             :     }
    2127           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextDef),ci->cursp->next!=NULL);
    2128           0 :     GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevDef),ci->cursp->prev!=NULL);
    2129           0 : }
    2130             : 
    2131           0 : static int PI_NextPrev(GGadget *g, GEvent *e) {
    2132           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2133           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2134           0 :         CharView *cv = ci->cv;
    2135           0 :         int cid = GGadgetGetCid(g);
    2136             :         SplinePointList *spl;
    2137             : 
    2138           0 :         PI_FixStuff(ci);
    2139             : 
    2140           0 :         ci->cursp->selected = false;
    2141           0 :         if ( cid == CID_Next ) {
    2142           0 :             if ( ci->cursp->next!=NULL && ci->cursp->next->to!=ci->curspl->first )
    2143           0 :                 ci->cursp = ci->cursp->next->to;
    2144             :             else {
    2145           0 :                 if ( ci->curspl->next == NULL ) {
    2146           0 :                     ci->curspl = cv->b.layerheads[cv->b.drawmode]->splines;
    2147           0 :                     GDrawBeep(NULL);
    2148             :                 } else
    2149           0 :                     ci->curspl = ci->curspl->next;
    2150           0 :                 ci->cursp = ci->curspl->first;
    2151             :             }
    2152           0 :         } else if ( cid == CID_Prev ) {
    2153           0 :             if ( ci->cursp!=ci->curspl->first ) {
    2154           0 :                 ci->cursp = ci->cursp->prev->from;
    2155             :             } else {
    2156           0 :                 if ( ci->curspl==cv->b.layerheads[cv->b.drawmode]->splines ) {
    2157           0 :                     for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=NULL; spl=spl->next );
    2158           0 :                     GDrawBeep(NULL);
    2159             :                 } else {
    2160           0 :                     for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=ci->curspl; spl=spl->next );
    2161             :                 }
    2162           0 :                 ci->curspl = spl;
    2163           0 :                 ci->cursp = spl->last;
    2164           0 :                 if ( spl->last==spl->first && spl->last->prev!=NULL )
    2165           0 :                     ci->cursp = ci->cursp->prev->from;
    2166             :             }
    2167           0 :         } else if ( cid==CID_NextC ) {
    2168           0 :             if ( ci->cursp->next!=NULL )
    2169           0 :                 ci->cursp = ci->cursp->next->to;
    2170             :             else {
    2171           0 :                 ci->cursp = ci->curspl->first;
    2172           0 :                 GDrawBeep(NULL);
    2173             :             }
    2174             :         } else /* CID_PrevC */ {
    2175           0 :             if ( ci->cursp->prev!=NULL )
    2176           0 :                 ci->cursp = ci->cursp->prev->from;
    2177             :             else {
    2178           0 :                 ci->cursp = ci->curspl->last;
    2179           0 :                 GDrawBeep(NULL);
    2180             :             }
    2181             :         }
    2182           0 :         ci->cursp->selected = true;
    2183           0 :         PIChangePoint(ci);
    2184           0 :         CVShowPoint(cv,&ci->cursp->me);
    2185           0 :         SCUpdateAll(cv->b.sc);
    2186             :     }
    2187           0 : return( true );
    2188             : }
    2189             : 
    2190           0 : static int PI_InterpChanged(GGadget *g, GEvent *e) {
    2191           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2192           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2193           0 :         SplinePoint *cursp = ci->cursp;
    2194             : 
    2195           0 :         if ( GGadgetGetCid(g)==CID_Interpolated ) {
    2196           0 :             if ( cursp->nonextcp && cursp->noprevcp )
    2197             :                 /* Do Nothing */;
    2198             :             else {
    2199           0 :                 if ( cursp->nonextcp && cursp->next ) {
    2200           0 :                     SplinePoint *n = cursp->next->to;
    2201           0 :                     cursp->nextcp.x = rint((n->me.x+cursp->me.x)/2);
    2202           0 :                     cursp->nextcp.y = rint((n->me.y+cursp->me.y)/2);
    2203           0 :                     n->prevcp = cursp->nextcp;
    2204           0 :                     cursp->nonextcp = n->noprevcp = false;
    2205             :                 }
    2206           0 :                 if ( cursp->noprevcp && cursp->prev ) {
    2207           0 :                     SplinePoint *p = cursp->prev->from;
    2208           0 :                     cursp->prevcp.x = rint((p->me.x+cursp->me.x)/2);
    2209           0 :                     cursp->prevcp.y = rint((p->me.y+cursp->me.y)/2);
    2210           0 :                     p->nextcp = cursp->prevcp;
    2211           0 :                     cursp->noprevcp = p->nonextcp = false;
    2212             :                 }
    2213           0 :                 cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
    2214           0 :                 cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
    2215           0 :                 if ( cursp->pointtype==pt_tangent ) {
    2216           0 :                     cursp->pointtype = pt_curve;
    2217           0 :                     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve),true);
    2218             :                 }
    2219           0 :                 if ( cursp->next!=NULL )
    2220           0 :                     SplineRefigure(cursp->next);
    2221           0 :                 if ( cursp->prev!=NULL )
    2222           0 :                     SplineRefigure(cursp->prev);
    2223           0 :                 SplineSetSpirosClear(ci->curspl);
    2224           0 :                 CVCharChangedUpdate(&ci->cv->b);
    2225             :             }
    2226           0 :             PIFillup(ci,0);
    2227             :         }
    2228           0 :         PIShowHide(ci);
    2229             :     }
    2230           0 : return( true );
    2231             : }
    2232             : 
    2233           0 : static int PI_NeverInterpChanged(GGadget *g, GEvent *e) {
    2234           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2235           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2236           0 :         int never = GGadgetIsChecked(g);
    2237             : 
    2238           0 :         GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Interpolated),!never);
    2239             : 
    2240           0 :         if ( never )
    2241           0 :             GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Normal),true);
    2242           0 :         ci->cursp->dontinterpolate = never;
    2243           0 :         PIShowHide(ci);
    2244             :     }
    2245           0 : return( true );
    2246             : }
    2247             : 
    2248           0 : static int PI_BaseChanged(GGadget *g, GEvent *e) {
    2249           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    2250           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2251           0 :         real dx=0, dy=0;
    2252           0 :         int err=false;
    2253           0 :         SplinePoint *cursp = ci->cursp;
    2254             : 
    2255           0 :         if ( GGadgetGetCid(g)==CID_BaseX )
    2256           0 :             dx = GetCalmReal8(ci->gw,CID_BaseX,_("Base X"),&err)-cursp->me.x;
    2257             :         else
    2258           0 :             dy = GetCalmReal8(ci->gw,CID_BaseY,_("Base Y"),&err)-cursp->me.y;
    2259           0 :         if ( (dx==0 && dy==0) || err )
    2260           0 : return( true );
    2261           0 :         cursp->me.x += dx;
    2262           0 :         cursp->nextcp.x += dx;
    2263           0 :         cursp->prevcp.x += dx;
    2264           0 :         cursp->me.y += dy;
    2265           0 :         cursp->nextcp.y += dy;
    2266           0 :         cursp->prevcp.y += dy;
    2267           0 :         if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 ) {
    2268           0 :             SplinePointNextCPChanged2(cursp);
    2269           0 :             SplinePointPrevCPChanged2(cursp);
    2270             :         }
    2271           0 :         if ( cursp->next!=NULL )
    2272           0 :             SplineRefigure(cursp->next);
    2273           0 :         if ( cursp->prev!=NULL )
    2274           0 :             SplineRefigure(cursp->prev);
    2275           0 :         SplineSetSpirosClear(ci->curspl);
    2276           0 :         CVCharChangedUpdate(&ci->cv->b);
    2277           0 :         PIFillup(ci,GGadgetGetCid(g));
    2278           0 :     } else if ( e->type==et_controlevent &&
    2279           0 :             e->u.control.subtype == et_textfocuschanged &&
    2280           0 :             e->u.control.u.tf_focus.gained_focus ) {
    2281           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2282           0 :         PI_FigureNext(ci);
    2283           0 :         PI_FigurePrev(ci);
    2284             :     }
    2285           0 : return( true );
    2286             : }
    2287             : 
    2288           0 : static int PI_NextChanged(GGadget *g, GEvent *e) {
    2289           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    2290           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2291           0 :         real dx=0, dy=0;
    2292           0 :         int err=false;
    2293           0 :         SplinePoint *cursp = ci->cursp;
    2294             : 
    2295           0 :         if ( GGadgetGetCid(g)==CID_NextXOff ) {
    2296           0 :             dx = GetCalmReal8(ci->gw,CID_NextXOff,_("Next CP X"),&err)-(cursp->nextcp.x-cursp->me.x);
    2297           0 :             if ( cursp->pointtype==pt_tangent && cursp->prev!=NULL ) {
    2298           0 :                 if ( cursp->prev->from->me.x==cursp->me.x ) {
    2299           0 :                     dy = dx; dx = 0;    /* They should be constrained not to change in the x direction */
    2300             :                 } else
    2301           0 :                     dy = dx*(cursp->prev->from->me.y-cursp->me.y)/(cursp->prev->from->me.x-cursp->me.x);
    2302             :             }
    2303           0 :         } else if ( GGadgetGetCid(g)==CID_NextYOff ) {
    2304           0 :             dy = GetCalmReal8(ci->gw,CID_NextYOff,_("Next CP Y"),&err)-(cursp->nextcp.y-cursp->me.y);
    2305           0 :             if ( cursp->pointtype==pt_tangent && cursp->prev!=NULL ) {
    2306           0 :                 if ( cursp->prev->from->me.y==cursp->me.y ) {
    2307           0 :                     dx = dy; dy = 0;    /* They should be constrained not to change in the y direction */
    2308             :                 } else
    2309           0 :                     dx = dy*(cursp->prev->from->me.x-cursp->me.x)/(cursp->prev->from->me.y-cursp->me.y);
    2310             :             }
    2311             :         } else {
    2312             :             double len, theta;
    2313           0 :             len = GetCalmReal8(ci->gw,CID_NextR,_("Next CP Dist"),&err);
    2314           0 :             theta = GetCalmReal8(ci->gw,CID_NextTheta,_("Next CP Angle"),&err)/RAD2DEG;
    2315           0 :             dx = len*cos(theta) - (cursp->nextcp.x-cursp->me.x);
    2316           0 :             dy = len*sin(theta) - (cursp->nextcp.y-cursp->me.y);
    2317             :         }
    2318           0 :         if ( (dx==0 && dy==0) || err )
    2319           0 : return( true );
    2320           0 :         if ( cursp->pointtype==pt_hvcurve ) {
    2321             :             BasePoint diff;
    2322           0 :             diff.x = cursp->nextcp.x+dx - cursp->me.x;
    2323           0 :             diff.y = cursp->nextcp.y+dy - cursp->me.y;
    2324           0 :             BP_HVForce(&diff);
    2325           0 :             dx = diff.x + (cursp->me.x - cursp->nextcp.x);
    2326           0 :             dy = diff.y + (cursp->me.y - cursp->nextcp.y);
    2327             :         }
    2328           0 :         cursp->nextcp.x += dx;
    2329           0 :         cursp->nextcp.y += dy;
    2330           0 :         cursp->nonextcp = false;
    2331           0 :         SplineSetSpirosClear(ci->curspl);
    2332           0 :         ci->nextchanged = true;
    2333           0 :         if (( dx>.1 || dx<-.1 || dy>.1 || dy<-.1 ) && cursp->nextcpdef ) {
    2334           0 :             cursp->nextcpdef = false;
    2335           0 :             GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NextDef), false );
    2336             :         }
    2337           0 :         if (( cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve) && cursp->prev!=NULL ) {
    2338             :             double plen, ntheta;
    2339             :             double ndx, ndy;
    2340           0 :             ndx = ci->cursp->nextcp.x-ci->cursp->me.x;
    2341           0 :             ndy = ci->cursp->nextcp.y-ci->cursp->me.y;
    2342           0 :             ntheta = atan2(ndy,ndx);
    2343           0 :             plen = GetCalmReal8(ci->gw,CID_PrevR,_("Prev CP Dist"),&err);
    2344           0 :             ci->cursp->prevcp.x = ci->cursp->me.x - plen*cos(ntheta);
    2345           0 :             ci->cursp->prevcp.y = ci->cursp->me.y - plen*sin(ntheta);
    2346           0 :             if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2347           0 :                 SplinePointPrevCPChanged2(cursp);
    2348           0 :             SplineRefigure(cursp->prev);
    2349             :         }
    2350           0 :         if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2351           0 :             SplinePointNextCPChanged2(cursp);
    2352           0 :         if ( cursp->next!=NULL )
    2353           0 :             SplineRefigure(cursp->next);
    2354           0 :         CVCharChangedUpdate(&ci->cv->b);
    2355           0 :         PIFillup(ci,GGadgetGetCid(g));
    2356           0 :     } else if ( e->type==et_controlevent &&
    2357           0 :             e->u.control.subtype == et_textfocuschanged &&
    2358           0 :             e->u.control.u.tf_focus.gained_focus ) {
    2359           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2360           0 :         PI_FigureNext(ci);
    2361             :     }
    2362           0 : return( true );
    2363             : }
    2364             : 
    2365           0 : static int PI_PrevChanged(GGadget *g, GEvent *e) {
    2366           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    2367           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2368           0 :         real dx=0, dy=0;
    2369           0 :         int err=false;
    2370           0 :         SplinePoint *cursp = ci->cursp;
    2371             : 
    2372           0 :         if ( GGadgetGetCid(g)==CID_PrevXOff ) {
    2373           0 :             dx = GetCalmReal8(ci->gw,CID_PrevXOff,_("Prev CP X"),&err)-(cursp->prevcp.x-cursp->me.x);
    2374           0 :             if ( cursp->pointtype==pt_tangent && cursp->next!=NULL ) {
    2375           0 :                 if ( cursp->next->to->me.x==cursp->me.x ) {
    2376           0 :                     dy = dx; dx = 0;    /* They should be constrained not to change in the x direction */
    2377             :                 } else
    2378           0 :                     dy = dx*(cursp->next->to->me.y-cursp->me.y)/(cursp->next->to->me.x-cursp->me.x);
    2379             :             }
    2380           0 :         } else if ( GGadgetGetCid(g)==CID_PrevYOff ) {
    2381           0 :             dy = GetCalmReal8(ci->gw,CID_PrevYOff,_("Prev CP Y"),&err)-(cursp->prevcp.y-cursp->me.y);
    2382           0 :             if ( cursp->pointtype==pt_tangent && cursp->next!=NULL ) {
    2383           0 :                 if ( cursp->next->to->me.y==cursp->me.y ) {
    2384           0 :                     dx = dy; dy = 0;    /* They should be constrained not to change in the y direction */
    2385             :                 } else
    2386           0 :                     dx = dy*(cursp->next->to->me.x-cursp->me.x)/(cursp->next->to->me.y-cursp->me.y);
    2387             :             }
    2388             :         } else {
    2389             :             double len, theta;
    2390           0 :             len = GetCalmReal8(ci->gw,CID_PrevR,_("Prev CP Dist"),&err);
    2391           0 :             theta = GetCalmReal8(ci->gw,CID_PrevTheta,_("Prev CP Angle"),&err)/RAD2DEG;
    2392           0 :             dx = len*cos(theta) - (cursp->prevcp.x-cursp->me.x);
    2393           0 :             dy = len*sin(theta) - (cursp->prevcp.y-cursp->me.y);
    2394             :         }
    2395           0 :         if ( (dx==0 && dy==0) || err )
    2396           0 : return( true );
    2397           0 :         if ( cursp->pointtype==pt_hvcurve ) {
    2398             :             BasePoint diff;
    2399           0 :             diff.x = cursp->prevcp.x+dx - cursp->me.x;
    2400           0 :             diff.y = cursp->prevcp.y+dy - cursp->me.y;
    2401           0 :             BP_HVForce(&diff);
    2402           0 :             dx = diff.x - (cursp->prevcp.x - cursp->me.x);
    2403           0 :             dy = diff.y - (cursp->prevcp.y - cursp->me.y);
    2404             :         }
    2405           0 :         cursp->prevcp.x += dx;
    2406           0 :         cursp->prevcp.y += dy;
    2407           0 :         cursp->noprevcp = false;
    2408           0 :         ci->prevchanged = true;
    2409           0 :         SplineSetSpirosClear(ci->curspl);
    2410           0 :         if (( dx>.1 || dx<-.1 || dy>.1 || dy<-.1 ) && cursp->prevcpdef ) {
    2411           0 :             cursp->prevcpdef = false;
    2412           0 :             GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_PrevDef), false );
    2413             :         }
    2414           0 :         if (( cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve) && cursp->next!=NULL ) {
    2415             :             double nlen, ptheta;
    2416             :             double pdx, pdy;
    2417           0 :             pdx = ci->cursp->prevcp.x-ci->cursp->me.x;
    2418           0 :             pdy = ci->cursp->prevcp.y-ci->cursp->me.y;
    2419           0 :             ptheta = atan2(pdy,pdx);
    2420           0 :             nlen = GetCalmReal8(ci->gw,CID_NextR,_("Next CP Dist"),&err);
    2421           0 :             ci->cursp->nextcp.x = ci->cursp->me.x - nlen*cos(ptheta);
    2422           0 :             ci->cursp->nextcp.y = ci->cursp->me.y - nlen*sin(ptheta);
    2423           0 :             if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2424           0 :                 SplinePointNextCPChanged2(cursp);
    2425           0 :             SplineRefigure(cursp->next);
    2426             :         }
    2427           0 :         if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2428           0 :             SplinePointPrevCPChanged2(cursp);
    2429           0 :         if ( cursp->prev!=NULL )
    2430           0 :             SplineRefigure(cursp->prev);
    2431           0 :         CVCharChangedUpdate(&ci->cv->b);
    2432           0 :         PIFillup(ci,GGadgetGetCid(g));
    2433           0 :     } else if ( e->type==et_controlevent &&
    2434           0 :             e->u.control.subtype == et_textfocuschanged &&
    2435           0 :             e->u.control.u.tf_focus.gained_focus ) {
    2436           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2437           0 :         PI_FigurePrev(ci);
    2438             :     }
    2439           0 : return( true );
    2440             : }
    2441             : 
    2442           0 : static int PI_NextIntChanged(GGadget *g, GEvent *e) {
    2443           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    2444           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2445           0 :         real x=0, y=0;
    2446           0 :         int err=false;
    2447           0 :         SplinePoint *cursp = ci->cursp;
    2448             : 
    2449           0 :         x = GetCalmReal8(ci->gw,CID_NextX,_("Next CP X"),&err);
    2450           0 :         y = GetCalmReal8(ci->gw,CID_NextY,_("Next CP Y"),&err);
    2451           0 :         if ( err || (x==cursp->nextcp.x && y==cursp->nextcp.y) )
    2452           0 : return( true );
    2453           0 :         cursp->nextcp.x = x;
    2454           0 :         cursp->nextcp.y = y;
    2455           0 :         cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
    2456           0 :         cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
    2457           0 :         SplineSetSpirosClear(ci->curspl);
    2458           0 :         if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2459           0 :             SplinePointNextCPChanged2(cursp);
    2460           0 :         if ( cursp->next!=NULL )
    2461           0 :             SplineRefigure(cursp->next);
    2462           0 :         CVCharChangedUpdate(&ci->cv->b);
    2463           0 :         PIFillup(ci,GGadgetGetCid(g));
    2464           0 :     } else if ( e->type==et_controlevent &&
    2465           0 :             e->u.control.subtype == et_textfocuschanged &&
    2466           0 :             e->u.control.u.tf_focus.gained_focus ) {
    2467           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2468           0 :         PI_FigureNext(ci);
    2469             :     }
    2470           0 : return( true );
    2471             : }
    2472             : 
    2473           0 : static int PI_PrevIntChanged(GGadget *g, GEvent *e) {
    2474           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    2475           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2476           0 :         real x=0, y=0;
    2477           0 :         int err=false;
    2478           0 :         SplinePoint *cursp = ci->cursp;
    2479             : 
    2480           0 :         x = GetCalmReal8(ci->gw,CID_PrevX,_("Prev CP X"),&err);
    2481           0 :         y = GetCalmReal8(ci->gw,CID_PrevY,_("Prev CP Y"),&err);
    2482           0 :         if ( err || (x==cursp->prevcp.x && y==cursp->prevcp.y) )
    2483           0 : return( true );
    2484           0 :         cursp->prevcp.x = x;
    2485           0 :         cursp->prevcp.y = y;
    2486           0 :         cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
    2487           0 :         cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
    2488           0 :         SplineSetSpirosClear(ci->curspl);
    2489           0 :         if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
    2490           0 :             SplinePointPrevCPChanged2(cursp);
    2491           0 :         if ( cursp->prev!=NULL )
    2492           0 :             SplineRefigure(cursp->prev);
    2493           0 :         CVCharChangedUpdate(&ci->cv->b);
    2494           0 :         PIFillup(ci,GGadgetGetCid(g));
    2495           0 :     } else if ( e->type==et_controlevent &&
    2496           0 :             e->u.control.subtype == et_textfocuschanged &&
    2497           0 :             e->u.control.u.tf_focus.gained_focus ) {
    2498           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2499           0 :         PI_FigureNext(ci);
    2500             :     }
    2501           0 : return( true );
    2502             : }
    2503             : 
    2504           0 : static int PI_NextDefChanged(GGadget *g, GEvent *e) {
    2505           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2506           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2507           0 :         SplinePoint *cursp = ci->cursp;
    2508             : 
    2509           0 :         cursp->nextcpdef = GGadgetIsChecked(g);
    2510             :         /* If they turned def off, that's a noop, but if they turned it on... */
    2511             :         /*  then set things to the default */
    2512           0 :         if ( cursp->nextcpdef ) {
    2513           0 :             BasePoint temp = cursp->prevcp;
    2514           0 :             SplineCharDefaultNextCP(cursp);
    2515           0 :             if ( !cursp->prevcpdef ) {
    2516           0 :                 cursp->prevcp = temp;
    2517           0 :                 SplineSetSpirosClear(ci->curspl);
    2518             :             }
    2519           0 :             CVCharChangedUpdate(&ci->cv->b);
    2520           0 :             PIFillup(ci,GGadgetGetCid(g));
    2521             :         }
    2522             :     }
    2523           0 : return( true );
    2524             : }
    2525             : 
    2526           0 : static int PI_PrevDefChanged(GGadget *g, GEvent *e) {
    2527           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2528           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2529           0 :         SplinePoint *cursp = ci->cursp;
    2530             : 
    2531           0 :         cursp->prevcpdef = GGadgetIsChecked(g);
    2532             :         /* If they turned def off, that's a noop, but if they turned it on... */
    2533             :         /*  then set things to the default */
    2534           0 :         if ( cursp->prevcpdef ) {
    2535           0 :             BasePoint temp = cursp->nextcp;
    2536           0 :             SplineCharDefaultPrevCP(cursp);
    2537           0 :             if ( !cursp->nextcpdef ) {
    2538           0 :                 cursp->nextcp = temp;
    2539           0 :                 SplineSetSpirosClear(ci->curspl);
    2540             :             }
    2541           0 :             CVCharChangedUpdate(&ci->cv->b);
    2542           0 :             PIFillup(ci,GGadgetGetCid(g));
    2543             :         }
    2544             :     }
    2545           0 : return( true );
    2546             : }
    2547             : 
    2548           0 : static int PI_PTypeChanged(GGadget *g, GEvent *e) {
    2549           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2550           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2551           0 :         SplinePoint *cursp = ci->cursp;
    2552           0 :         enum pointtype pt = GGadgetGetCid(g)-CID_Curve + pt_curve;
    2553             : 
    2554           0 :         if ( pt==cursp->pointtype ) {
    2555             :             /* Can't happen */
    2556           0 :         } else if ( pt==pt_corner ) {
    2557           0 :             cursp->pointtype = pt_corner;
    2558           0 :             CVCharChangedUpdate(&ci->cv->b);
    2559             :         } else {
    2560           0 :             SPChangePointType(cursp,pt);
    2561           0 :             SplineSetSpirosClear(ci->curspl);
    2562           0 :             CVCharChangedUpdate(&ci->cv->b);
    2563           0 :             PIFillup(ci,GGadgetGetCid(g));
    2564             :         }
    2565             :     }
    2566           0 : return( true );
    2567             : }
    2568             : 
    2569           0 : static int PI_AspectChange(GGadget *g, GEvent *e) {
    2570           0 :     if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_radiochanged )) {
    2571           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2572           0 :         int aspect = GTabSetGetSel(g);
    2573             : 
    2574           0 :         _PI_ShowHints(ci,aspect==1);
    2575             :     }
    2576           0 : return( true );
    2577             : }
    2578             : 
    2579           0 : static int PI_HintSel(GGadget *g, GEvent *e) {
    2580           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
    2581           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    2582             : 
    2583           0 :         _PI_ShowHints(ci,true);
    2584             : 
    2585           0 :         if ( GGadgetIsListItemSelected(g,e->u.control.u.list.changed_index)) {
    2586             :             /* If we just selected something, check to make sure it doesn't */
    2587             :             /*  conflict with any other hints. */
    2588             :             /* Adobe says this is an error, but in "three" in AdobeSansMM */
    2589             :             /*  (in black,extended) we have a hintmask which contains two */
    2590             :             /*  overlapping hints */
    2591             :             /* So just make it a warning */
    2592             :             int i,j;
    2593           0 :             StemInfo *h, *h2=NULL;
    2594           0 :             for ( i=0, h=ci->cv->b.sc->hstem; h!=NULL && i!=e->u.control.u.list.changed_index; h=h->next, ++i );
    2595           0 :             if ( h!=NULL ) {
    2596           0 :                 for ( h2 = ci->cv->b.sc->hstem, i=0 ; h2!=NULL; h2=h2->next, ++i ) {
    2597           0 :                     if ( h2!=h && GGadgetIsListItemSelected(g,i)) {
    2598           0 :                         if (( h2->start<h->start && h2->start+h2->width>h->start ) ||
    2599           0 :                             ( h2->start>=h->start && h->start+h->width>h2->start ))
    2600             :                 break;
    2601             :                     }
    2602             :                 }
    2603             :             } else {
    2604           0 :                 j = i;
    2605           0 :                 for ( h=ci->cv->b.sc->vstem; h!=NULL && i!=e->u.control.u.list.changed_index; h=h->next, ++i );
    2606           0 :                 if ( h==NULL )
    2607           0 :                     IError("Failed to find hint");
    2608             :                 else {
    2609           0 :                     for ( h2 = ci->cv->b.sc->vstem, i=j ; h2!=NULL; h2=h2->next, ++i ) {
    2610           0 :                         if ( h2!=h && GGadgetIsListItemSelected(g,i)) {
    2611           0 :                             if (( h2->start<h->start && h2->start+h2->width>h->start ) ||
    2612           0 :                                 ( h2->start>=h->start && h->start+h->width>h2->start ))
    2613             :                     break;
    2614             :                         }
    2615             :                     }
    2616             :                 }
    2617             :             }
    2618           0 :             if ( h2!=NULL )
    2619           0 :                 ff_post_error(_("Overlapped Hints"),_("The hint you have just selected overlaps with <%.2f,%.2f>. You should deselect one of the two."),
    2620             :                         h2->start,h2->width);
    2621             :         }
    2622             :     }
    2623           0 : return( true );
    2624             : }
    2625             : 
    2626           0 : GTextInfo *SCHintList(SplineChar *sc,HintMask *hm) {
    2627             :     StemInfo *h;
    2628             :     int i;
    2629             :     GTextInfo *ti;
    2630             :     char buffer[100];
    2631             : 
    2632           0 :     for ( h=sc->hstem, i=0; h!=NULL; h=h->next, ++i );
    2633           0 :     for ( h=sc->vstem     ; h!=NULL; h=h->next, ++i );
    2634           0 :     ti = calloc(i+1,sizeof(GTextInfo));
    2635             : 
    2636           0 :     for ( h=sc->hstem, i=0; h!=NULL; h=h->next, ++i ) {
    2637           0 :         ti[i].fg = ti[i].bg = COLOR_DEFAULT;
    2638           0 :         ti[i].userdata = h;
    2639           0 :         if ( h->ghost && h->width>0 )
    2640           0 :             sprintf( buffer, "H<%g,%g>",
    2641           0 :                     rint(h->start*100)/100+rint(h->width*100)/100, -rint(h->width*100)/100 );
    2642             :         else
    2643           0 :             sprintf( buffer, "H<%g,%g>",
    2644           0 :                     rint(h->start*100)/100, rint(h->width*100)/100 );
    2645           0 :         ti[i].text = uc_copy(buffer);
    2646           0 :         if ( hm!=NULL && ((*hm)[i>>3]&(0x80>>(i&7))))
    2647           0 :             ti[i].selected = true;
    2648             :     }
    2649             : 
    2650           0 :     for ( h=sc->vstem    ; h!=NULL; h=h->next, ++i ) {
    2651           0 :         ti[i].fg = ti[i].bg = COLOR_DEFAULT;
    2652           0 :         ti[i].userdata = h;
    2653           0 :         if ( h->ghost && h->width>0 )
    2654           0 :             sprintf( buffer, "V<%g,%g>",
    2655           0 :                     rint(h->start*100)/100+rint(h->width*100)/100, -rint(h->width*100)/100 );
    2656             :         else
    2657           0 :             sprintf( buffer, "V<%g,%g>",
    2658           0 :                     rint(h->start*100)/100, rint(h->width*100)/100 );
    2659           0 :         ti[i].text = uc_copy(buffer);
    2660           0 :         if ( hm!=NULL && ((*hm)[i>>3]&(0x80>>(i&7))))
    2661           0 :             ti[i].selected = true;
    2662             :     }
    2663           0 : return( ti );
    2664             : }
    2665             : 
    2666           0 : static void PointGetInfo(CharView *cv, SplinePoint *sp, SplinePointList *spl) {
    2667           0 :     GIData* gi = 0;
    2668             :     GRect pos;
    2669             :     GWindowAttrs wattrs;
    2670           0 :     const int gcdcount = 54;
    2671           0 :     GGadgetCreateData gcd[gcdcount], hgcd[2], h2gcd[2], mgcd[11];
    2672             :     GGadgetCreateData mb[5], pb[9];
    2673             :     GGadgetCreateData *marray[11], *marray2[5], *marray3[5], *marray4[7],
    2674             :         *varray[11], *harray1[4], *harray2[6], *hvarray1[25], *hvarray2[25],
    2675             :         *hvarray3[16], *harray3[13];
    2676             :     GTextInfo label[54], mlabel[11];
    2677             :     GTabInfo aspects[4];
    2678             :     static GBox cur, nextcp, prevcp;
    2679             :     extern Color nextcpcol, prevcpcol;
    2680             :     GWindow root;
    2681             :     GRect screensize;
    2682             :     GPoint pt;
    2683             :     int j, defxpos, nextstarty, k, l;
    2684             : 
    2685           0 :     gi = calloc(1,sizeof(GIData));
    2686             : 
    2687           0 :     cur.main_background = nextcp.main_background = prevcp.main_background = COLOR_DEFAULT;
    2688           0 :     cur.main_foreground = 0xff0000;
    2689           0 :     nextcp.main_foreground = nextcpcol;
    2690           0 :     prevcp.main_foreground = prevcpcol;
    2691           0 :     gi->cv = cv;
    2692           0 :     gi->sc = cv->b.sc;
    2693           0 :     gi->cursp = sp;
    2694           0 :     gi->curspl = spl;
    2695           0 :     gi->oldstate = SplinePointListCopy(cv->b.layerheads[cv->b.drawmode]->splines);
    2696           0 :     gi->done = false;
    2697           0 :     CVPreserveState(&cv->b);
    2698             : 
    2699           0 :     root = GDrawGetRoot(NULL);
    2700           0 :     GDrawGetSize(root,&screensize);
    2701             : 
    2702           0 :         memset(&wattrs,0,sizeof(wattrs));
    2703           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_positioned|wam_isdlg;
    2704           0 :         wattrs.event_masks = ~(1<<et_charup);
    2705           0 :         wattrs.restrict_input_to_me = 1;
    2706           0 :         wattrs.positioned = 1;
    2707           0 :         wattrs.cursor = ct_pointer;
    2708           0 :         wattrs.utf8_window_title = _("Point Info");
    2709           0 :         wattrs.is_dlg = true;
    2710           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,PI_Width));
    2711           0 :         pos.height = GDrawPointsToPixels(NULL,PI_Height);
    2712           0 :         pt.x = cv->xoff + rint(sp->me.x*cv->scale);
    2713           0 :         pt.y = -cv->yoff + cv->height - rint(sp->me.y*cv->scale);
    2714           0 :         GDrawTranslateCoordinates(cv->v,root,&pt);
    2715           0 :         if ( pt.x+20+pos.width<=screensize.width )
    2716           0 :             pos.x = pt.x+20;
    2717           0 :         else if ( (pos.x = pt.x-10-screensize.width)<0 )
    2718           0 :             pos.x = 0;
    2719           0 :         pos.y = pt.y;
    2720           0 :         if ( pos.y+pos.height+20 > screensize.height )
    2721           0 :             pos.y = screensize.height - pos.height - 20;
    2722           0 :         if ( pos.y<0 ) pos.y = 0;
    2723           0 :         gi->gw = GDrawCreateTopWindow(NULL,&pos,pi_e_h,gi,&wattrs);
    2724             : 
    2725           0 :         memset(&gcd,0,sizeof(gcd));
    2726           0 :         memset(&label,0,sizeof(label));
    2727           0 :         memset(&hgcd,0,sizeof(hgcd));
    2728           0 :         memset(&h2gcd,0,sizeof(h2gcd));
    2729           0 :         memset(&mgcd,0,sizeof(mgcd));
    2730           0 :         memset(&mlabel,0,sizeof(mlabel));
    2731           0 :         memset(&aspects,0,sizeof(aspects));
    2732           0 :         memset(&pb,0,sizeof(pb));
    2733             : 
    2734           0 :         j=k=0;
    2735           0 :         gi->gcd = malloc( gcdcount*sizeof(GGadgetCreateData) );
    2736           0 :         memcpy( gi->gcd, gcd, gcdcount*sizeof(GGadgetCreateData) );
    2737             : 
    2738           0 :         label[j].text = (unichar_t *) _("_Normal");
    2739           0 :         label[j].text_is_1byte = true;
    2740           0 :         label[j].text_in_resource = true;
    2741           0 :         gcd[j].gd.label = &label[j];
    2742           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = 5;
    2743           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_cb_on;
    2744           0 :         gcd[j].gd.cid = CID_Normal;
    2745           0 :         gcd[j].gd.handle_controlevent = PI_InterpChanged;
    2746           0 :         gcd[j].creator = GRadioCreate;
    2747           0 :         harray1[0] = &gcd[j];
    2748           0 :         ++j;
    2749             : 
    2750           0 :         label[j].text = (unichar_t *) _("_Interpolated");
    2751           0 :         label[j].text_is_1byte = true;
    2752           0 :         label[j].text_in_resource = true;
    2753           0 :         gcd[j].gd.label = &label[j];
    2754           0 :         gcd[j].gd.pos.x = 70; gcd[j].gd.pos.y = 5;
    2755           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    2756           0 :         gcd[j].gd.cid = CID_Interpolated;
    2757           0 :         gcd[j].gd.handle_controlevent = PI_InterpChanged;
    2758           0 :         gcd[j].creator = GRadioCreate;
    2759           0 :         harray1[1] = &gcd[j]; harray1[2] = GCD_Glue; harray1[3] = NULL;
    2760           0 :         ++j;
    2761             : 
    2762           0 :         pb[2].gd.flags = gg_enabled|gg_visible;
    2763           0 :         pb[2].gd.u.boxelements = harray1;
    2764           0 :         pb[2].creator = GHBoxCreate;
    2765           0 :         varray[k++] = &pb[2];
    2766             : 
    2767           0 :         label[j].text = (unichar_t *) _("N_ever Interpolate");
    2768           0 :         label[j].text_is_1byte = true;
    2769           0 :         label[j].text_in_resource = true;
    2770           0 :         gcd[j].gd.label = &label[j];
    2771           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+16;
    2772           0 :         gcd[j].gd.flags = cv->b.layerheads[cv->b.drawmode]->order2 ? (gg_enabled|gg_visible) : gg_visible;
    2773           0 :         gcd[j].gd.cid = CID_NeverInterpolate;
    2774           0 :         gcd[j].gd.handle_controlevent = PI_NeverInterpChanged;
    2775           0 :         gcd[j].creator = GCheckBoxCreate;
    2776           0 :         varray[k++] = &gcd[j];
    2777           0 :         ++j;
    2778             : 
    2779           0 :         gi->normal_start = j;
    2780           0 :         label[j].text = (unichar_t *) _("_Base:");
    2781           0 :         label[j].text_is_1byte = true;
    2782           0 :         label[j].text_in_resource = true;
    2783           0 :         gcd[j].gd.label = &label[j];
    2784           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+17+6;
    2785           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    2786           0 :         gcd[j].gd.box = &cur;
    2787           0 :         gcd[j].creator = GLabelCreate;
    2788           0 :         harray2[0] = &gcd[j]; harray2[1] = GCD_Glue;
    2789           0 :         ++j;
    2790             : 
    2791           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-6; gcd[j].gd.pos.width = 70;
    2792           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2793           0 :         gcd[j].gd.cid = CID_BaseX;
    2794           0 :         gcd[j].gd.handle_controlevent = PI_BaseChanged;
    2795           0 :         gcd[j].creator = GNumericFieldCreate;
    2796           0 :         harray2[2] = &gcd[j];
    2797           0 :         ++j;
    2798             : 
    2799           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    2800           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2801           0 :         gcd[j].gd.cid = CID_BaseY;
    2802           0 :         gcd[j].gd.handle_controlevent = PI_BaseChanged;
    2803           0 :         gcd[j].creator = GNumericFieldCreate;
    2804           0 :         harray2[3] = &gcd[j]; harray2[4] = GCD_Glue; harray2[5] = NULL;
    2805           0 :         ++j;
    2806             : 
    2807           0 :         pb[3].gd.flags = gg_enabled|gg_visible;
    2808           0 :         pb[3].gd.u.boxelements = harray2;
    2809           0 :         pb[3].creator = GHBoxCreate;
    2810           0 :         varray[k++] = &pb[3];
    2811             : 
    2812           0 :         l = 0;
    2813           0 :         label[j].text = (unichar_t *) _("Prev CP:");
    2814           0 :         label[j].text_is_1byte = true;
    2815           0 :         gcd[j].gd.label = &label[j];
    2816           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+24+4;
    2817           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    2818           0 :         gcd[j].gd.box = &prevcp;
    2819           0 :         gcd[j].creator = GLabelCreate;
    2820           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
    2821           0 :         ++j;
    2822             : 
    2823           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 65;
    2824           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2825           0 :         gcd[j].gd.cid = CID_PrevPos;
    2826           0 :         gcd[j].creator = GLabelCreate;
    2827           0 :         hvarray1[l++] = &gcd[j];
    2828           0 :         ++j;
    2829             : 
    2830           0 :         defxpos = 130;
    2831           0 :         label[j].text = (unichar_t *) S_("ControlPoint|Default");
    2832           0 :         label[j].text_is_1byte = true;
    2833           0 :         gcd[j].gd.label = &label[j];
    2834           0 :         gcd[j].gd.pos.x = defxpos; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-3;
    2835           0 :         gcd[j].gd.flags = (gg_enabled|gg_visible);
    2836           0 :         gcd[j].gd.cid = CID_PrevDef;
    2837           0 :         gcd[j].gd.handle_controlevent = PI_PrevDefChanged;
    2838           0 :         gcd[j].creator = GCheckBoxCreate;
    2839           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = NULL;
    2840           0 :         ++j;
    2841             : 
    2842           0 :         label[j].text = (unichar_t *) _("Offset");
    2843           0 :         label[j].text_is_1byte = true;
    2844           0 :         gcd[j].gd.label = &label[j];
    2845           0 :         gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+18+4;
    2846           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2847           0 :         gcd[j].creator = GLabelCreate;
    2848           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
    2849           0 :         ++j;
    2850             : 
    2851           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    2852           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2853           0 :         gcd[j].gd.cid = CID_PrevXOff;
    2854           0 :         gcd[j].gd.handle_controlevent = PI_PrevChanged;
    2855           0 :         gcd[j].creator = GNumericFieldCreate;
    2856           0 :         hvarray1[l++] = &gcd[j];
    2857           0 :         ++j;
    2858             : 
    2859           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    2860           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2861           0 :         gcd[j].gd.cid = CID_PrevYOff;
    2862           0 :         gcd[j].gd.handle_controlevent = PI_PrevChanged;
    2863           0 :         gcd[j].creator = GNumericFieldCreate;
    2864           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = NULL;
    2865           0 :         ++j;
    2866             : 
    2867           0 :         label[j].text = (unichar_t *) _("Dist");
    2868           0 :         label[j].text_is_1byte = true;
    2869           0 :         gcd[j].gd.label = &label[j];
    2870           0 :         gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
    2871           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2872           0 :         gcd[j].creator = GLabelCreate;
    2873           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
    2874           0 :         ++j;
    2875             : 
    2876           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    2877           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2878           0 :         gcd[j].gd.cid = CID_PrevR;
    2879           0 :         gcd[j].gd.handle_controlevent = PI_PrevChanged;
    2880           0 :         gcd[j].creator = GNumericFieldCreate;
    2881           0 :         hvarray1[l++] = &gcd[j];
    2882           0 :         ++j;
    2883             : 
    2884           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 60;
    2885           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2886           0 :         gcd[j].gd.cid = CID_PrevTheta;
    2887           0 :         gcd[j].gd.handle_controlevent = PI_PrevChanged;
    2888           0 :         gcd[j].creator = GTextFieldCreate;
    2889           0 :         hvarray1[l++] = &gcd[j];
    2890           0 :         ++j;
    2891             : 
    2892           0 :         label[j].text = (unichar_t *) U_("°");
    2893           0 :         label[j].text_is_1byte = true;
    2894           0 :         gcd[j].gd.label = &label[j];
    2895           0 :         gcd[j].gd.pos.x = gcd[j-1].gd.pos.x+gcd[j-1].gd.pos.width+2; gcd[j].gd.pos.y = gcd[j-3].gd.pos.y;
    2896           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2897           0 :         gcd[j].creator = GLabelCreate;
    2898           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = NULL;
    2899           0 :         ++j;
    2900             : 
    2901           0 :         label[j].text = (unichar_t *) _("Curvature: -0.00000000");
    2902           0 :         label[j].text_is_1byte = true;
    2903           0 :         gcd[j].gd.label = &label[j];
    2904           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+20;
    2905           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2906           0 :         gcd[j].gd.cid = CID_PrevCurvature;
    2907           0 :         gcd[j].creator = GLabelCreate;
    2908           0 :         hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = GCD_ColSpan;
    2909           0 :           hvarray1[l++] = GCD_Glue; hvarray1[l++] = GCD_Glue; hvarray1[l++] = NULL;
    2910           0 :          hvarray1[l++] = NULL;
    2911           0 :         ++j;
    2912             : 
    2913           0 :         pb[4].gd.pos.x = pb[4].gd.pos.y = 2;
    2914           0 :         pb[4].gd.flags = gg_enabled|gg_visible;
    2915           0 :         pb[4].gd.u.boxelements = hvarray1;
    2916           0 :         pb[4].creator = GHVGroupCreate;
    2917           0 :         varray[k++] = &pb[4];
    2918             : 
    2919           0 :         l = 0;
    2920           0 :         nextstarty = gcd[j-2].gd.pos.y+28;
    2921           0 :         label[j].text = (unichar_t *) _("Next CP:");
    2922           0 :         label[j].text_is_1byte = true;
    2923           0 :         gcd[j].gd.label = &label[j];
    2924           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = nextstarty;
    2925           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    2926           0 :         gcd[j].gd.box = &nextcp;
    2927           0 :         gcd[j].creator = GLabelCreate;
    2928           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
    2929           0 :         ++j;
    2930             : 
    2931           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = nextstarty;  gcd[j].gd.pos.width = 65;
    2932           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2933           0 :         gcd[j].gd.cid = CID_NextPos;
    2934           0 :         gcd[j].creator = GLabelCreate;
    2935           0 :         hvarray2[l++] = &gcd[j];
    2936           0 :         ++j;
    2937             : 
    2938           0 :         label[j].text = (unichar_t *) S_("ControlPoint|Default");
    2939           0 :         label[j].text_is_1byte = true;
    2940           0 :         gcd[j].gd.label = &label[j];
    2941           0 :         gcd[j].gd.pos.x = defxpos; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-3;
    2942           0 :         gcd[j].gd.flags = (gg_enabled|gg_visible);
    2943           0 :         gcd[j].gd.cid = CID_NextDef;
    2944           0 :         gcd[j].gd.handle_controlevent = PI_NextDefChanged;
    2945           0 :         gcd[j].creator = GCheckBoxCreate;
    2946           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
    2947           0 :         ++j;
    2948             : 
    2949           0 :         label[j].text = (unichar_t *) _("Offset");
    2950           0 :         label[j].text_is_1byte = true;
    2951           0 :         gcd[j].gd.label = &label[j];
    2952           0 :         gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+18+4;
    2953           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2954           0 :         gcd[j].creator = GLabelCreate;
    2955           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
    2956           0 :         ++j;
    2957             : 
    2958           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    2959           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2960           0 :         gcd[j].gd.cid = CID_NextXOff;
    2961           0 :         gcd[j].gd.handle_controlevent = PI_NextChanged;
    2962           0 :         gcd[j].creator = GNumericFieldCreate;
    2963           0 :         hvarray2[l++] = &gcd[j];
    2964           0 :         ++j;
    2965             : 
    2966           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    2967           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2968           0 :         gcd[j].gd.cid = CID_NextYOff;
    2969           0 :         gcd[j].gd.handle_controlevent = PI_NextChanged;
    2970           0 :         gcd[j].creator = GNumericFieldCreate;
    2971           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
    2972           0 :         ++j;
    2973             : 
    2974           0 :         label[j].text = (unichar_t *) _("Dist");
    2975           0 :         label[j].text_is_1byte = true;
    2976           0 :         gcd[j].gd.label = &label[j];
    2977           0 :         gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
    2978           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2979           0 :         gcd[j].creator = GLabelCreate;
    2980           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
    2981           0 :         ++j;
    2982             : 
    2983           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    2984           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2985           0 :         gcd[j].gd.cid = CID_NextR;
    2986           0 :         gcd[j].gd.handle_controlevent = PI_NextChanged;
    2987           0 :         gcd[j].creator = GNumericFieldCreate;
    2988           0 :         hvarray2[l++] = &gcd[j];
    2989           0 :         ++j;
    2990             : 
    2991           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 60;
    2992           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    2993           0 :         gcd[j].gd.cid = CID_NextTheta;
    2994           0 :         gcd[j].gd.handle_controlevent = PI_NextChanged;
    2995           0 :         gcd[j].creator = GTextFieldCreate;
    2996           0 :         hvarray2[l++] = &gcd[j];
    2997           0 :         ++j;
    2998             : 
    2999           0 :         label[j].text = (unichar_t *) U_("°");
    3000           0 :         label[j].text_is_1byte = true;
    3001           0 :         gcd[j].gd.label = &label[j];
    3002           0 :         gcd[j].gd.pos.x = gcd[j-1].gd.pos.x+gcd[j-1].gd.pos.width+2; gcd[j].gd.pos.y = gcd[j-3].gd.pos.y;
    3003           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3004           0 :         gcd[j].creator = GLabelCreate;
    3005           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = NULL;
    3006           0 :         ++j;
    3007             : 
    3008           0 :         label[j].text = (unichar_t *) _("Curvature: -0.00000000");
    3009           0 :         label[j].text_is_1byte = true;
    3010           0 :         gcd[j].gd.label = &label[j];
    3011           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+20;
    3012           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3013           0 :         gcd[j].gd.cid = CID_NextCurvature;
    3014           0 :         gcd[j].creator = GLabelCreate;
    3015           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = GCD_ColSpan;
    3016           0 :         ++j;
    3017             : 
    3018           0 :         label[j].text = (unichar_t *) "∆: -0.00000000";
    3019           0 :         label[j].text_is_1byte = true;
    3020           0 :         gcd[j].gd.label = &label[j];
    3021           0 :         gcd[j].gd.pos.x = 130; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3022           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    3023           0 :         gcd[j].gd.popup_msg = (unichar_t *) _("This is the difference of the curvature between\nthe next and previous splines. Contours often\nlook nicer as this number approaches 0." );
    3024           0 :         gcd[j].gd.cid = CID_DeltaCurvature;
    3025           0 :         gcd[j].creator = GLabelCreate;
    3026           0 :         hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
    3027           0 :         hvarray2[l++] = NULL;
    3028           0 :         ++j;
    3029             : 
    3030           0 :         pb[5].gd.pos.x = pb[5].gd.pos.y = 2;
    3031           0 :         pb[5].gd.flags = gg_enabled|gg_visible;
    3032           0 :         pb[5].gd.u.boxelements = hvarray2;
    3033           0 :         pb[5].creator = GHVGroupCreate;
    3034           0 :         varray[k++] = &pb[5];
    3035           0 :         gi->normal_end = j;
    3036             : 
    3037           0 :         gi->interp_start = j;
    3038           0 :         l = 0;
    3039           0 :         label[j].text = (unichar_t *) _("_Base:");
    3040           0 :         label[j].text_is_1byte = true;
    3041           0 :         label[j].text_in_resource = true;
    3042           0 :         gcd[j].gd.label = &label[j];
    3043           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[gi->normal_start].gd.pos.y;
    3044           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    3045           0 :         gcd[j].gd.box = &cur;
    3046           0 :         gcd[j].creator = GLabelCreate;
    3047           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
    3048           0 :         ++j;
    3049             : 
    3050           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 65;
    3051           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3052           0 :         gcd[j].gd.cid = CID_BasePos;
    3053           0 :         gcd[j].creator = GLabelCreate;
    3054           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue; hvarray3[l++] = NULL;
    3055           0 :         ++j;
    3056             : 
    3057           0 :         label[j].text = (unichar_t *) _("Prev CP:");
    3058           0 :         label[j].text_is_1byte = true;
    3059           0 :         gcd[j].gd.label = &label[j];
    3060           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14+4;
    3061           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    3062           0 :         gcd[j].gd.box = &prevcp;
    3063           0 :         gcd[j].creator = GLabelCreate;
    3064           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
    3065           0 :         ++j;
    3066             : 
    3067           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    3068           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3069           0 :         gcd[j].gd.cid = CID_PrevX;
    3070           0 :         gcd[j].gd.handle_controlevent = PI_PrevIntChanged;
    3071           0 :         gcd[j].creator = GNumericFieldCreate;
    3072           0 :         hvarray3[l++] = &gcd[j];
    3073           0 :         ++j;
    3074             : 
    3075           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    3076           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3077           0 :         gcd[j].gd.cid = CID_PrevY;
    3078           0 :         gcd[j].gd.handle_controlevent = PI_PrevIntChanged;
    3079           0 :         gcd[j].creator = GNumericFieldCreate;
    3080           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = NULL;
    3081           0 :         ++j;
    3082             : 
    3083           0 :         label[j].text = (unichar_t *) _("Next CP:");
    3084           0 :         label[j].text_is_1byte = true;
    3085           0 :         gcd[j].gd.label = &label[j];
    3086           0 :         gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+24+4;
    3087           0 :         gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
    3088           0 :         gcd[j].gd.box = &nextcp;
    3089           0 :         gcd[j].creator = GLabelCreate;
    3090           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
    3091           0 :         ++j;
    3092             : 
    3093           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
    3094           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3095           0 :         gcd[j].gd.cid = CID_NextX;
    3096           0 :         gcd[j].gd.handle_controlevent = PI_NextIntChanged;
    3097           0 :         gcd[j].creator = GNumericFieldCreate;
    3098           0 :         hvarray3[l++] = &gcd[j];
    3099           0 :         ++j;
    3100             : 
    3101           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    3102           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3103           0 :         gcd[j].gd.cid = CID_NextY;
    3104           0 :         gcd[j].gd.handle_controlevent = PI_NextIntChanged;
    3105           0 :         gcd[j].creator = GNumericFieldCreate;
    3106           0 :         hvarray3[l++] = &gcd[j]; hvarray3[l++] = NULL; hvarray3[l++] = NULL;
    3107           0 :         ++j;
    3108           0 :         gi->interp_end = j;
    3109             : 
    3110           0 :         pb[6].gd.flags = gg_enabled|gg_visible;
    3111           0 :         pb[6].gd.u.boxelements = hvarray3;
    3112           0 :         pb[6].creator = GHVBoxCreate;
    3113           0 :         varray[k++] = &pb[6];
    3114           0 :         varray[k++] = GCD_Glue;
    3115             : 
    3116           0 :         label[j].text = (unichar_t *) _("Type:");
    3117           0 :         label[j].text_is_1byte = true;
    3118           0 :         gcd[j].gd.label = &label[j];
    3119           0 :         gcd[j].gd.pos.x = gcd[0].gd.pos.x; gcd[j].gd.pos.y = gcd[gi->normal_end-2].gd.pos.y+26;
    3120           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3121           0 :         gcd[j].creator = GLabelCreate;
    3122           0 :         harray3[0] = &gcd[j]; harray3[1] = GCD_Glue; harray3[2] = GCD_Glue;
    3123           0 :         ++j;
    3124             : 
    3125           0 :         label[j].image = &GIcon_midcurve;
    3126           0 :         gcd[j].gd.label = &label[j];
    3127           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
    3128           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3129           0 :         gcd[j].gd.cid = CID_Curve;
    3130           0 :         gcd[j].gd.handle_controlevent = PI_PTypeChanged;
    3131           0 :         gcd[j].creator = GRadioCreate;
    3132           0 :         harray3[3] = &gcd[j]; harray3[4] = GCD_Glue;
    3133           0 :         ++j;
    3134             : 
    3135           0 :         label[j].image = &GIcon_midhvcurve;
    3136           0 :         gcd[j].gd.label = &label[j];
    3137           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
    3138           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3139           0 :         gcd[j].gd.cid = CID_HVCurve;
    3140           0 :         gcd[j].gd.handle_controlevent = PI_PTypeChanged;
    3141           0 :         gcd[j].creator = GRadioCreate;
    3142           0 :         harray3[5] = &gcd[j]; harray3[6] = GCD_Glue;
    3143           0 :         ++j;
    3144             : 
    3145           0 :         label[j].image = &GIcon_midcorner;
    3146           0 :         gcd[j].gd.label = &label[j];
    3147           0 :         gcd[j].gd.pos.x = 100; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3148           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    3149           0 :         gcd[j].gd.cid = CID_Corner;
    3150           0 :         gcd[j].gd.handle_controlevent = PI_PTypeChanged;
    3151           0 :         gcd[j].creator = GRadioCreate;
    3152           0 :         harray3[7] = &gcd[j]; harray3[8] = GCD_Glue;
    3153           0 :         ++j;
    3154             : 
    3155           0 :         label[j].image = &GIcon_midtangent;
    3156           0 :         gcd[j].gd.label = &label[j];
    3157           0 :         gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3158           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    3159           0 :         gcd[j].gd.cid = CID_Tangent;
    3160           0 :         gcd[j].gd.handle_controlevent = PI_PTypeChanged;
    3161           0 :         gcd[j].creator = GRadioCreate;
    3162           0 :         harray3[9] = &gcd[j]; harray3[10] = GCD_Glue; harray3[11] = GCD_Glue;
    3163           0 :         harray3[12] = NULL;
    3164           0 :         ++j;
    3165             : 
    3166           0 :         pb[7].gd.flags = gg_enabled|gg_visible;
    3167           0 :         pb[7].gd.u.boxelements = harray3;
    3168           0 :         pb[7].creator = GHBoxCreate;
    3169           0 :         varray[k++] = &pb[7];
    3170           0 :         varray[k++] = NULL;
    3171             : 
    3172           0 :         pb[0].gd.flags = gg_enabled|gg_visible;
    3173           0 :         pb[0].gd.u.boxelements = varray;
    3174           0 :         pb[0].creator = GVBoxCreate;
    3175             : 
    3176           0 :         hgcd[0].gd.pos.x = 5; hgcd[0].gd.pos.y = 5;
    3177           0 :         hgcd[0].gd.pos.width = PI_Width-20; hgcd[0].gd.pos.height = gcd[j-1].gd.pos.y+10;
    3178           0 :         hgcd[0].gd.flags = gg_visible | gg_enabled | gg_list_multiplesel;
    3179           0 :         hgcd[0].gd.cid = CID_HintMask;
    3180           0 :         hgcd[0].gd.u.list = SCHintList(cv->b.sc,NULL);
    3181           0 :         hgcd[0].gd.handle_controlevent = PI_HintSel;
    3182           0 :         hgcd[0].creator = GListCreate;
    3183             : 
    3184           0 :         h2gcd[0].gd.pos.x = 5; h2gcd[0].gd.pos.y = 5;
    3185           0 :         h2gcd[0].gd.pos.width = PI_Width-20; h2gcd[0].gd.pos.height = gcd[j-1].gd.pos.y+10;
    3186           0 :         h2gcd[0].gd.flags = gg_visible | gg_list_multiplesel;
    3187           0 :         h2gcd[0].gd.cid = CID_ActiveHints;
    3188           0 :         h2gcd[0].gd.u.list = SCHintList(cv->b.sc,NULL);
    3189           0 :         h2gcd[0].creator = GListCreate;
    3190             : 
    3191           0 :         j = 0;
    3192             : 
    3193           0 :         aspects[j].text = (unichar_t *) _("Location");
    3194           0 :         aspects[j].text_is_1byte = true;
    3195           0 :         aspects[j++].gcd = pb;
    3196             : 
    3197           0 :         aspects[j].text = (unichar_t *) _("Hint Mask");
    3198           0 :         aspects[j].text_is_1byte = true;
    3199           0 :         aspects[j++].gcd = hgcd;
    3200             : 
    3201           0 :         aspects[j].text = (unichar_t *) _("Active Hints");
    3202           0 :         aspects[j].text_is_1byte = true;
    3203           0 :         aspects[j++].gcd = h2gcd;
    3204             : 
    3205           0 :         j = 0;
    3206             : 
    3207           0 :         mgcd[j].gd.pos.x = 4; mgcd[j].gd.pos.y = 6;
    3208           0 :         mgcd[j].gd.pos.width = PI_Width-8;
    3209           0 :         mgcd[j].gd.pos.height = hgcd[0].gd.pos.height+10+24;
    3210           0 :         mgcd[j].gd.u.tabs = aspects;
    3211           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled;
    3212           0 :         mgcd[j].gd.handle_controlevent = PI_AspectChange;
    3213           0 :         mgcd[j].gd.cid = CID_TabSet;
    3214           0 :         mgcd[j++].creator = GTabSetCreate;
    3215             : 
    3216           0 :         mgcd[j].gd.pos.x = (PI_Width-2*50-10)/2; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+mgcd[j-1].gd.pos.height+5;
    3217           0 :         mgcd[j].gd.pos.width = 53; mgcd[j].gd.pos.height = 0;
    3218           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled;
    3219           0 :         mlabel[j].text = (unichar_t *) _("< _Prev");
    3220           0 :         mlabel[j].text_is_1byte = true;
    3221           0 :         mlabel[j].text_in_resource = true;
    3222           0 :         mgcd[j].gd.label = &mlabel[j];
    3223           0 :         mgcd[j].gd.cid = CID_Prev;
    3224           0 :         mgcd[j].gd.handle_controlevent = PI_NextPrev;
    3225           0 :         mgcd[j].creator = GButtonCreate;
    3226           0 :         ++j;
    3227             : 
    3228           0 :         mgcd[j].gd.pos.x = PI_Width-50-(PI_Width-2*50-10)/2; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y;
    3229           0 :         mgcd[j].gd.pos.width = 53; mgcd[j].gd.pos.height = 0;
    3230           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled;
    3231           0 :         mlabel[j].text = (unichar_t *) _("_Next >");
    3232           0 :         mlabel[j].text_is_1byte = true;
    3233           0 :         mlabel[j].text_in_resource = true;
    3234           0 :         mgcd[j].gd.label = &mlabel[j];
    3235           0 :         mgcd[j].gd.cid = CID_Next;
    3236           0 :         mgcd[j].gd.handle_controlevent = PI_NextPrev;
    3237           0 :         mgcd[j].creator = GButtonCreate;
    3238           0 :         ++j;
    3239             : 
    3240             : /* Why 3? */
    3241           0 :         mgcd[j].gd.pos.x = mgcd[j-2].gd.pos.x-50+3; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+26;
    3242           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled;
    3243           0 :         mlabel[j].text = (unichar_t *) _("Prev On Contour");
    3244           0 :         mlabel[j].text_is_1byte = true;
    3245           0 :         mgcd[j].gd.label = &mlabel[j];
    3246           0 :         mgcd[j].gd.cid = CID_PrevC;
    3247           0 :         mgcd[j].gd.handle_controlevent = PI_NextPrev;
    3248           0 :         mgcd[j].creator = GButtonCreate;
    3249           0 :         ++j;
    3250             : 
    3251           0 :         mgcd[j].gd.pos.x = mgcd[j-2].gd.pos.x; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y;
    3252           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled;
    3253           0 :         mlabel[j].text = (unichar_t *) _("Next On Contour");
    3254           0 :         mlabel[j].text_is_1byte = true;
    3255           0 :         mgcd[j].gd.label = &mlabel[j];
    3256           0 :         mgcd[j].gd.cid = CID_NextC;
    3257           0 :         mgcd[j].gd.handle_controlevent = PI_NextPrev;
    3258           0 :         mgcd[j].creator = GButtonCreate;
    3259           0 :         ++j;
    3260             : 
    3261           0 :         mgcd[j].gd.pos.x = 5; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+28;
    3262           0 :         mgcd[j].gd.pos.width = PI_Width-10;
    3263           0 :         mgcd[j].gd.flags = gg_enabled|gg_visible;
    3264           0 :         mgcd[j].creator = GLineCreate;
    3265           0 :         ++j;
    3266             : 
    3267           0 :         mgcd[j].gd.pos.x = 20-3; mgcd[j].gd.pos.y = PI_Height-33-3;
    3268           0 :         mgcd[j].gd.pos.width = -1; mgcd[j].gd.pos.height = 0;
    3269           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled | gg_but_default;
    3270           0 :         mlabel[j].text = (unichar_t *) _("_OK");
    3271           0 :         mlabel[j].text_is_1byte = true;
    3272           0 :         mlabel[j].text_in_resource = true;
    3273           0 :         mgcd[j].gd.mnemonic = 'O';
    3274           0 :         mgcd[j].gd.label = &mlabel[j];
    3275           0 :         mgcd[j].gd.handle_controlevent = PI_Ok;
    3276           0 :         mgcd[j].creator = GButtonCreate;
    3277           0 :         ++j;
    3278             : 
    3279           0 :         mgcd[j].gd.pos.x = -20; mgcd[j].gd.pos.y = PI_Height-33;
    3280           0 :         mgcd[j].gd.pos.width = -1; mgcd[j].gd.pos.height = 0;
    3281           0 :         mgcd[j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    3282           0 :         mlabel[j].text = (unichar_t *) _("_Cancel");
    3283           0 :         mlabel[j].text_is_1byte = true;
    3284           0 :         mlabel[j].text_in_resource = true;
    3285           0 :         mgcd[j].gd.label = &mlabel[j];
    3286           0 :         mgcd[j].gd.mnemonic = 'C';
    3287           0 :         mgcd[j].gd.handle_controlevent = PI_Cancel;
    3288           0 :         mgcd[j].creator = GButtonCreate;
    3289           0 :         ++j;
    3290             : 
    3291           0 :         marray[0] = &mgcd[0]; marray[1] = NULL;
    3292           0 :         marray[2] = &mb[2]; marray[3] = NULL;
    3293           0 :         marray[4] = &mb[3]; marray[5] = NULL;
    3294           0 :         marray[6] = &mgcd[5]; marray[7] = NULL;
    3295           0 :         marray[8] = &mb[4]; marray[9] = NULL;
    3296           0 :         marray[10] = NULL;
    3297           0 :         marray2[0] = GCD_Glue; marray2[1] = &mgcd[1]; marray2[2] = &mgcd[2]; marray2[3] = GCD_Glue; marray2[4] = NULL;
    3298           0 :         marray3[0] = GCD_Glue; marray3[1] = &mgcd[3]; marray3[2] = &mgcd[4]; marray3[3] = GCD_Glue; marray3[4] = NULL;
    3299           0 :         marray4[0] = GCD_Glue; marray4[1] = &mgcd[6]; marray4[2] = GCD_Glue; marray4[3] = GCD_Glue; marray4[4] = &mgcd[7]; marray4[5] = GCD_Glue; marray4[6] = NULL;
    3300             : 
    3301           0 :         memset(mb,0,sizeof(mb));
    3302           0 :         mb[0].gd.pos.x = mb[0].gd.pos.y = 2;
    3303           0 :         mb[0].gd.flags = gg_enabled|gg_visible;
    3304           0 :         mb[0].gd.u.boxelements = marray;
    3305           0 :         mb[0].creator = GHVGroupCreate;
    3306             : 
    3307           0 :         mb[2].gd.flags = gg_enabled|gg_visible;
    3308           0 :         mb[2].gd.u.boxelements = marray2;
    3309           0 :         mb[2].creator = GHBoxCreate;
    3310             : 
    3311           0 :         mb[3].gd.flags = gg_enabled|gg_visible;
    3312           0 :         mb[3].gd.u.boxelements = marray3;
    3313           0 :         mb[3].creator = GHBoxCreate;
    3314             : 
    3315           0 :         mb[4].gd.flags = gg_enabled|gg_visible;
    3316           0 :         mb[4].gd.u.boxelements = marray4;
    3317           0 :         mb[4].creator = GHBoxCreate;
    3318             : 
    3319           0 :         GGadgetsCreate(gi->gw,mb);
    3320           0 :         gi->group1ret = pb[4].ret; gi->group2ret = pb[5].ret;
    3321           0 :         memcpy( gi->gcd, gcd, gcdcount*sizeof(GGadgetCreateData) ); // This copies pointers, but only to static things.
    3322           0 :         GTextInfoListFree(hgcd[0].gd.u.list);
    3323           0 :         GTextInfoListFree(h2gcd[0].gd.u.list);
    3324             : 
    3325           0 :         GHVBoxSetExpandableRow(mb[0].ret,0);
    3326           0 :         GHVBoxSetExpandableCol(mb[2].ret,gb_expandgluesame);
    3327           0 :         GHVBoxSetExpandableCol(mb[3].ret,gb_expandgluesame);
    3328           0 :         GHVBoxSetExpandableCol(mb[4].ret,gb_expandgluesame);
    3329           0 :         GHVBoxSetExpandableRow(pb[0].ret,gb_expandglue);
    3330           0 :         GHVBoxSetExpandableCol(pb[2].ret,gb_expandglue);
    3331           0 :         GHVBoxSetExpandableCol(pb[3].ret,gb_expandglue);
    3332           0 :         GHVBoxSetExpandableCol(pb[4].ret,gb_expandglue);
    3333           0 :         GHVBoxSetExpandableCol(pb[5].ret,gb_expandglue);
    3334           0 :         GHVBoxSetExpandableCol(pb[6].ret,gb_expandglue);
    3335           0 :         GHVBoxSetExpandableCol(pb[7].ret,gb_expandglue);
    3336             : 
    3337           0 :         PIChangePoint(gi);
    3338             : 
    3339           0 :         GHVBoxFitWindow(mb[0].ret);
    3340             : 
    3341           0 :         gi->nonmodal = 1;
    3342           0 :         dlist_pushfront( &cv->pointInfoDialogs, (struct dlistnode *)gi );
    3343           0 :         GWidgetHidePalettes();
    3344           0 :         GDrawResize(gi->gw,
    3345             :                     GGadgetScale(GDrawPointsToPixels(NULL,PI_Width)),
    3346             :                     GDrawPointsToPixels(NULL,PI_Height));
    3347           0 :         GDrawSetVisible(gi->gw,true);
    3348           0 : }
    3349             : 
    3350             : /* ************************************************************************** */
    3351             : /* ****************************** Spiro Points ****************************** */
    3352             : /* ************************************************************************** */
    3353             : 
    3354           0 : static void SpiroFillup(GIData *ci, int except_cid) {
    3355             :     char buffer[50];
    3356             :     int ty;
    3357             : 
    3358           0 :     mysprintf(buffer, "%.2f", ci->curcp->x );
    3359           0 :     if ( except_cid!=CID_BaseX )
    3360           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseX),buffer);
    3361             : 
    3362           0 :     mysprintf(buffer, "%.2f", ci->curcp->y );
    3363           0 :     if ( except_cid!=CID_BaseY )
    3364           0 :         GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseY),buffer);
    3365             : 
    3366           0 :     ty = ci->curcp->ty&0x7f;
    3367           0 :     if ( ty == SPIRO_OPEN_CONTOUR )
    3368           0 :         ty = SPIRO_G4;
    3369           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve), ty==SPIRO_G4 );
    3370           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Tangent), ty==SPIRO_G2 );
    3371           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Corner), ty==SPIRO_CORNER );
    3372           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_SpiroLeft), ty==SPIRO_LEFT );
    3373           0 :     GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_SpiroRight), ty==SPIRO_RIGHT );
    3374           0 : }
    3375             : 
    3376           0 : static void SpiroChangePoint(GIData *ci) {
    3377             : 
    3378           0 :     SpiroFillup(ci,0);
    3379           0 : }
    3380             : 
    3381           0 : static int PI_SpiroNextPrev(GGadget *g, GEvent *e) {
    3382           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    3383           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    3384           0 :         CharView *cv = ci->cv;
    3385           0 :         int cid = GGadgetGetCid(g);
    3386             :         SplinePointList *spl;
    3387           0 :         int index = ci->curcp - ci->curspl->spiros;
    3388             :         BasePoint here;
    3389             : 
    3390           0 :         SPIRO_DESELECT(ci->curcp);
    3391           0 :         if ( cid == CID_Next ) {
    3392           0 :             if ( index < ci->curspl->spiro_cnt-2 )
    3393           0 :                 ci->curcp = &ci->curspl->spiros[index+1];
    3394             :             else {
    3395           0 :                 if ( ci->curspl->next == NULL ) {
    3396           0 :                     ci->curspl = cv->b.layerheads[cv->b.drawmode]->splines;
    3397           0 :                     GDrawBeep(NULL);
    3398             :                 } else
    3399           0 :                     ci->curspl = ci->curspl->next;
    3400           0 :                 ci->curcp = &ci->curspl->spiros[0];
    3401             :             }
    3402           0 :         } else if ( cid == CID_Prev ) {
    3403           0 :             if ( index!=0 ) {
    3404           0 :                 ci->curcp = &ci->curspl->spiros[index-1];
    3405             :             } else {
    3406           0 :                 if ( ci->curspl==cv->b.layerheads[cv->b.drawmode]->splines ) {
    3407           0 :                     for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=NULL; spl=spl->next );
    3408           0 :                     GDrawBeep(NULL);
    3409             :                 } else {
    3410           0 :                     for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=ci->curspl; spl=spl->next );
    3411             :                 }
    3412           0 :                 ci->curspl = spl;
    3413           0 :                 ci->curcp = &ci->curspl->spiros[ci->curspl->spiro_cnt-2];
    3414             :             }
    3415           0 :         } else if ( cid==CID_NextC ) {
    3416           0 :             if ( index < ci->curspl->spiro_cnt-2 )
    3417           0 :                 ci->curcp = &ci->curspl->spiros[index+1];
    3418             :             else {
    3419           0 :                 ci->curcp = &ci->curspl->spiros[0];
    3420           0 :                 GDrawBeep(NULL);
    3421             :             }
    3422             :         } else /* CID_PrevC */ {
    3423           0 :             if ( index!=0 )
    3424           0 :                 ci->curcp = &ci->curspl->spiros[index-1];
    3425             :             else {
    3426           0 :                 ci->curcp = &ci->curspl->spiros[ci->curspl->spiro_cnt-2];
    3427           0 :                 GDrawBeep(NULL);
    3428             :             }
    3429             :         }
    3430           0 :         SPIRO_SELECT(ci->curcp);
    3431           0 :         SpiroChangePoint(ci);
    3432           0 :         here.x = ci->curcp->x; here.y = ci->curcp->y;
    3433           0 :         CVShowPoint(cv,&here);
    3434           0 :         SCUpdateAll(cv->b.sc);
    3435             :     }
    3436           0 : return( true );
    3437             : }
    3438             : 
    3439           0 : static int PI_SpiroChanged(GGadget *g, GEvent *e) {
    3440           0 :     if ( e->type==et_controlevent &&
    3441           0 :             (e->u.control.subtype == et_textchanged ||
    3442           0 :              e->u.control.subtype == et_radiochanged)) {
    3443           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    3444             :         double x,y;
    3445             :         int ty;
    3446           0 :         int err=false;
    3447           0 :         spiro_cp *curcp = ci->curcp;
    3448             : 
    3449           0 :         x = GetCalmReal8(ci->gw,CID_BaseX,_("X"),&err);
    3450           0 :         y = GetCalmReal8(ci->gw,CID_BaseY,_("Y"),&err);
    3451           0 :         ty = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Curve))? SPIRO_G4 :
    3452           0 :              GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Tangent))? SPIRO_G2 :
    3453           0 :              GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Corner))? SPIRO_CORNER :
    3454           0 :              GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_SpiroLeft))? SPIRO_LEFT :
    3455             :                      SPIRO_RIGHT;
    3456           0 :         curcp->x = x;
    3457           0 :         curcp->y = y;
    3458           0 :         curcp->ty = ty | 0x80;
    3459           0 :         SSRegenerateFromSpiros(ci->curspl);
    3460           0 :         CVCharChangedUpdate(&ci->cv->b);
    3461             :     }
    3462           0 : return( true );
    3463             : }
    3464             : 
    3465           0 : static int PI_SpiroOk(GGadget *g, GEvent *e) {
    3466           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    3467           0 :         GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
    3468             : 
    3469           0 :         ci->done = true;
    3470             :         /* All the work has been done as we've gone along */
    3471           0 :         PI_Close(g);
    3472             :     }
    3473           0 : return( true );
    3474             : }
    3475             : 
    3476           0 : static void SpiroPointGetInfo(CharView *cv, spiro_cp *scp, SplinePointList *spl) {
    3477           0 :     GIData *gip = calloc(1, sizeof(GIData));
    3478             :     GRect pos;
    3479             :     GWindowAttrs wattrs;
    3480             :     GGadgetCreateData gcd[20];
    3481             :     GGadgetCreateData pb[9];
    3482             :     GGadgetCreateData *varray[20], *harray2[10], *harray3[15], *harray4[6],
    3483             :             *harray5[6], *harray6[9];
    3484             :     GTextInfo label[20];
    3485             :     GWindow root;
    3486             :     GRect screensize;
    3487             :     GPoint pt;
    3488             :     int j,k;
    3489             : 
    3490           0 :     gip->cv = cv;
    3491           0 :     gip->sc = cv->b.sc;
    3492           0 :     gip->curcp = scp;
    3493           0 :     gip->curspl = spl;
    3494           0 :     gip->oldstate = SplinePointListCopy(cv->b.layerheads[cv->b.drawmode]->splines);
    3495           0 :     gip->done = false;
    3496           0 :     CVPreserveState(&cv->b);
    3497             : 
    3498           0 :     root = GDrawGetRoot(NULL);
    3499           0 :     GDrawGetSize(root,&screensize);
    3500             : 
    3501           0 :         memset(&wattrs,0,sizeof(wattrs));
    3502           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_positioned|wam_isdlg|wam_restrict;
    3503           0 :         wattrs.event_masks = ~(1<<et_charup);
    3504           0 :         wattrs.restrict_input_to_me = 1;
    3505           0 :         wattrs.positioned = 1;
    3506           0 :         wattrs.cursor = ct_pointer;
    3507           0 :         wattrs.utf8_window_title = _("Spiro Point Info");
    3508           0 :         wattrs.is_dlg = true;
    3509           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,PI_Width));
    3510           0 :         pos.height = GDrawPointsToPixels(NULL,PI_Height);
    3511           0 :         pt.x = cv->xoff + rint(scp->x*cv->scale);
    3512           0 :         pt.y = -cv->yoff + cv->height - rint(scp->y*cv->scale);
    3513           0 :         GDrawTranslateCoordinates(cv->v,root,&pt);
    3514           0 :         if ( pt.x+20+pos.width<=screensize.width )
    3515           0 :             pos.x = pt.x+20;
    3516           0 :         else if ( (pos.x = pt.x-10-screensize.width)<0 )
    3517           0 :             pos.x = 0;
    3518           0 :         pos.y = pt.y;
    3519           0 :         if ( pos.y+pos.height+20 > screensize.height )
    3520           0 :             pos.y = screensize.height - pos.height - 20;
    3521           0 :         if ( pos.y<0 ) pos.y = 0;
    3522           0 :         gip->gw = GDrawCreateTopWindow(NULL,&pos,pi_e_h,gip,&wattrs);
    3523             : 
    3524           0 :         memset(&gcd,0,sizeof(gcd));
    3525           0 :         memset(&label,0,sizeof(label));
    3526           0 :         memset(&pb,0,sizeof(pb));
    3527             : 
    3528           0 :         j=k=0;
    3529           0 :         gip->gcd = gcd;
    3530             : 
    3531           0 :         label[j].text = (unichar_t *) _("_X:");
    3532           0 :         label[j].text_is_1byte = true;
    3533           0 :         label[j].text_in_resource = true;
    3534           0 :         gcd[j].gd.label = &label[j];
    3535           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3536           0 :         gcd[j].creator = GLabelCreate;
    3537           0 :         harray2[0] = &gcd[j]; harray2[1] = GCD_Glue;
    3538           0 :         ++j;
    3539             : 
    3540           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-6; gcd[j].gd.pos.width = 70;
    3541           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3542           0 :         gcd[j].gd.cid = CID_BaseX;
    3543           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3544           0 :         gcd[j].creator = GNumericFieldCreate;
    3545           0 :         harray2[2] = &gcd[j]; harray2[3] = GCD_Glue; harray2[4] = GCD_Glue;
    3546           0 :         ++j;
    3547             : 
    3548           0 :         label[j].text = (unichar_t *) _("_Y:");
    3549           0 :         label[j].text_is_1byte = true;
    3550           0 :         label[j].text_in_resource = true;
    3551           0 :         gcd[j].gd.label = &label[j];
    3552           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3553           0 :         gcd[j].creator = GLabelCreate;
    3554           0 :         harray2[5] = &gcd[j]; harray2[6] = GCD_Glue;
    3555           0 :         ++j;
    3556             : 
    3557           0 :         gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
    3558           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3559           0 :         gcd[j].gd.cid = CID_BaseY;
    3560           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3561           0 :         gcd[j].creator = GNumericFieldCreate;
    3562           0 :         harray2[7] = &gcd[j]; harray2[8] = NULL;
    3563           0 :         ++j;
    3564             : 
    3565           0 :         pb[2].gd.flags = gg_enabled|gg_visible;
    3566           0 :         pb[2].gd.u.boxelements = harray2;
    3567           0 :         pb[2].creator = GHBoxCreate;
    3568           0 :         varray[k++] = &pb[2]; varray[k++] = NULL;
    3569             : 
    3570           0 :         label[j].text = (unichar_t *) _("Type:");
    3571           0 :         label[j].text_is_1byte = true;
    3572           0 :         gcd[j].gd.label = &label[j];
    3573           0 :         gcd[j].gd.pos.x = gcd[0].gd.pos.x;
    3574           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3575           0 :         gcd[j].creator = GLabelCreate;
    3576           0 :         harray3[0] = &gcd[j]; harray3[1] = GCD_Glue; harray3[2] = GCD_Glue;
    3577           0 :         ++j;
    3578             : 
    3579           0 :         label[j].image = &GIcon_smallspirocurve;
    3580           0 :         gcd[j].gd.label = &label[j];
    3581           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
    3582           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3583           0 :         gcd[j].gd.cid = CID_Curve;
    3584           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3585           0 :         gcd[j].creator = GRadioCreate;
    3586           0 :         harray3[3] = &gcd[j]; harray3[4] = GCD_Glue;
    3587           0 :         ++j;
    3588             : 
    3589           0 :         label[j].image = &GIcon_smallspirog2curve;
    3590           0 :         gcd[j].gd.label = &label[j];
    3591           0 :         gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
    3592           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3593           0 :         gcd[j].gd.cid = CID_Tangent;
    3594           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3595           0 :         gcd[j].creator = GRadioCreate;
    3596           0 :         harray3[5] = &gcd[j]; harray3[6] = GCD_Glue;
    3597           0 :         ++j;
    3598             : 
    3599           0 :         label[j].image = &GIcon_smallspirocorner;
    3600           0 :         gcd[j].gd.label = &label[j];
    3601           0 :         gcd[j].gd.pos.x = 100; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3602           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    3603           0 :         gcd[j].gd.cid = CID_Corner;
    3604           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3605           0 :         gcd[j].creator = GRadioCreate;
    3606           0 :         harray3[7] = &gcd[j]; harray3[8] = GCD_Glue;
    3607           0 :         ++j;
    3608             : 
    3609           0 :         label[j].image = &GIcon_smallspiroleft;
    3610           0 :         gcd[j].gd.label = &label[j];
    3611           0 :         gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3612           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    3613           0 :         gcd[j].gd.cid = CID_SpiroLeft;
    3614           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3615           0 :         gcd[j].creator = GRadioCreate;
    3616           0 :         harray3[9] = &gcd[j]; harray3[10] = GCD_Glue;
    3617           0 :         ++j;
    3618             : 
    3619           0 :         label[j].image = &GIcon_smallspiroright;
    3620           0 :         gcd[j].gd.label = &label[j];
    3621           0 :         gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
    3622           0 :         gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
    3623           0 :         gcd[j].gd.cid = CID_SpiroRight;
    3624           0 :         gcd[j].gd.handle_controlevent = PI_SpiroChanged;
    3625           0 :         gcd[j].creator = GRadioCreate;
    3626           0 :         harray3[11] = &gcd[j]; harray3[12] = GCD_Glue; harray3[13] = GCD_Glue;
    3627           0 :         harray3[14] = NULL;
    3628           0 :         ++j;
    3629             : 
    3630           0 :         pb[3].gd.flags = gg_enabled|gg_visible;
    3631           0 :         pb[3].gd.u.boxelements = harray3;
    3632           0 :         pb[3].creator = GHBoxCreate;
    3633           0 :         varray[k++] = &pb[3];
    3634           0 :         varray[k++] = NULL;
    3635           0 :         varray[k++] = GCD_Glue;
    3636           0 :         varray[k++] = NULL;
    3637             : 
    3638           0 :         gcd[j].gd.flags = gg_visible | gg_enabled;
    3639           0 :         label[j].text = (unichar_t *) _("< _Prev");
    3640           0 :         label[j].text_is_1byte = true;
    3641           0 :         label[j].text_in_resource = true;
    3642           0 :         gcd[j].gd.label = &label[j];
    3643           0 :         gcd[j].gd.cid = CID_Prev;
    3644           0 :         gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
    3645           0 :         gcd[j].creator = GButtonCreate;
    3646           0 :         harray4[0] = GCD_Glue; harray4[1] = &gcd[j];
    3647           0 :         ++j;
    3648             : 
    3649           0 :         gcd[j].gd.flags = gg_visible | gg_enabled;
    3650           0 :         label[j].text = (unichar_t *) _("_Next >");
    3651           0 :         label[j].text_is_1byte = true;
    3652           0 :         label[j].text_in_resource = true;
    3653           0 :         gcd[j].gd.label = &label[j];
    3654           0 :         gcd[j].gd.cid = CID_Next;
    3655           0 :         gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
    3656           0 :         gcd[j].creator = GButtonCreate;
    3657           0 :         harray4[2] = &gcd[j]; harray4[3] = GCD_Glue; harray4[4] = NULL;
    3658           0 :         ++j;
    3659             : 
    3660           0 :         pb[4].gd.flags = gg_enabled|gg_visible;
    3661           0 :         pb[4].gd.u.boxelements = harray4;
    3662           0 :         pb[4].creator = GHBoxCreate;
    3663           0 :         varray[k++] = &pb[4];
    3664           0 :         varray[k++] = NULL;
    3665             : 
    3666           0 :         gcd[j].gd.flags = gg_visible | gg_enabled;
    3667           0 :         label[j].text = (unichar_t *) _("Prev On Contour");
    3668           0 :         label[j].text_is_1byte = true;
    3669           0 :         gcd[j].gd.label = &label[j];
    3670           0 :         gcd[j].gd.cid = CID_PrevC;
    3671           0 :         gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
    3672           0 :         gcd[j].creator = GButtonCreate;
    3673           0 :         harray5[0] = GCD_Glue; harray5[1] = &gcd[j];
    3674           0 :         ++j;
    3675             : 
    3676           0 :         gcd[j].gd.flags = gg_visible | gg_enabled;
    3677           0 :         label[j].text = (unichar_t *) _("Next On Contour");
    3678           0 :         label[j].text_is_1byte = true;
    3679           0 :         gcd[j].gd.label = &label[j];
    3680           0 :         gcd[j].gd.cid = CID_NextC;
    3681           0 :         gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
    3682           0 :         gcd[j].creator = GButtonCreate;
    3683           0 :         harray5[2] = &gcd[j]; harray5[3] = GCD_Glue; harray5[4] = NULL;
    3684           0 :         ++j;
    3685             : 
    3686           0 :         pb[5].gd.flags = gg_enabled|gg_visible;
    3687           0 :         pb[5].gd.u.boxelements = harray5;
    3688           0 :         pb[5].creator = GHBoxCreate;
    3689           0 :         varray[k++] = &pb[5];
    3690           0 :         varray[k++] = NULL;
    3691             : 
    3692           0 :         gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
    3693           0 :         gcd[j].gd.pos.width = PI_Width-10;
    3694           0 :         gcd[j].gd.flags = gg_enabled|gg_visible;
    3695           0 :         gcd[j].creator = GLineCreate;
    3696           0 :         ++j;
    3697           0 :         varray[k++] = &gcd[j-1];
    3698           0 :         varray[k++] = NULL;
    3699           0 :         varray[k++] = GCD_Glue;
    3700           0 :         varray[k++] = NULL;
    3701             : 
    3702           0 :         gcd[j].gd.pos.x = 20-3; gcd[j].gd.pos.y = PI_Height-33-3;
    3703           0 :         gcd[j].gd.flags = gg_visible | gg_enabled | gg_but_default;
    3704           0 :         label[j].text = (unichar_t *) _("_OK");
    3705           0 :         label[j].text_is_1byte = true;
    3706           0 :         label[j].text_in_resource = true;
    3707           0 :         gcd[j].gd.mnemonic = 'O';
    3708           0 :         gcd[j].gd.label = &label[j];
    3709           0 :         gcd[j].gd.handle_controlevent = PI_SpiroOk;
    3710           0 :         gcd[j].creator = GButtonCreate;
    3711           0 :         harray6[0] = GCD_Glue; harray6[1] = &gcd[j]; harray6[2] = GCD_Glue; harray6[3] = GCD_Glue;
    3712           0 :         ++j;
    3713             : 
    3714           0 :         gcd[j].gd.pos.x = -20; gcd[j].gd.pos.y = PI_Height-33;
    3715           0 :         gcd[j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    3716           0 :         label[j].text = (unichar_t *) _("_Cancel");
    3717           0 :         label[j].text_is_1byte = true;
    3718           0 :         label[j].text_in_resource = true;
    3719           0 :         gcd[j].gd.label = &label[j];
    3720           0 :         gcd[j].gd.mnemonic = 'C';
    3721           0 :         gcd[j].gd.handle_controlevent = PI_Cancel;
    3722           0 :         gcd[j].creator = GButtonCreate;
    3723           0 :         harray6[4] = GCD_Glue; harray6[5] = &gcd[j]; harray6[6] = GCD_Glue; harray6[7] = NULL;
    3724           0 :         ++j;
    3725             : 
    3726           0 :         pb[6].gd.flags = gg_enabled|gg_visible;
    3727           0 :         pb[6].gd.u.boxelements = harray6;
    3728           0 :         pb[6].creator = GHBoxCreate;
    3729           0 :         varray[k++] = &pb[6];
    3730           0 :         varray[k++] = NULL;
    3731           0 :         varray[k++] = NULL;
    3732             : 
    3733           0 :         pb[0].gd.pos.x = pb[0].gd.pos.y = 2;
    3734           0 :         pb[0].gd.flags = gg_enabled|gg_visible;
    3735           0 :         pb[0].gd.u.boxelements = varray;
    3736           0 :         pb[0].creator = GHVGroupCreate;
    3737             : 
    3738           0 :         GGadgetsCreate(gip->gw,pb);
    3739             : 
    3740           0 :         GHVBoxSetExpandableRow(pb[0].ret,gb_expandglue);
    3741           0 :         GHVBoxSetExpandableCol(pb[2].ret,gb_expandglue);
    3742           0 :         GHVBoxSetExpandableCol(pb[3].ret,gb_expandglue);
    3743           0 :         GHVBoxSetExpandableCol(pb[4].ret,gb_expandglue);
    3744           0 :         GHVBoxSetExpandableCol(pb[5].ret,gb_expandglue);
    3745           0 :         GHVBoxSetExpandableCol(pb[6].ret,gb_expandgluesame);
    3746             : 
    3747           0 :         SpiroChangePoint(gip);
    3748             : 
    3749           0 :         GHVBoxFitWindow(pb[0].ret);
    3750             : 
    3751           0 :     GWidgetHidePalettes();
    3752           0 :     GDrawSetVisible(gip->gw,true);
    3753           0 :     while ( !gip->done )
    3754           0 :         GDrawProcessOneEvent(NULL);
    3755           0 : }
    3756             : 
    3757           0 : void CVGetInfo(CharView *cv) {
    3758             :     SplinePoint *sp;
    3759             :     SplinePointList *spl;
    3760             :     RefChar *ref;
    3761             :     ImageList *img;
    3762             :     AnchorPoint *ap;
    3763             :     spiro_cp *scp;
    3764             : 
    3765           0 :     if ( !CVOneThingSel(cv,&sp,&spl,&ref,&img,&ap,&scp)) {
    3766           0 :     } else if ( ref!=NULL )
    3767           0 :         RefGetInfo(cv,ref);
    3768           0 :     else if ( img!=NULL )
    3769           0 :         ImgGetInfo(cv,img);
    3770           0 :     else if ( ap!=NULL )
    3771           0 :         ApGetInfo(cv,ap);
    3772           0 :     else if ( scp!=NULL )
    3773           0 :         SpiroPointGetInfo(cv,scp,spl);
    3774             :     else
    3775           0 :         PointGetInfo(cv,sp,spl);
    3776           0 : }
    3777             : 
    3778           0 : void CVPGetInfo(CharView *cv) {
    3779             : 
    3780           0 :     if ( cv->p.ref!=NULL )
    3781           0 :         RefGetInfo(cv,cv->p.ref);
    3782           0 :     else if ( cv->p.img!=NULL )
    3783           0 :         ImgGetInfo(cv,cv->p.img);
    3784           0 :     else if ( cv->p.ap!=NULL )
    3785           0 :         ApGetInfo(cv,cv->p.ap);
    3786           0 :     else if ( cv->p.sp!=NULL )
    3787           0 :         PointGetInfo(cv,cv->p.sp,cv->p.spl);
    3788           0 :     else if ( cv->p.spiro!=NULL )
    3789           0 :         SpiroPointGetInfo(cv,cv->p.spiro,cv->p.spl);
    3790           0 : }
    3791             : 
    3792           0 : void SCRefBy(SplineChar *sc) {
    3793           0 :     int cnt,i,tot=0;
    3794           0 :     char **deps = NULL;
    3795             :     struct splinecharlist *d;
    3796             :     char *buts[3];
    3797             : 
    3798           0 :     buts[0] = _("_Show");
    3799           0 :     buts[1] = _("_Cancel");
    3800           0 :     buts[2] = NULL;
    3801             : 
    3802           0 :     for ( i=0; i<2; ++i ) {
    3803           0 :         cnt = 0;
    3804           0 :         for ( d = sc->dependents; d!=NULL; d=d->next ) {
    3805           0 :             if ( deps!=NULL )
    3806           0 :                 deps[tot-cnt] = copy(d->sc->name);
    3807           0 :             ++cnt;
    3808             :         }
    3809           0 :         if ( cnt==0 )
    3810           0 : return;
    3811           0 :         if ( i==0 )
    3812           0 :             deps = calloc(cnt+1,sizeof(unichar_t *));
    3813           0 :         tot = cnt-1;
    3814             :     }
    3815             : 
    3816           0 :     i = gwwv_choose_with_buttons(_("Dependents"),(const char **) deps, cnt, 0, buts, _("Dependents") );
    3817           0 :     if ( i!=-1 ) {
    3818           0 :         i = tot-i;
    3819           0 :         for ( d = sc->dependents, cnt=0; d!=NULL && cnt<i; d=d->next, ++cnt );
    3820           0 :         CharViewCreate(d->sc,(FontView *) (sc->parent->fv),-1);
    3821             :     }
    3822           0 :     for ( i=0; i<=tot; ++i )
    3823           0 :         free( deps[i] );
    3824           0 :     free(deps);
    3825             : }
    3826             : 
    3827           0 : static int UsedIn(char *name, char *subs) {
    3828           0 :     int nlen = strlen( name );
    3829           0 :     while ( *subs!='\0' ) {
    3830           0 :         if ( strncmp(subs,name,nlen)==0 && (subs[nlen]==' ' || subs[nlen]=='\0'))
    3831           0 : return( true );
    3832           0 :         while ( *subs!=' ' && *subs!='\0' ) ++subs;
    3833           0 :         while ( *subs==' ' ) ++subs;
    3834             :     }
    3835           0 : return( false );
    3836             : }
    3837             : 
    3838           0 : int SCUsedBySubs(SplineChar *sc) {
    3839             :     int k, i;
    3840             :     SplineFont *_sf, *sf;
    3841             :     PST *pst;
    3842             : 
    3843           0 :     if ( sc==NULL )
    3844           0 : return( false );
    3845             : 
    3846           0 :     _sf = sc->parent;
    3847           0 :     if ( _sf->cidmaster!=NULL ) _sf=_sf->cidmaster;
    3848           0 :     k=0;
    3849             :     do {
    3850           0 :         sf = _sf->subfontcnt==0 ? _sf : _sf->subfonts[k];
    3851           0 :         for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
    3852           0 :             for ( pst=sf->glyphs[i]->possub; pst!=NULL; pst=pst->next ) {
    3853           0 :                 if ( pst->type==pst_substitution || pst->type==pst_alternate ||
    3854           0 :                         pst->type==pst_multiple || pst->type==pst_ligature )
    3855           0 :                     if ( UsedIn(sc->name,pst->u.mult.components))
    3856           0 : return( true );
    3857             :             }
    3858             :         }
    3859           0 :         ++k;
    3860           0 :     } while ( k<_sf->subfontcnt );
    3861           0 : return( false );
    3862             : }
    3863             : 
    3864           0 : void SCSubBy(SplineChar *sc) {
    3865             :     int i,j,k,tot;
    3866           0 :     char **deps = NULL;
    3867             :     SplineChar **depsc;
    3868             :     char ubuf[200];
    3869             :     SplineFont *sf, *_sf;
    3870             :     PST *pst;
    3871             :     char *buts[3];
    3872             : 
    3873           0 :     buts[0] = _("Show");
    3874           0 :     buts[1] = _("_Cancel");
    3875           0 :     buts[2] = NULL;
    3876             : 
    3877           0 :     if ( sc==NULL )
    3878           0 : return;
    3879             : 
    3880           0 :     _sf = sc->parent;
    3881           0 :     if ( _sf->cidmaster!=NULL ) _sf=_sf->cidmaster;
    3882           0 :     for ( j=0; j<2; ++j ) {
    3883           0 :         tot = 0;
    3884           0 :         k=0;
    3885             :         do {
    3886           0 :             sf = _sf->subfontcnt==0 ? _sf : _sf->subfonts[k];
    3887           0 :             for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
    3888           0 :                 for ( pst=sf->glyphs[i]->possub; pst!=NULL; pst=pst->next ) {
    3889           0 :                     if ( pst->type==pst_substitution || pst->type==pst_alternate ||
    3890           0 :                             pst->type==pst_multiple || pst->type==pst_ligature )
    3891           0 :                         if ( UsedIn(sc->name,pst->u.mult.components)) {
    3892           0 :                             if ( deps!=NULL ) {
    3893           0 :                                 snprintf(ubuf,sizeof(ubuf),
    3894           0 :                                         _("Subtable %.60s in glyph %.60s"),
    3895           0 :                                         pst->subtable->subtable_name,
    3896           0 :                                         sf->glyphs[i]->name);
    3897           0 :                                 deps[tot] = copy(ubuf);
    3898           0 :                                 depsc[tot] = sf->glyphs[i];
    3899             :                             }
    3900           0 :                             ++tot;
    3901             :                         }
    3902             :                 }
    3903             :             }
    3904           0 :             ++k;
    3905           0 :         } while ( k<_sf->subfontcnt );
    3906           0 :         if ( tot==0 )
    3907           0 : return;
    3908           0 :         if ( j==0 ) {
    3909           0 :             deps = calloc(tot+1,sizeof(char *));
    3910           0 :             depsc = malloc(tot*sizeof(SplineChar *));
    3911             :         }
    3912             :     }
    3913             : 
    3914           0 :     i = gwwv_choose_with_buttons(_("Dependent Substitutions"),(const char **) deps, tot, 0, buts, _("Dependent Substitutions") );
    3915           0 :     if ( i>-1 ) {
    3916           0 :         CharViewCreate(depsc[i],(FontView *) (sc->parent->fv),-1);
    3917             :     }
    3918           0 :     for ( i=0; i<=tot; ++i )
    3919           0 :         free( deps[i] );
    3920           0 :     free(deps);
    3921           0 :     free(depsc);
    3922             : }

Generated by: LCOV version 1.10