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

          Line data    Source code
       1             : /* Copyright (C) 2008-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 "fontforgeui.h"
      28             : #include "splineutil.h"
      29             : #include "tottfgpos.h"
      30             : #include <ustring.h>
      31             : #include <chardata.h>
      32             : #include <utype.h>
      33             : #include <gkeysym.h>
      34             : #include <math.h>
      35             : 
      36           0 : static uint32 TagFromString(char *pt) {
      37             :     char script[4];
      38             : 
      39           0 :     memset(script,' ',4);
      40           0 :     script[0] = *pt++;
      41           0 :     if ( *pt!='\0' ) {
      42           0 :         script[1] = *pt++;
      43           0 :         if ( *pt!='\0' ) {
      44           0 :             script[2] = *pt++;
      45           0 :             if ( *pt!='\0' )
      46           0 :                 script[3] = *pt;
      47             :         }
      48             :     }
      49           0 : return( CHR(script[0],script[1],script[2],script[3]));
      50             : }
      51             : 
      52             : typedef struct basedlg {
      53             :     GWindow gw;
      54             :     SplineFont *sf;
      55             :     struct Base *old;
      56             :     int vertical;
      57             :     int done;
      58             : } BaseDlg;
      59             : 
      60             : typedef struct baselangdlg {
      61             :     GWindow gw;
      62             :     SplineFont *sf;
      63             :     struct baselangextent *old;
      64             :     int vertical;
      65             :     int islang;
      66             :     int done;
      67             :     uint32 script;
      68             : } BaseLangDlg;
      69             : 
      70             : extern GTextInfo scripts[], languages[];
      71             : 
      72             : static struct col_init baselangci[4] = {
      73             :     { me_stringchoicetag , NULL, languages, NULL, N_("Language") },
      74             :     { me_int , NULL, NULL, NULL, N_("Min") },
      75             :     { me_int , NULL, NULL, NULL, N_("Max") },
      76             :     { me_addr, NULL, NULL, NULL, "hidden" }   /* Used to hold per-language data */
      77             :     };
      78             : static struct col_init basefeatci[4] = {
      79             :     { me_string , NULL, NULL, NULL, N_("Feature") },
      80             :     { me_int , NULL, NULL, NULL, N_("Min") },
      81             :     { me_int , NULL, NULL, NULL, N_("Max") },
      82             :     { me_addr, NULL, NULL, NULL, "hidden" }   /* Not used */
      83             :     };
      84             : 
      85             : #define CID_Languages   1008
      86             : #define CID_Extents     1009
      87             : 
      88           0 : static void Base_EnableOtherButtons(GGadget *g, int r, int c) {
      89           0 :     GGadgetSetEnabled(GWidgetGetControl(GGadgetGetWindow(g),CID_Extents),r!=-1);
      90           0 : }
      91             : 
      92           0 : static void Base_DelClean(GGadget *g, int r) {
      93           0 :     int rows, cols = GMatrixEditGetColCnt(g);
      94           0 :     struct matrix_data *md = _GMatrixEditGet(g,&rows);
      95             : 
      96           0 :     BaseLangFree((struct baselangextent *) md[r*cols+cols-1].u.md_str);
      97           0 :     md[r*cols+cols-1].u.md_str = NULL;
      98           0 : }
      99             : 
     100           0 : static void BaseLang_FinishEdit(GGadget *g, int r, int c, int wasnew) {
     101             : 
     102           0 :     if ( wasnew && c==0 ) {
     103           0 :         BaseLangDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
     104           0 :         int rows, cols = GMatrixEditGetColCnt(g);
     105           0 :         struct matrix_data *md = GMatrixEditGet(g,&rows);
     106           0 :         uint32 lang = TagFromString(md[r*cols+0].u.md_str);
     107             :         int gid;
     108             :         SplineChar *sc;
     109             :         DBounds bnd, scb;
     110             : 
     111           0 :         memset(&bnd,0,sizeof(bnd));
     112           0 :         for ( gid=0; gid<b->sf->glyphcnt; ++gid ) if ( (sc=b->sf->glyphs[gid])!=NULL ) {
     113           0 :             if ( lang==CHR('E','N','G',' ') && (sc->unicodeenc<0 || sc->unicodeenc>127))
     114             :                 /* English just uses ASCII */;
     115           0 :             else if ( b->script==CHR('l','a','t','n') &&
     116           0 :                     (sc->unicodeenc<0 || sc->unicodeenc>255) &&
     117             :                     lang!=CHR('V','I','T',' ') )
     118             :                 /* Most languages in latin script only use one accent per */
     119             :                 /*  letter. So latin1 should provide a reasonable bounding */
     120             :                 /*  box. Vietnamese is an exception. */;
     121           0 :             else if ( SCScriptFromUnicode(sc)!=b->script )
     122             :                 /* Not interesting */;
     123             :             else {
     124           0 :                 SplineCharFindBounds(sc,&scb);
     125           0 :                 if ( bnd.minx==bnd.maxx )
     126           0 :                     bnd = scb;
     127             :                 else {
     128           0 :                     if ( scb.minx<bnd.minx ) bnd.minx = scb.minx;
     129           0 :                     if ( scb.miny<bnd.miny ) bnd.miny = scb.miny;
     130           0 :                     if ( scb.maxx>bnd.maxx ) bnd.maxx = scb.maxx;
     131           0 :                     if ( scb.maxy>bnd.maxy ) bnd.maxy = scb.maxy;
     132             :                 }
     133             :             }
     134             :         }
     135           0 :         if ( b->vertical ) {
     136           0 :             md[r*cols+1].u.md_ival = floor(bnd.minx);
     137           0 :             md[r*cols+2].u.md_ival = ceil(bnd.maxx);
     138             :         } else {
     139           0 :             md[r*cols+1].u.md_ival = floor(bnd.miny);
     140           0 :             md[r*cols+2].u.md_ival = ceil(bnd.maxy);
     141             :         }
     142             :     }
     143           0 : }
     144             :         
     145           0 : static void BaseLangMatrixInit(struct matrixinit *mi,struct baselangextent *old,
     146             :         int islang, int isvert) {
     147             :     struct matrix_data *md;
     148             :     int cnt;
     149             :     char lang[8];
     150             :     struct baselangextent *bl;
     151             : 
     152           0 :     memset(mi,0,sizeof(*mi));
     153           0 :     mi->col_cnt = 4;
     154           0 :     mi->col_init = islang ? baselangci : basefeatci;
     155             : 
     156           0 :     mi->col_init[1].title = isvert ? _("Min") : _("Min (descent)");
     157           0 :     mi->col_init[2].title = isvert ? _("Max") : _("Max (ascent)");
     158             : 
     159           0 :     for ( cnt = 0, bl=old; bl!=NULL; bl=bl->next, ++cnt);
     160           0 :     mi->initial_row_cnt = cnt;
     161           0 :     mi->matrix_data     = md = calloc(mi->col_cnt*cnt,sizeof(struct matrix_data));
     162             : 
     163           0 :     for ( cnt = 0, bl=old; bl!=NULL; bl=bl->next, ++cnt) {
     164           0 :         lang[0] = bl->lang>>24;
     165           0 :         lang[1] = bl->lang>>16;
     166           0 :         lang[2] = bl->lang>>8;
     167           0 :         lang[3] = bl->lang;
     168           0 :         lang[4] = '\0';
     169           0 :         md[mi->col_cnt*cnt+0].u.md_str = copy(lang);
     170           0 :         md[mi->col_cnt*cnt+1].u.md_ival = bl->descent;
     171           0 :         md[mi->col_cnt*cnt+2].u.md_ival = bl->ascent;
     172           0 :         md[mi->col_cnt*cnt+mi->col_cnt-1].u.md_str = (char *) BaseLangCopy(bl->features);
     173             :     }
     174             : 
     175           0 :     mi->finishedit = BaseLang_FinishEdit;
     176           0 :     mi->candelete = NULL;
     177           0 :     mi->popupmenu = NULL;
     178           0 :     mi->handle_key = NULL;
     179           0 :     mi->bigedittitle = NULL;
     180           0 : }
     181             : 
     182             : static struct baselangextent *SFBaselang(SplineFont *sf,struct baselangextent *old,
     183             :         int is_vertical, int islang, uint32 script );
     184             : 
     185           0 : static int BaseLang_Extents(GGadget *g, GEvent *e) {
     186           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     187           0 :         BaseLangDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
     188           0 :         GGadget *gme = GWidgetGetControl(b->gw,CID_Languages);
     189           0 :         int rows, cols = GMatrixEditGetColCnt(gme);
     190           0 :         struct matrix_data *md = _GMatrixEditGet(gme,&rows);
     191           0 :         int r = GMatrixEditGetActiveRow(gme);
     192             : 
     193           0 :         if ( r<0 || r>=rows )
     194           0 : return( true );
     195           0 :         md[r*cols+cols-1].u.md_str = (char *)
     196           0 :                 SFBaselang(b->sf,(struct baselangextent *)md[r*cols+cols-1].u.md_str,
     197             :                         b->vertical,false, b->script);
     198             :     }
     199           0 : return( true );
     200             : }
     201             : 
     202           0 : static void BaseLang_DoCancel(BaseLangDlg *b) {
     203           0 :     GGadget *g = GWidgetGetControl(b->gw,CID_Languages);
     204           0 :     int r, rows, cols = GMatrixEditGetColCnt(g);
     205           0 :     struct matrix_data *md = _GMatrixEditGet(g,&rows);
     206             : 
     207           0 :     for ( r=0; r<rows; ++r ) {
     208           0 :         BaseLangFree( (struct baselangextent *) md[r*cols+cols-1].u.md_str);
     209           0 :         md[r*cols+cols-1].u.md_str = NULL;
     210             :     }
     211           0 :     b->done = true;
     212           0 : }
     213             : 
     214           0 : static int BaseLang_Cancel(GGadget *g, GEvent *e) {
     215             :     BaseLangDlg *b;
     216             : 
     217           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     218           0 :         b = GDrawGetUserData(GGadgetGetWindow(g));
     219           0 :         BaseLang_DoCancel(b);
     220             :     }
     221           0 : return( true );
     222             : }
     223             : 
     224           0 : static int BaseLang_OK(GGadget *g, GEvent *e) {
     225             : 
     226           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     227           0 :         BaseLangDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
     228           0 :         GGadget *g = GWidgetGetControl(b->gw,CID_Languages);
     229           0 :         int r, rows, cols = GMatrixEditGetColCnt(g);
     230           0 :         struct matrix_data *md = GMatrixEditGet(g,&rows);
     231             :         struct baselangextent *cur, *last;
     232             : 
     233           0 :         if ( md==NULL )
     234           0 : return( true );
     235             : 
     236           0 :         BaseLangFree(b->old);
     237           0 :         b->old = last = NULL;
     238           0 :         for ( r=0; r<rows; ++r ) {
     239           0 :             cur = chunkalloc(sizeof(struct baselangextent));
     240           0 :             cur->lang = TagFromString(md[r*cols+0].u.md_str);
     241           0 :             cur->descent = md[r*cols+1].u.md_ival;
     242           0 :             cur->ascent = md[r*cols+2].u.md_ival;
     243           0 :             cur->features = (struct baselangextent *) md[r*cols+3].u.md_str;
     244           0 :             md[r*cols+3].u.md_str = NULL;
     245           0 :             if ( last==NULL )
     246           0 :                 b->old = cur;
     247             :             else
     248           0 :                 last->next = cur;
     249           0 :             last = cur;
     250             :         }
     251           0 :         b->done = true;
     252             :     }
     253           0 : return( true );
     254             : }
     255             : 
     256           0 : static int baselang_e_h(GWindow gw, GEvent *event) {
     257           0 :     BaseLangDlg *b = GDrawGetUserData(gw);
     258             : 
     259           0 :     switch ( event->type ) {
     260             :       case et_close:
     261           0 :         BaseLang_DoCancel(b);
     262           0 :       break;
     263             :       case et_char:
     264           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     265           0 :             help("baseline.html");
     266           0 : return( true );
     267             :         }
     268           0 : return( false );
     269             :       break;
     270             :     }
     271           0 : return( true );
     272             : }
     273             : 
     274           0 : static struct baselangextent *SFBaselang(SplineFont *sf,struct baselangextent *old,
     275             :         int is_vertical, int islang, uint32 script ) {
     276             :     int i,j,k;
     277             :     GRect pos;
     278             :     GWindowAttrs wattrs;
     279             :     BaseLangDlg b;
     280             :     GWindow gw;
     281             :     char buffer[200];
     282             :     GGadgetCreateData gcd[13], box[4], buttongcd[2];
     283             :     GGadgetCreateData *buttonarray[8], *varray[12];
     284             :     GTextInfo label[13], buttonlabel[1];
     285             :     struct matrixinit mi;
     286             :     GGadget *g;
     287             : 
     288           0 :     memset(&b,0,sizeof(b));
     289           0 :     b.sf = sf;
     290           0 :     b.old = old;
     291           0 :     b.vertical = is_vertical;
     292           0 :     b.islang = islang;
     293           0 :     b.script = script;
     294             : 
     295           0 :     memset(&wattrs,0,sizeof(wattrs));
     296             : 
     297           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     298           0 :     wattrs.event_masks = ~(1<<et_charup);
     299           0 :     wattrs.restrict_input_to_me = true;
     300           0 :     wattrs.undercursor = 1;
     301           0 :     wattrs.cursor = ct_pointer;
     302           0 :     snprintf(buffer,sizeof(buffer),is_vertical ? _("Vertical Extents for %c%c%c%c") : _("Horizontal Extents for %c%c%c%c"),
     303             :             script>>24, script>>16, script>>8, script);
     304           0 :     wattrs.utf8_window_title = buffer;
     305           0 :     wattrs.is_dlg = true;
     306           0 :     pos.x = pos.y = 0;
     307           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,300));
     308           0 :     pos.height = GDrawPointsToPixels(NULL,200);
     309           0 :     b.gw = gw = GDrawCreateTopWindow(NULL,&pos,baselang_e_h,&b,&wattrs);
     310             : 
     311           0 :     memset(&gcd,0,sizeof(gcd));
     312           0 :     memset(&buttongcd,0,sizeof(buttongcd));
     313           0 :     memset(&box,0,sizeof(box));
     314           0 :     memset(&label,0,sizeof(label));
     315           0 :     memset(&buttonlabel,0,sizeof(buttonlabel));
     316             : 
     317           0 :     i = j = k = 0;
     318           0 :     if ( islang )
     319           0 :         label[i].text = (unichar_t *) _(
     320             :                 "Set the minimum and maximum values by which\n"
     321             :                 "the glyphs in this script extend below and\n"
     322             :                 "above the baseline. This may vary by language" );
     323             :     else
     324           0 :         label[i].text = (unichar_t *) _(
     325             :                 "Set the minimum and maximum values by which\n"
     326             :                 "the glyphs in this script extend below and\n"
     327             :                 "above the baseline when modified by a feature." );
     328           0 :     label[i].text_is_1byte = true;
     329           0 :     gcd[i].gd.label = &label[i];
     330           0 :     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4; 
     331           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     332           0 :     gcd[i].creator = GLabelCreate;
     333           0 :     varray[j++] = &gcd[i++]; varray[j++] = NULL;
     334             : 
     335           0 :     BaseLangMatrixInit(&mi,old,islang,is_vertical);
     336           0 :     gcd[i].gd.pos.width = 300; gcd[i].gd.pos.height = 200;
     337           0 :     gcd[i].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     338           0 :     gcd[i].gd.cid = CID_Languages;
     339           0 :     gcd[i].gd.u.matrix = &mi;
     340           0 :     gcd[i++].creator = GMatrixEditCreate;
     341           0 :     varray[j++] = &gcd[i-1]; varray[j++] = NULL;
     342             : 
     343           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
     344           0 :     label[i].text = (unichar_t *) _("_OK");
     345           0 :     label[i].text_is_1byte = true;
     346           0 :     label[i].text_in_resource = true;
     347           0 :     gcd[i].gd.label = &label[i];
     348           0 :     gcd[i].gd.handle_controlevent = BaseLang_OK;
     349           0 :     gcd[i++].creator = GButtonCreate;
     350             : 
     351           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     352           0 :     label[i].text = (unichar_t *) _("_Cancel");
     353           0 :     label[i].text_is_1byte = true;
     354           0 :     label[i].text_in_resource = true;
     355           0 :     gcd[i].gd.label = &label[i];
     356           0 :     gcd[i].gd.handle_controlevent = BaseLang_Cancel;
     357           0 :     gcd[i++].creator = GButtonCreate;
     358             : 
     359           0 :     buttonarray[0] = GCD_Glue; buttonarray[1] = &gcd[i-2]; buttonarray[2] = GCD_Glue;
     360           0 :     buttonarray[3] = GCD_Glue; buttonarray[4] = &gcd[i-1]; buttonarray[5] = GCD_Glue;
     361           0 :     buttonarray[6] = NULL;
     362           0 :     box[3].gd.flags = gg_enabled|gg_visible;
     363           0 :     box[3].gd.u.boxelements = buttonarray;
     364           0 :     box[3].creator = GHBoxCreate;
     365           0 :     varray[j++] = &box[3]; varray[j++] = NULL; varray[j++] = NULL;
     366             : 
     367           0 :     box[0].gd.pos.x = box[0].gd.pos.y = 2;
     368           0 :     box[0].gd.flags = gg_enabled|gg_visible;
     369           0 :     box[0].gd.u.boxelements = varray;
     370           0 :     box[0].creator = GHVGroupCreate;
     371             : 
     372           0 :     GGadgetsCreate(gw,box);
     373           0 :     GHVBoxSetExpandableRow(box[0].ret,1);
     374           0 :     GHVBoxSetExpandableCol(box[3].ret,gb_expandgluesame);
     375             : 
     376           0 :     buttongcd[0].gd.flags = gg_visible;
     377           0 :     buttonlabel[0].text = (unichar_t *) S_("Set Feature Extents");
     378           0 :     buttonlabel[0].text_is_1byte = true;
     379           0 :     buttonlabel[0].text_in_resource = true;
     380           0 :     buttongcd[0].gd.label = &buttonlabel[0];
     381           0 :     buttongcd[0].gd.cid = CID_Extents;
     382           0 :     buttongcd[0].gd.handle_controlevent = BaseLang_Extents;
     383           0 :     buttongcd[0].creator = GButtonCreate;
     384             : 
     385           0 :     g = GWidgetGetControl(gw,CID_Languages);
     386           0 :     if ( islang ) {
     387           0 :         GMatrixEditAddButtons(g,buttongcd);
     388           0 :         GMatrixEditSetOtherButtonEnable(g,Base_EnableOtherButtons);
     389             :     }
     390           0 :     GMatrixEditShowColumn(g,3,false);
     391             : 
     392           0 :     GMatrixEditSetBeforeDelete(GWidgetGetControl(gw,CID_Languages),Base_DelClean);
     393           0 :     GHVBoxFitWindow(box[0].ret);
     394             : 
     395           0 :     GDrawSetVisible(gw,true);
     396           0 :     while ( !b.done )
     397           0 :         GDrawProcessOneEvent(NULL);
     398           0 :     GDrawDestroyWindow(gw);
     399           0 : return( b.old );
     400             : }
     401             : 
     402             : GTextInfo baselinetags[] = {
     403             :     { (unichar_t *) ("hang"), NULL, 0, 0, (void *) CHR('h','a','n','g'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     404             :     { (unichar_t *) ("icfb"), NULL, 0, 0, (void *) CHR('i','c','f','b'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     405             :     { (unichar_t *) ("icft"), NULL, 0, 0, (void *) CHR('i','c','f','t'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     406             :     { (unichar_t *) ("ideo"), NULL, 0, 0, (void *) CHR('i','d','e','o'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     407             :     { (unichar_t *) ("idtp"), NULL, 0, 0, (void *) CHR('i','d','t','p'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     408             :     { (unichar_t *) ("math"), NULL, 0, 0, (void *) CHR('m','a','t','h'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     409             :     { (unichar_t *) ("romn"), NULL, 0, 0, (void *) CHR('r','o','m','n'), NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     410             :     GTEXTINFO_EMPTY
     411             : };
     412             : 
     413             : static struct col_init baselinesci[10] = {
     414             :     { me_stringchoicetag , NULL, scripts, NULL, N_("writing system|Script") },
     415             :     { me_enum , NULL, baselinetags, NULL, N_("Default Baseline") },
     416             :     { me_int, NULL, NULL, NULL, "hang" },
     417             :     { me_int, NULL, NULL, NULL, "icfb" },
     418             :     { me_int, NULL, NULL, NULL, "icft" },
     419             :     { me_int, NULL, NULL, NULL, "ideo" },
     420             :     { me_int, NULL, NULL, NULL, "idtp" },
     421             :     { me_int, NULL, NULL, NULL, "math" },
     422             :     { me_int, NULL, NULL, NULL, "romn" },
     423             :     { me_int, NULL, NULL, NULL, "hidden" }    /* Used to hold per-script data */
     424             :     };
     425             : static uint32 stdtags[] = {
     426             :     CHR('h','a','n','g'), CHR('i','c','f','b'), CHR('i','c','f','t'), CHR('i','d','e','o'),
     427             :     CHR('i','d','t','p'), CHR('m','a','t','h'), CHR('r','o','m','n'), 0
     428             : };
     429             : 
     430           0 : static void Base_FinishEdit(GGadget *g, int r, int c, int wasnew) {
     431             : 
     432           0 :     if ( wasnew && c==0 ) {
     433           0 :         int rows, cols = GMatrixEditGetColCnt(g);
     434           0 :         struct matrix_data *md = GMatrixEditGet(g,&rows);
     435           0 :         uint32 script = TagFromString(md[r*cols+0].u.md_str);
     436             :         uint32 bsln;
     437           0 :         int i=0,j,k;
     438             : 
     439             : /* This if is duplicated (almost) in tottfaat.c: PerGlyphDefBaseline */
     440           0 :         if ( script==CHR('k','a','n','a') || script==CHR('h','a','n','g') ||
     441           0 :                 script==CHR('h','a','n','i') || script==CHR('b','o','p','o') ||
     442           0 :                 script==CHR('j','a','m','o') || script==CHR('y','i',' ',' '))
     443           0 :             bsln = CHR('i','d','e','o');
     444           0 :         else if ( script==CHR('t','i','b','t' ) ||
     445           0 :                 script == CHR('b','e','n','g' ) || script == CHR('b','n','g','2') ||
     446           0 :                 script == CHR('d','e','v','a' ) || script == CHR('d','e','v','2') ||
     447           0 :                 script == CHR('g','u','j','r' ) || script == CHR('g','j','r','2') ||
     448           0 :                 script == CHR('g','u','r','u' ) || script == CHR('g','u','r','2') ||
     449           0 :                 script == CHR('k','n','d','a' ) || script == CHR('k','n','d','2') ||
     450           0 :                 script == CHR('m','l','y','m' ) || script == CHR('m','l','m','2') ||
     451           0 :                 script == CHR('o','r','y','a' ) || script == CHR('o','r','y','2') ||
     452           0 :                 script == CHR('t','a','m','l' ) || script == CHR('t','m','l','2') ||
     453           0 :                 script == CHR('t','e','l','u' ) || script == CHR('t','e','l','2'))
     454           0 :             bsln = CHR('h','a','n','g');
     455           0 :         else if ( script==CHR('m','a','t','h') )
     456           0 :             bsln = CHR('m','a','t','h');
     457             :         else
     458           0 :             bsln = CHR('r','o','m','n');
     459           0 :         md[r*cols+1].u.md_ival = bsln;
     460           0 :         for ( j=0; j<rows; ++j ) if ( j!=r ) {
     461           0 :             if ( md[j*cols+1].u.md_ival == i ) {
     462           0 :                 for ( k=1; k<cols-1; ++k )
     463           0 :                     md[r*cols+k].u.md_ival = md[j*cols+k].u.md_ival;
     464           0 :         break;
     465             :             }
     466             :         }
     467             :     }
     468           0 : }
     469             :         
     470           0 : static void BaselineMatrixInit(struct matrixinit *mi,struct Base *old) {
     471             :     struct matrix_data *md;
     472             :     int k, i, cnt, mustfreemem;
     473             :     int _maps[20], *mapping;
     474             :     char script[8];
     475             :     struct basescript *bs;
     476             : 
     477           0 :     memset(mi,0,sizeof(*mi));
     478           0 :     mi->col_cnt = 10;
     479           0 :     mi->col_init = baselinesci;
     480             : 
     481           0 :     cnt = 0;
     482           0 :     mustfreemem = 0;
     483           0 :     if ( old!=NULL )
     484           0 :         for ( cnt=0, bs=old->scripts; bs!=NULL; bs=bs->next, ++cnt );
     485           0 :     mi->initial_row_cnt = cnt;
     486           0 :     mi->matrix_data     = md = calloc(mi->col_cnt*cnt,sizeof(struct matrix_data));
     487             : 
     488           0 :     if ( old!=NULL ) {
     489           0 :         if ( old->baseline_cnt<sizeof(_maps)/sizeof(_maps[0]) )
     490           0 :             mapping = _maps;
     491             :         else  {
     492           0 :             mustfreemem = 1;
     493           0 :             mapping = malloc(old->baseline_cnt*sizeof(int));
     494             :         }
     495           0 :         for ( k=0; k<old->baseline_cnt; ++k ) {
     496           0 :             mapping[k] = -1;
     497           0 :             for ( i=0; stdtags[i]!=0; ++i )
     498           0 :                 if ( old->baseline_tags[k]==stdtags[i]) mapping[k] = i+2;
     499             :         }
     500           0 :         for ( cnt=0, bs=old->scripts; bs!=NULL; bs=bs->next, ++cnt ) {
     501           0 :             script[0] = bs->script>>24;
     502           0 :             script[1] = bs->script>>16;
     503           0 :             script[2] = bs->script>>8;
     504           0 :             script[3] = bs->script;
     505           0 :             script[4] = '\0';
     506           0 :             md[mi->col_cnt*cnt+0].u.md_str = copy(script);
     507           0 :             if ( old->baseline_cnt!=0 ) {
     508           0 :                 md[mi->col_cnt*cnt+1].u.md_ival = old->baseline_tags[bs->def_baseline];
     509           0 :                 for ( k=0; k<old->baseline_cnt; ++k ) if ( mapping[k]!=-1 )
     510           0 :                     md[mi->col_cnt*cnt+mapping[k]].u.md_ival = bs->baseline_pos[k];
     511             :             }
     512           0 :             md[mi->col_cnt*cnt+mi->col_cnt-1].u.md_str = (char *) BaseLangCopy(bs->langs);
     513             :         }
     514           0 :         if (mustfreemem != 0) 
     515           0 :             free(mapping);
     516             :     }
     517             : 
     518           0 :     mi->finishedit = Base_FinishEdit;
     519           0 :     mi->candelete = NULL;
     520           0 :     mi->popupmenu = NULL;
     521           0 :     mi->handle_key = NULL;
     522           0 :     mi->bigedittitle = NULL;
     523           0 : }
     524             : 
     525             : 
     526             : #define CID_BaseHang    1001
     527             : #define CID_BaseIcfb    1002
     528             : #define CID_BaseIcft    1003
     529             : #define CID_BaseIdeo    1004
     530             : #define CID_BaseIdtp    1005
     531             : #define CID_BaseMath    1006
     532             : #define CID_BaseRomn    1007
     533             : #define CID_Baselines   1008
     534             : 
     535           0 : static int Base_Extents(GGadget *g, GEvent *e) {
     536           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     537           0 :         BaseDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
     538           0 :         GGadget *gme = GWidgetGetControl(b->gw,CID_Baselines);
     539           0 :         int rows, cols = GMatrixEditGetColCnt(gme);
     540           0 :         struct matrix_data *md = _GMatrixEditGet(gme,&rows);
     541           0 :         int r = GMatrixEditGetActiveRow(gme);
     542             : 
     543           0 :         if ( r<0 || r>=rows )
     544           0 : return( true );
     545           0 :         md[r*cols+cols-1].u.md_str = (char *)
     546           0 :                 SFBaselang(b->sf,(struct baselangextent *)md[r*cols+cols-1].u.md_str,
     547           0 :                         b->vertical,true, TagFromString(md[r*cols+0].u.md_str));
     548             :     }
     549           0 : return( true );
     550             : }
     551             : 
     552           0 : static int Base_ChangeBase(GGadget *g, GEvent *e) {
     553           0 :     if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_radiochanged )) {
     554           0 :         int k, any = false;
     555           0 :         GWindow gw = GGadgetGetWindow(g);
     556           0 :         GGadget *bases = GWidgetGetControl(gw,CID_Baselines);
     557           0 :         for ( k=CID_BaseHang; k<=CID_BaseRomn; ++k ) {
     558           0 :             int checked = GGadgetIsChecked(GWidgetGetControl(gw,k));
     559           0 :             GMatrixEditShowColumn(bases,k-CID_BaseHang+2, checked);
     560           0 :             any |= checked;
     561             :         }
     562             :         
     563           0 :         GMatrixEditShowColumn(bases,1,any);
     564           0 :         GMatrixEditShowColumn(bases,9,false);
     565             :     }
     566           0 : return( true );
     567             : }
     568             : 
     569           0 : static void Base_DoCancel(BaseDlg *b) {
     570           0 :     GGadget *g = GWidgetGetControl(b->gw,CID_Baselines);
     571           0 :     int r, rows, cols = GMatrixEditGetColCnt(g);
     572           0 :     struct matrix_data *md = _GMatrixEditGet(g,&rows);
     573             : 
     574           0 :     for ( r=0; r<rows; ++r ) {
     575           0 :         BaseLangFree( (struct baselangextent *) md[r*cols+cols-1].u.md_str);
     576           0 :         md[r*cols+cols-1].u.md_str = NULL;
     577             :     }
     578           0 :     b->done = true;
     579           0 : }
     580             : 
     581           0 : static int Base_Cancel(GGadget *g, GEvent *e) {
     582             :     BaseDlg *b;
     583             : 
     584           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     585           0 :         b = GDrawGetUserData(GGadgetGetWindow(g));
     586           0 :         Base_DoCancel(b);
     587             :     }
     588           0 : return( true );
     589             : }
     590             : 
     591           0 : static int Base_OK(GGadget *g, GEvent *e) {
     592             : 
     593           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     594           0 :         BaseDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
     595           0 :         GGadget *g = GWidgetGetControl(b->gw,CID_Baselines);
     596           0 :         int r, rows, cols = GMatrixEditGetColCnt(g);
     597           0 :         struct matrix_data *md = GMatrixEditGet(g,&rows);
     598             :         int mapping[20], backmap[20];
     599             :         int i, j, cnt;
     600             :         struct basescript *bs, *last;
     601             : 
     602           0 :         if ( md==NULL )
     603           0 : return( true );
     604             : 
     605           0 :         i=0;
     606           0 :         mapping[0] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseHang))? i++ : -1;
     607           0 :         mapping[1] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseIcfb))? i++ : -1;
     608           0 :         mapping[2] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseIcft))? i++ : -1;
     609           0 :         mapping[3] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseIdeo))? i++ : -1;
     610           0 :         mapping[4] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseIdtp))? i++ : -1;
     611           0 :         mapping[5] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseMath))? i++ : -1;
     612           0 :         mapping[6] = GGadgetIsChecked(GWidgetGetControl(b->gw,CID_BaseRomn))? i++ : -1;
     613           0 :         cnt = i;
     614           0 :         memset(backmap,-1,sizeof(backmap));
     615           0 :         for ( j=0; j<7; ++j ) if ( mapping[j]!=-1 )
     616           0 :             backmap[mapping[j]] = j;
     617             : 
     618           0 :         if ( cnt!=0 ) {
     619           0 :             for ( r=0; r<rows; ++r ) {
     620           0 :                 int tag = md[cols*r+1].u.md_ival;
     621           0 :                 for ( j=0; stdtags[j]!=0 && stdtags[j]!=tag; ++j );
     622           0 :                 if ( stdtags[j]==0 || mapping[ j ]==-1 ) {
     623           0 :                     ff_post_error(_("Bad default baseline"),_("Script '%c%c%c%c' claims baseline '%c%c%c%c' as its default, but that baseline is not currently active."),
     624           0 :                             md[cols*r+0].u.md_ival>>24, md[cols*r+0].u.md_ival>>16,
     625           0 :                             md[cols*r+0].u.md_ival>>8, md[cols*r+0].u.md_ival,
     626             :                             tag>>24, tag>>16, tag>>8, tag );
     627           0 : return( true );
     628             :                 }
     629             :             }
     630             :         }
     631             : 
     632           0 :         BaseFree(b->old);
     633           0 :         b->old = chunkalloc(sizeof(struct Base));
     634             : 
     635           0 :         b->old->baseline_cnt = cnt;
     636           0 :         if ( i!=0 ) {
     637           0 :             b->old->baseline_tags = malloc(cnt*sizeof(uint32));
     638           0 :             for ( i=0; stdtags[i]!=0 ; ++i ) if ( mapping[i]!=-1 )
     639           0 :                 b->old->baseline_tags[mapping[i]] = stdtags[i];
     640             :         }
     641           0 :         last = NULL;
     642           0 :         for ( r=0; r<rows; ++r ) {
     643           0 :             if ( cnt==0 && md[r*cols+cols-1].u.md_str==NULL )
     644           0 :         continue;
     645           0 :             bs = chunkalloc(sizeof(struct basescript));
     646           0 :             bs->script = TagFromString(md[r*cols+0].u.md_str);
     647           0 :             if ( cnt!=0 ) {
     648           0 :                 int tag = md[cols*r+1].u.md_ival;
     649           0 :                 for ( j=0; stdtags[j]!=0 && stdtags[j]!=tag; ++j );
     650           0 :                 bs->def_baseline = mapping[j];
     651           0 :                 bs->baseline_pos = malloc(cnt*sizeof(uint16));
     652           0 :                 for ( i=0; stdtags[i]!=0 ; ++i ) if ( mapping[i]!=-1 )
     653           0 :                     bs->baseline_pos[mapping[i]] = md[r*cols+i+2].u.md_ival;
     654             :             }
     655           0 :             bs->langs = (struct baselangextent *) md[r*cols+cols-1].u.md_str;
     656           0 :             md[r*cols+cols-1].u.md_str = NULL;
     657           0 :             if ( last==NULL )
     658           0 :                 b->old->scripts = bs;
     659             :             else
     660           0 :                 last->next = bs;
     661           0 :             last = bs;
     662             :         }
     663           0 :         b->done = true;
     664             :     }
     665           0 : return( true );
     666             : }
     667             : 
     668           0 : static int base_e_h(GWindow gw, GEvent *event) {
     669           0 :     BaseDlg *b = GDrawGetUserData(gw);
     670             : 
     671           0 :     switch ( event->type ) {
     672             :       case et_close:
     673           0 :         Base_DoCancel(b);
     674           0 :       break;
     675             :       case et_char:
     676           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     677           0 :             help("baseline.html");
     678           0 : return( true );
     679             :         }
     680           0 : return( false );
     681             :       break;
     682             :     }
     683           0 : return( true );
     684             : }
     685             : 
     686           0 : static void BaseUIInit(void) {
     687             :     static int inited = false;
     688             : 
     689           0 :     if ( inited )
     690           0 : return;
     691             : 
     692           0 :     baselinesci[0].title = S_(baselinesci[0].title);
     693           0 :     baselinesci[1].title = S_(baselinesci[1].title);
     694           0 :     baselangci[0].title = S_(baselangci[0].title);
     695           0 :     baselangci[1].title = S_(baselangci[1].title);
     696           0 :     baselangci[2].title = S_(baselangci[2].title);
     697           0 :     basefeatci[0].title = S_(basefeatci[0].title);
     698           0 :     basefeatci[1].title = S_(basefeatci[1].title);
     699           0 :     basefeatci[2].title = S_(basefeatci[2].title);
     700           0 :     inited = true;
     701             : }
     702             : 
     703           0 : struct Base *SFBaselines(SplineFont *sf,struct Base *old,int is_vertical) {
     704             :     int i,j,k;
     705             :     GRect pos;
     706             :     GWindowAttrs wattrs;
     707             :     BaseDlg b;
     708             :     GWindow gw;
     709             :     char buffer[200];
     710             :     GGadgetCreateData gcd[13], box[4], buttongcd[2];
     711             :     GGadgetCreateData *buttonarray[8], *varray[12], *hvarray[12];
     712             :     GTextInfo label[13], buttonlabel[1];
     713             :     struct matrixinit mi;
     714             :     GGadget *g;
     715             : 
     716           0 :     memset(&b,0,sizeof(b));
     717           0 :     b.sf = sf;
     718           0 :     b.sf = sf;
     719           0 :     b.old = old;
     720           0 :     b.vertical = is_vertical;
     721             : 
     722           0 :     memset(&wattrs,0,sizeof(wattrs));
     723             : 
     724           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     725           0 :     wattrs.event_masks = ~(1<<et_charup);
     726           0 :     wattrs.restrict_input_to_me = true;
     727           0 :     wattrs.undercursor = 1;
     728           0 :     wattrs.cursor = ct_pointer;
     729           0 :     snprintf(buffer,sizeof(buffer),"%s", is_vertical ? _("Vertical Baselines") : _("Horizontal Baselines") );
     730           0 :     wattrs.utf8_window_title = buffer;
     731           0 :     wattrs.is_dlg = true;
     732           0 :     pos.x = pos.y = 0;
     733           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,300));
     734           0 :     pos.height = GDrawPointsToPixels(NULL,200);
     735           0 :     b.gw = gw = GDrawCreateTopWindow(NULL,&pos,base_e_h,&b,&wattrs);
     736             : 
     737           0 :     LookupUIInit();
     738           0 :     BaseUIInit();
     739             : 
     740           0 :     memset(&gcd,0,sizeof(gcd));
     741           0 :     memset(&buttongcd,0,sizeof(buttongcd));
     742           0 :     memset(&box,0,sizeof(box));
     743           0 :     memset(&label,0,sizeof(label));
     744           0 :     memset(&buttonlabel,0,sizeof(buttonlabel));
     745             : 
     746           0 :     i = j = k = 0;
     747           0 :     label[i].text = (unichar_t *) _("From the list below, select the baselines for which you\nwill provide data.");
     748           0 :     label[i].text_is_1byte = true;
     749           0 :     gcd[i].gd.label = &label[i];
     750           0 :     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4; 
     751           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     752           0 :     gcd[i].creator = GLabelCreate;
     753           0 :     varray[j++] = &gcd[i++]; varray[j++] = NULL;
     754             : 
     755           0 :     label[i].text = (unichar_t *) _("hang");
     756           0 :     label[i].text_is_1byte = true;
     757           0 :     label[i].text_in_resource = true;
     758           0 :     gcd[i].gd.label = &label[i];
     759           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     760           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Indic (& Tibetan) hanging baseline");
     761           0 :     gcd[i].gd.cid = CID_BaseHang;
     762           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     763           0 :     gcd[i].creator = GCheckBoxCreate;
     764           0 :     hvarray[k++] = &gcd[i++];
     765             : 
     766           0 :     label[i].text = (unichar_t *) _("icfb");
     767           0 :     label[i].text_is_1byte = true;
     768           0 :     label[i].text_in_resource = true;
     769           0 :     gcd[i].gd.label = &label[i];
     770           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     771           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Ideographic character face bottom edge baseline");
     772           0 :     gcd[i].gd.cid = CID_BaseIcfb;
     773           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     774           0 :     gcd[i].creator = GCheckBoxCreate;
     775           0 :     hvarray[k++] = &gcd[i++];
     776             : 
     777           0 :     label[i].text = (unichar_t *) _("icft");
     778           0 :     label[i].text_is_1byte = true;
     779           0 :     label[i].text_in_resource = true;
     780           0 :     gcd[i].gd.label = &label[i];
     781           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     782           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Ideographic character face top edge baseline");
     783           0 :     gcd[i].gd.cid = CID_BaseIcft;
     784           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     785           0 :     gcd[i].creator = GCheckBoxCreate;
     786           0 :     hvarray[k++] = &gcd[i++];
     787             : 
     788           0 :     label[i].text = (unichar_t *) _("ideo");
     789           0 :     label[i].text_is_1byte = true;
     790           0 :     label[i].text_in_resource = true;
     791           0 :     gcd[i].gd.label = &label[i];
     792           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     793           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Ideographic em-box bottom edge baseline");
     794           0 :     gcd[i].gd.cid = CID_BaseIdeo;
     795           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     796           0 :     gcd[i].creator = GCheckBoxCreate;
     797           0 :     hvarray[k++] = &gcd[i++]; hvarray[k++] = NULL;
     798             : 
     799           0 :     label[i].text = (unichar_t *) _("idtp");
     800           0 :     label[i].text_is_1byte = true;
     801           0 :     label[i].text_in_resource = true;
     802           0 :     gcd[i].gd.label = &label[i];
     803           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     804           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Ideographic em-box top edge baseline");
     805           0 :     gcd[i].gd.cid = CID_BaseIdtp;
     806           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     807           0 :     gcd[i].creator = GCheckBoxCreate;
     808           0 :     hvarray[k++] = &gcd[i++];
     809             : 
     810           0 :     label[i].text = (unichar_t *) _("math");
     811           0 :     label[i].text_is_1byte = true;
     812           0 :     label[i].text_in_resource = true;
     813           0 :     gcd[i].gd.label = &label[i];
     814           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     815           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Mathematical centerline");
     816           0 :     gcd[i].gd.cid = CID_BaseMath;
     817           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     818           0 :     gcd[i].creator = GCheckBoxCreate;
     819           0 :     hvarray[k++] = &gcd[i++];
     820             : 
     821           0 :     label[i].text = (unichar_t *) _("romn");
     822           0 :     label[i].text_is_1byte = true;
     823           0 :     label[i].text_in_resource = true;
     824           0 :     gcd[i].gd.label = &label[i];
     825           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
     826           0 :     gcd[i].gd.popup_msg = (unichar_t *) _("Baseline used for Latin, Greek, Cyrillic text.");
     827           0 :     gcd[i].gd.cid = CID_BaseRomn;
     828           0 :     gcd[i].gd.handle_controlevent = Base_ChangeBase;
     829           0 :     gcd[i].creator = GCheckBoxCreate;
     830           0 :     hvarray[k++] = &gcd[i++];
     831           0 :     hvarray[k++] = GCD_Glue; hvarray[k++] = NULL; hvarray[k++] = NULL;
     832             : 
     833           0 :     box[2].gd.flags = gg_enabled|gg_visible;
     834           0 :     box[2].gd.u.boxelements = hvarray;
     835           0 :     box[2].creator = GHVBoxCreate;
     836           0 :     varray[j++] = &box[2]; varray[j++] = NULL;
     837             : 
     838           0 :     label[i].text = (unichar_t *) _(
     839             :             "If any of the above baselines are active then you should\n"
     840             :             "specify which one is the default baseline for each script\n"
     841             :             "in the font, and specify how to position glyphs in this\n"
     842             :             "script relative to all active baselines");
     843           0 :     label[i].text_is_1byte = true;
     844           0 :     gcd[i].gd.label = &label[i];
     845           0 :     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4; 
     846           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     847           0 :     gcd[i].creator = GLabelCreate;
     848           0 :     varray[j++] = &gcd[i++]; varray[j++] = NULL;
     849             : 
     850           0 :     BaselineMatrixInit(&mi,old);
     851           0 :     gcd[i].gd.pos.width = 300; gcd[i].gd.pos.height = 200;
     852           0 :     gcd[i].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     853           0 :     gcd[i].gd.cid = CID_Baselines;
     854           0 :     gcd[i].gd.u.matrix = &mi;
     855           0 :     gcd[i++].creator = GMatrixEditCreate;
     856           0 :     varray[j++] = &gcd[i-1]; varray[j++] = NULL;
     857             : 
     858           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
     859           0 :     label[i].text = (unichar_t *) _("_OK");
     860           0 :     label[i].text_is_1byte = true;
     861           0 :     label[i].text_in_resource = true;
     862           0 :     gcd[i].gd.label = &label[i];
     863           0 :     gcd[i].gd.handle_controlevent = Base_OK;
     864           0 :     gcd[i++].creator = GButtonCreate;
     865             : 
     866           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     867           0 :     label[i].text = (unichar_t *) _("_Cancel");
     868           0 :     label[i].text_is_1byte = true;
     869           0 :     label[i].text_in_resource = true;
     870           0 :     gcd[i].gd.label = &label[i];
     871           0 :     gcd[i].gd.handle_controlevent = Base_Cancel;
     872           0 :     gcd[i++].creator = GButtonCreate;
     873             : 
     874           0 :     buttonarray[0] = GCD_Glue; buttonarray[1] = &gcd[i-2]; buttonarray[2] = GCD_Glue;
     875           0 :     buttonarray[3] = GCD_Glue; buttonarray[4] = &gcd[i-1]; buttonarray[5] = GCD_Glue;
     876           0 :     buttonarray[6] = NULL;
     877           0 :     box[3].gd.flags = gg_enabled|gg_visible;
     878           0 :     box[3].gd.u.boxelements = buttonarray;
     879           0 :     box[3].creator = GHBoxCreate;
     880           0 :     varray[j++] = &box[3]; varray[j++] = NULL; varray[j++] = NULL;
     881             : 
     882           0 :     box[0].gd.pos.x = box[0].gd.pos.y = 2;
     883           0 :     box[0].gd.flags = gg_enabled|gg_visible;
     884           0 :     box[0].gd.u.boxelements = varray;
     885           0 :     box[0].creator = GHVGroupCreate;
     886             : 
     887           0 :     GGadgetsCreate(gw,box);
     888           0 :     GHVBoxSetExpandableRow(box[0].ret,3);
     889           0 :     GHVBoxSetExpandableCol(box[3].ret,gb_expandgluesame);
     890             : 
     891           0 :     buttongcd[0].gd.flags = gg_visible;
     892           0 :     buttonlabel[0].text = (unichar_t *) S_("Set Extents");
     893           0 :     buttonlabel[0].text_is_1byte = true;
     894           0 :     buttonlabel[0].text_in_resource = true;
     895           0 :     buttongcd[0].gd.label = &buttonlabel[0];
     896           0 :     buttongcd[0].gd.cid = CID_Extents;
     897           0 :     buttongcd[0].gd.handle_controlevent = Base_Extents;
     898           0 :     buttongcd[0].creator = GButtonCreate;
     899             : 
     900           0 :     g = GWidgetGetControl(gw,CID_Baselines);
     901           0 :     GMatrixEditAddButtons(g,buttongcd);
     902           0 :     GMatrixEditSetOtherButtonEnable(g,Base_EnableOtherButtons);
     903             : 
     904           0 :     GMatrixEditSetBeforeDelete(GWidgetGetControl(gw,CID_Baselines),Base_DelClean);
     905           0 :     if ( old!=NULL ) {
     906           0 :         for ( k=0; k<old->baseline_cnt; ++k ) {
     907           0 :             for ( i=0; stdtags[i]!=0; ++i )
     908           0 :                 if ( old->baseline_tags[k] == stdtags[i] ) {
     909           0 :                     GGadgetSetChecked(GWidgetGetControl(gw,CID_BaseHang+i),true);
     910           0 :             break;
     911             :                 }
     912             :         }
     913             :     }
     914           0 :     Base_ChangeBase(GWidgetGetControl(gw,CID_BaseHang), NULL);
     915           0 :     GHVBoxFitWindow(box[0].ret);
     916             : 
     917           0 :     GDrawSetVisible(gw,true);
     918           0 :     while ( !b.done )
     919           0 :         GDrawProcessOneEvent(NULL);
     920           0 :     GDrawDestroyWindow(gw);
     921           0 : return( b.old );
     922             : }

Generated by: LCOV version 1.10