LCOV - code coverage report
Current view: top level - fontforgeexe - justifydlg.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 638 0.0 %
Date: 2017-08-04 Functions: 0 27 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 "fontforgeui.h"
      28             : #include "lookups.h"
      29             : #include "splineutil.h"
      30             : #include <ustring.h>
      31             : #include <chardata.h>
      32             : #include <utype.h>
      33             : #include <gkeysym.h>
      34             : #include <math.h>
      35             : 
      36             : extern GTextInfo scripts[], languages[];
      37             : 
      38             : static char *JSTF_GlyphDlg(GGadget *, int r, int c);
      39             : static char *JSTF_LookupListDlg(GGadget *, int r, int c);
      40             : static char *JSTF_Langs(GGadget *, int r, int c);
      41             : 
      42             : static struct col_init glyph_ci[] = {
      43             :     { me_string , NULL, NULL, NULL, N_("Glyph Names") },
      44             :     COL_INIT_EMPTY
      45             : };
      46             : 
      47             : static struct col_init lookup_ci[] = {
      48             :     { me_enum , NULL, NULL, NULL, N_("Lookups") },
      49             :     COL_INIT_EMPTY
      50             : };
      51             : 
      52             : static struct col_init jstf_lang_ci[] = {
      53             :     { me_stringchoicetag , NULL, languages, NULL, N_("Language") },
      54             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Extend Lookups On") },
      55             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Extend Lookups Off") },
      56             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Extend Max Lookups") },
      57             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Shrink Lookups On") },
      58             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Shrink Lookups Off") },
      59             :     { me_funcedit, JSTF_LookupListDlg, NULL, NULL, N_("Shrink Max Lookups") },
      60             :     COL_INIT_EMPTY
      61             : };
      62             : 
      63             : static struct col_init justify_ci[] = {
      64             :     { me_stringchoicetag , NULL, scripts, NULL, N_("writing system|Script") },
      65             :     { me_funcedit, JSTF_GlyphDlg, NULL, NULL, N_("Extenders") },
      66             :     { me_button, JSTF_Langs, NULL, NULL, N_("Language info") },
      67             :     { me_addr, NULL, NULL, NULL, N_("Hidden") },
      68             :     COL_INIT_EMPTY
      69             : };
      70             : 
      71             : struct glyph_list_dlg {
      72             :     int done;
      73             :     char *ret;
      74             :     GWindow gw;
      75             :     SplineFont *sf;
      76             : };
      77             : 
      78             : typedef struct jstf_dlg {
      79             :     int done, ldone;
      80             :     GWindow gw, lgw;
      81             :     SplineFont *sf;
      82             :     struct jstf_lang **here;
      83             : } Jstf_Dlg;
      84             : 
      85             : #define CID_OK          1001
      86             : #define CID_Cancel      1002
      87             : 
      88             : #define CID_Glyphs      2001
      89             : #define CID_Lookups     2002
      90             : #define CID_Languages   2003
      91             : #define CID_Scripts     2004
      92             : 
      93           0 : static void JustUIInit(void) {
      94             :     static int done = false;
      95             :     int i, j;
      96             :     static struct col_init *needswork[] = {
      97             :         justify_ci, jstf_lang_ci, lookup_ci, glyph_ci,
      98             :         NULL
      99             :     };
     100             : 
     101           0 :     if ( done )
     102           0 : return;
     103           0 :     done = true;
     104           0 :     for ( j=0; needswork[j]!=NULL; ++j ) {
     105           0 :         for ( i=0; needswork[j][i].title!=NULL; ++i )
     106           0 :             if ( needswork[j][i].title!=NULL )
     107           0 :                 needswork[j][i].title = S_(needswork[j][i].title);
     108             :     }
     109             : }
     110             : 
     111             : /* ************************************************************************** */
     112             : /* dlg which presents a list of glyph names                                   */
     113             : /* ************************************************************************** */
     114             : 
     115           0 : static unichar_t **JSTF_Glyph_Completion(GGadget *t,int from_tab) {
     116           0 :     struct glyph_list_dlg *gld = GDrawGetUserData(GDrawGetParentWindow(GGadgetGetWindow(t)));
     117           0 :     SplineFont *sf = gld->sf;
     118             : 
     119           0 : return( SFGlyphNameCompletion(sf,t,from_tab,false));
     120             : }
     121             : 
     122           0 : static void GlyphMatrixInit(struct matrixinit *mi,char *glyphstr,SplineFont *sf) {
     123             :     struct matrix_data *md;
     124             :     int k, cnt;
     125             :     char *start, *end;
     126             : 
     127           0 :     memset(mi,0,sizeof(*mi));
     128           0 :     mi->col_cnt = 1;
     129           0 :     mi->col_init = glyph_ci;
     130             : 
     131           0 :     md = NULL;
     132           0 :     for ( k=0; k<2; ++k ) {
     133           0 :         cnt = 0;
     134           0 :         if ( glyphstr!=NULL ) for ( start = glyphstr; *start; ) {
     135           0 :             for ( end=start; *end!='\0' && *end!=' ' && *end!=','; ++end );
     136           0 :             if ( k ) {
     137           0 :                 char *str = copyn(start,end-start);
     138           0 :                 md[1*cnt+0].u.md_str = SFNameList2NameUni(sf,str);
     139           0 :                 free(str);
     140             :             }
     141           0 :             ++cnt;
     142           0 :             while ( *end==' ' || *end==',' ) ++end;
     143           0 :             start = end;
     144             :         }
     145           0 :         if ( md==NULL )
     146           0 :             md = calloc(1*(cnt+10),sizeof(struct matrix_data));
     147             :     }
     148           0 :     mi->matrix_data = md;
     149           0 :     mi->initial_row_cnt = cnt;
     150           0 : }
     151             : 
     152           0 : static int JSTF_Glyph_OK(GGadget *g, GEvent *e) {
     153             : 
     154           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     155           0 :         struct glyph_list_dlg *gld = GDrawGetUserData(GGadgetGetWindow(g));
     156             :         int rows, i, len;
     157           0 :         struct matrix_data *strings = GMatrixEditGet(GWidgetGetControl(gld->gw,CID_Glyphs), &rows);
     158             :         char *ret;
     159             : 
     160           0 :         if ( rows==0 )
     161           0 :             gld->ret = NULL;
     162             :         else {
     163           0 :             len = 0;
     164           0 :             for ( i=0; i<rows; ++i )
     165           0 :                 len += strlen(strings[1*i+0].u.md_str) +1;
     166           0 :             ret = malloc(len+1);
     167           0 :             for ( i=0; i<rows; ++i ) {
     168           0 :                 strcpy(ret,strings[1*i+0].u.md_str);
     169           0 :                 strcat(ret," ");
     170           0 :                 ret += strlen(ret);
     171             :             }
     172           0 :             if ( ret>gld->ret && ret[-1] == ' ' )
     173           0 :                 ret[-1] = '\0';
     174           0 :             gld->ret = GlyphNameListDeUnicode(ret);
     175           0 :             free(ret);
     176             :         }
     177           0 :         gld->done = true;
     178             :     }
     179           0 : return( true );
     180             : }
     181             : 
     182           0 : static int JSTF_Glyph_Cancel(GGadget *g, GEvent *e) {
     183             : 
     184           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     185           0 :         struct glyph_list_dlg *gld = GDrawGetUserData(GGadgetGetWindow(g));
     186           0 :         gld->done = true;
     187           0 :         gld->ret = NULL;
     188             :     }
     189           0 : return( true );
     190             : }
     191             : 
     192           0 : static int glyph_e_h(GWindow gw, GEvent *event) {
     193             : 
     194           0 :     if ( event->type==et_close ) {
     195           0 :         struct glyph_list_dlg *gld = GDrawGetUserData(gw);
     196           0 :         gld->done = true;
     197           0 :         gld->ret = NULL;
     198           0 :     } else if ( event->type == et_char ) {
     199           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     200           0 :             help("justify.html#glyphs-dlg");
     201           0 : return( true );
     202             :         }
     203           0 : return( false );
     204             :     }
     205             : 
     206           0 : return( true );
     207             : }
     208             : 
     209           0 : char *GlyphListDlg(SplineFont *sf, char *glyphstr) {
     210             :     int i, k, j;
     211             :     GRect pos;
     212             :     GWindow gw;
     213             :     GWindowAttrs wattrs;
     214             :     GGadgetCreateData gcd[4], boxes[3];
     215             :     GGadgetCreateData *varray[6], *harray3[8];
     216             :     GTextInfo label[4];
     217             :     struct matrixinit mi;
     218             :     struct glyph_list_dlg gld;
     219             : 
     220           0 :     memset(&gld,0,sizeof(gld));
     221           0 :     gld.sf = sf;
     222             : 
     223           0 :     memset(&wattrs,0,sizeof(wattrs));
     224           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     225           0 :     wattrs.event_masks = ~(1<<et_charup);
     226           0 :     wattrs.is_dlg = true;
     227           0 :     wattrs.restrict_input_to_me = 1;
     228           0 :     wattrs.undercursor = 1;
     229           0 :     wattrs.cursor = ct_pointer;
     230           0 :     wattrs.utf8_window_title = _("Extender Glyphs (kashidas, etc.)");
     231           0 :     pos.x = pos.y = 0;
     232           0 :     pos.width =GDrawPointsToPixels(NULL,GGadgetScale(268));
     233           0 :     pos.height = GDrawPointsToPixels(NULL,375);
     234           0 :     gld.gw = gw = GDrawCreateTopWindow(NULL,&pos,glyph_e_h,&gld,&wattrs);
     235             : 
     236           0 :     GlyphMatrixInit(&mi,glyphstr,sf);
     237             : 
     238           0 :     memset(&gcd,0,sizeof(gcd));
     239           0 :     memset(&boxes,0,sizeof(boxes));
     240           0 :     memset(&label,0,sizeof(label));
     241           0 :     k=j=0;
     242           0 :     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[1].gd.pos.y+14;
     243           0 :     gcd[k].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     244           0 :     gcd[k].gd.cid = CID_Glyphs;
     245           0 :     gcd[k].gd.u.matrix = &mi;
     246           0 :     gcd[k].gd.popup_msg = (unichar_t *) _( "A list of glyph names");
     247           0 :     gcd[k].creator = GMatrixEditCreate;
     248           0 :     varray[j++] = &gcd[k++]; varray[j++] = NULL;
     249             : 
     250           0 :     gcd[k].gd.pos.x = 30-3; 
     251           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     252           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
     253           0 :     label[k].text = (unichar_t *) _("_OK");
     254           0 :     label[k].text_is_1byte = true;
     255           0 :     label[k].text_in_resource = true;
     256           0 :     gcd[k].gd.label = &label[k];
     257           0 :     gcd[k].gd.handle_controlevent = JSTF_Glyph_OK;
     258           0 :     gcd[k].gd.cid = CID_OK;
     259           0 :     gcd[k++].creator = GButtonCreate;
     260             : 
     261           0 :     gcd[k].gd.pos.x = -30;
     262           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     263           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     264           0 :     label[k].text = (unichar_t *) _("_Cancel");
     265           0 :     label[k].text_is_1byte = true;
     266           0 :     label[k].text_in_resource = true;
     267           0 :     gcd[k].gd.label = &label[k];
     268           0 :     gcd[k].gd.handle_controlevent = JSTF_Glyph_Cancel;
     269           0 :     gcd[k].gd.cid = CID_Cancel;
     270           0 :     gcd[k++].creator = GButtonCreate;
     271             : 
     272           0 :     harray3[0] = harray3[2] = harray3[3] = harray3[4] = harray3[6] = GCD_Glue;
     273           0 :     harray3[7] = NULL;
     274           0 :     harray3[1] = &gcd[k-2]; harray3[5] = &gcd[k-1];
     275             : 
     276           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     277           0 :     boxes[0].gd.u.boxelements = harray3;
     278           0 :     boxes[0].creator = GHBoxCreate;
     279           0 :     varray[j++] = &boxes[0]; varray[j++] = NULL; varray[j] = NULL;
     280             :     
     281           0 :     boxes[1].gd.pos.x = boxes[1].gd.pos.y = 2;
     282           0 :     boxes[1].gd.flags = gg_enabled|gg_visible;
     283           0 :     boxes[1].gd.u.boxelements = varray;
     284           0 :     boxes[1].creator = GHVGroupCreate;
     285             : 
     286           0 :     GGadgetsCreate(gw,boxes+1);
     287             : 
     288           0 :     for ( i=0; i<mi.initial_row_cnt; ++i ) {
     289           0 :         free( mi.matrix_data[2*i+0].u.md_str );
     290             :     }
     291           0 :     free( mi.matrix_data );
     292             : 
     293           0 :     GMatrixEditSetNewText(gcd[0].ret,S_("GlyphName|New"));
     294           0 :     GMatrixEditSetColumnCompletion(gcd[0].ret, 0, JSTF_Glyph_Completion );
     295           0 :     GHVBoxSetExpandableCol(boxes[0].ret,gb_expandgluesame);
     296             : 
     297           0 :     GHVBoxFitWindow(boxes[1].ret);
     298             : 
     299           0 :     GDrawSetVisible(gw,true);
     300           0 :     while ( !gld.done )
     301           0 :         GDrawProcessOneEvent(NULL);
     302           0 :     GDrawDestroyWindow(gw);
     303           0 : return( gld.ret );
     304             : }
     305             : 
     306           0 : static char *JSTF_GlyphDlg(GGadget *g, int r, int c) {
     307             :     int rows;
     308           0 :     struct matrix_data *strings = GMatrixEditGet(g, &rows);
     309           0 :     int cols = GMatrixEditGetColCnt(g);
     310           0 :     char *glyphstr = strings[cols*r+c].u.md_str;
     311           0 :     Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     312             : 
     313           0 : return( GlyphListDlg(jd->sf,glyphstr));
     314             : }
     315             : 
     316             : /* ************************************************************************** */
     317             : /* dlg which presents a list of lookups                                       */
     318             : /* ************************************************************************** */
     319             : 
     320           0 : static void LookupMatrixInit(struct matrixinit *mi,char *lookupstr,
     321             :         SplineFont *sf, int col) {
     322             :     struct matrix_data *md;
     323             :     int j, k, cnt;
     324             :     char *temp;
     325             :     char *start, *end;
     326             : 
     327           0 :     memset(mi,0,sizeof(*mi));
     328           0 :     mi->col_cnt = 1;
     329           0 :     mi->col_init = lookup_ci;
     330             : 
     331           0 :     lookup_ci[0].enum_vals = SFLookupArrayFromMask(sf,col==3 || col==6 ? (gpos_single_mask|gpos_pair_mask) : 0 );
     332             : 
     333           0 :     md = NULL;
     334           0 :     for ( k=0; k<2; ++k ) {
     335           0 :         cnt = 0;
     336           0 :         if ( lookupstr!=NULL ) for ( start = lookupstr; *start; ) {
     337           0 :             for ( end=start; *end!='\0' && *end!=','; ++end );
     338           0 :             if ( k ) {
     339           0 :                 for ( j=0; (temp=(char *) (lookup_ci[0].enum_vals[j].text))!=NULL; ++j )
     340           0 :                     if ( strlen(temp)==end-start && strncmp(temp,start,end-start)==0 ) {
     341           0 :                         md[1*cnt++ + 0].u.md_ival = (intpt) lookup_ci[0].enum_vals[j].userdata;
     342           0 :                 break;
     343             :                     }
     344             :             } else
     345           0 :                 ++cnt;
     346           0 :             while ( *end==' ' || *end==',') ++end;
     347           0 :             start = end;
     348             :         }
     349           0 :         if ( md==NULL )
     350           0 :             md = calloc(1*(cnt+10),sizeof(struct matrix_data));
     351             :     }
     352           0 :     mi->matrix_data = md;
     353           0 :     mi->initial_row_cnt = cnt;
     354           0 : }
     355             : 
     356           0 : static int JSTF_Lookup_OK(GGadget *g, GEvent *e) {
     357             : 
     358           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     359           0 :         struct glyph_list_dlg *gld = GDrawGetUserData(GGadgetGetWindow(g));
     360             :         int rows, i, len;
     361           0 :         struct matrix_data *strings = GMatrixEditGet(GWidgetGetControl(gld->gw,CID_Lookups), &rows);
     362             :         char *ret;
     363             : 
     364           0 :         if ( rows==0 )
     365           0 :             gld->ret = NULL;
     366             :         else {
     367           0 :             len = 0;
     368           0 :             for ( i=0; i<rows; ++i ) {
     369           0 :                 OTLookup *otl = (OTLookup *) strings[1*i+0].u.md_ival;
     370           0 :                 len += strlen(otl->lookup_name) +2;
     371             :             }
     372           0 :             gld->ret = ret = malloc(len+1);
     373           0 :             for ( i=0; i<rows; ++i ) {
     374           0 :                 OTLookup *otl = (OTLookup *) strings[1*i+0].u.md_ival;
     375           0 :                 strcpy(ret,otl->lookup_name);
     376           0 :                 strcat(ret,", ");
     377           0 :                 ret += strlen(ret);
     378             :             }
     379           0 :             if ( ret>gld->ret && ret[-1] == ' ' )
     380           0 :                 *--ret = '\0';
     381           0 :             if ( ret>gld->ret && ret[-1] == ',' )
     382           0 :                 *--ret = '\0';
     383             :         }
     384           0 :         gld->done = true;
     385             :     }
     386           0 : return( true );
     387             : }
     388             : 
     389           0 : static int lookup_e_h(GWindow gw, GEvent *event) {
     390             : 
     391           0 :     if ( event->type==et_close ) {
     392           0 :         struct glyph_list_dlg *gld = GDrawGetUserData(gw);
     393           0 :         gld->done = true;
     394           0 :         gld->ret = NULL;
     395           0 :     } else if ( event->type == et_char ) {
     396           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     397           0 :             help("justify.html#lookup-dlg");
     398           0 : return( true );
     399             :         }
     400           0 : return( false );
     401             :     }
     402             : 
     403           0 : return( true );
     404             : }
     405             : 
     406           0 : static char *JSTF_LookupListDlg(GGadget *g, int r, int c) {
     407             :     int rows, k, j;
     408           0 :     struct matrix_data *strings = GMatrixEditGet(g, &rows);
     409           0 :     int cols = GMatrixEditGetColCnt(g);
     410           0 :     char *lookupstr = strings[cols*r+c].u.md_str;
     411           0 :     Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     412             :     GRect pos;
     413             :     GWindow gw;
     414             :     GWindowAttrs wattrs;
     415             :     GGadgetCreateData gcd[4], boxes[3];
     416             :     GGadgetCreateData *varray[6], *harray3[8];
     417             :     GTextInfo label[4];
     418             :     struct matrixinit mi;
     419             :     struct glyph_list_dlg gld;
     420             : 
     421           0 :     memset(&gld,0,sizeof(gld));
     422           0 :     gld.sf = jd->sf;
     423             : 
     424           0 :     memset(&wattrs,0,sizeof(wattrs));
     425           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     426           0 :     wattrs.event_masks = ~(1<<et_charup);
     427           0 :     wattrs.is_dlg = true;
     428           0 :     wattrs.restrict_input_to_me = 1;
     429           0 :     wattrs.undercursor = 1;
     430           0 :     wattrs.cursor = ct_pointer;
     431           0 :     wattrs.utf8_window_title =
     432             :             c==1 ? _("Lookups turned ON to extend a line") :
     433             :             c==2 ? _("Lookups turned OFF to extend a line") :
     434             :             c==3 ? _("Lookups which specify the maximum size by which a glyph may grow") :
     435             :             c==4 ? _("Lookups turned ON to shrink a line") :
     436             :             c==5 ? _("Lookups turned OFF to shrink a line") :
     437             :                    _("Lookups which specify the maximum size by which a glyph may shrink");
     438           0 :     pos.x = pos.y = 0;
     439           0 :     pos.width =GDrawPointsToPixels(NULL,GGadgetScale(268));
     440           0 :     pos.height = GDrawPointsToPixels(NULL,375);
     441           0 :     gld.gw = gw = GDrawCreateTopWindow(NULL,&pos,lookup_e_h,&gld,&wattrs);
     442             : 
     443           0 :     LookupMatrixInit(&mi,lookupstr,gld.sf,c);
     444             : 
     445           0 :     memset(&gcd,0,sizeof(gcd));
     446           0 :     memset(&boxes,0,sizeof(boxes));
     447           0 :     memset(&label,0,sizeof(label));
     448           0 :     k=j=0;
     449           0 :     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[1].gd.pos.y+14;
     450           0 :     gcd[k].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     451           0 :     gcd[k].gd.cid = CID_Lookups;
     452           0 :     gcd[k].gd.u.matrix = &mi;
     453           0 :     gcd[k].gd.popup_msg = (unichar_t *) _( "A list of lookup names");
     454           0 :     gcd[k].creator = GMatrixEditCreate;
     455           0 :     varray[j++] = &gcd[k++]; varray[j++] = NULL;
     456             : 
     457           0 :     gcd[k].gd.pos.x = 30-3; 
     458           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     459           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
     460           0 :     label[k].text = (unichar_t *) _("_OK");
     461           0 :     label[k].text_is_1byte = true;
     462           0 :     label[k].text_in_resource = true;
     463           0 :     gcd[k].gd.label = &label[k];
     464           0 :     gcd[k].gd.handle_controlevent = JSTF_Lookup_OK;
     465           0 :     gcd[k].gd.cid = CID_OK;
     466           0 :     gcd[k++].creator = GButtonCreate;
     467             : 
     468           0 :     gcd[k].gd.pos.x = -30;
     469           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     470           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     471           0 :     label[k].text = (unichar_t *) _("_Cancel");
     472           0 :     label[k].text_is_1byte = true;
     473           0 :     label[k].text_in_resource = true;
     474           0 :     gcd[k].gd.label = &label[k];
     475           0 :     gcd[k].gd.handle_controlevent = JSTF_Glyph_Cancel;
     476           0 :     gcd[k].gd.cid = CID_Cancel;
     477           0 :     gcd[k++].creator = GButtonCreate;
     478             : 
     479           0 :     harray3[0] = harray3[2] = harray3[3] = harray3[4] = harray3[6] = GCD_Glue;
     480           0 :     harray3[7] = NULL;
     481           0 :     harray3[1] = &gcd[k-2]; harray3[5] = &gcd[k-1];
     482             : 
     483           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     484           0 :     boxes[0].gd.u.boxelements = harray3;
     485           0 :     boxes[0].creator = GHBoxCreate;
     486           0 :     varray[j++] = &boxes[0]; varray[j++] = NULL; varray[j] = NULL;
     487             :     
     488           0 :     boxes[1].gd.pos.x = boxes[1].gd.pos.y = 2;
     489           0 :     boxes[1].gd.flags = gg_enabled|gg_visible;
     490           0 :     boxes[1].gd.u.boxelements = varray;
     491           0 :     boxes[1].creator = GHVGroupCreate;
     492             : 
     493           0 :     GGadgetsCreate(gw,boxes+1);
     494             : 
     495           0 :     free( mi.matrix_data );
     496             : 
     497           0 :     GMatrixEditSetNewText(gcd[0].ret,S_("LookupName|New"));
     498           0 :     GHVBoxSetExpandableCol(boxes[0].ret,gb_expandgluesame);
     499             : 
     500           0 :     GHVBoxFitWindow(boxes[1].ret);
     501             : 
     502           0 :     GDrawSetVisible(gw,true);
     503           0 :     while ( !gld.done )
     504           0 :         GDrawProcessOneEvent(NULL);
     505           0 :     GDrawDestroyWindow(gw);
     506           0 :     GTextInfoListFree(lookup_ci[0].enum_vals);
     507           0 :     lookup_ci[0].enum_vals = NULL;
     508           0 : return( gld.ret );
     509             : }
     510             : 
     511             : /* ************************************************************************** */
     512             : /* dlg which presents a list of languages and associated lookups              */
     513             : /* ************************************************************************** */
     514           0 : static char *Tag2Str(uint32 tag) {
     515             :     static char foo[8];
     516           0 :     foo[0] = tag>>24;
     517           0 :     foo[1] = tag>>16;
     518           0 :     foo[2] = tag>>8;
     519           0 :     foo[3] = tag;
     520           0 :     foo[4] = 0;
     521           0 : return( foo );
     522             : }
     523             : 
     524           0 : static uint32 Str2Tag(char *str) {
     525             :     unsigned char foo[4];
     526             : 
     527           0 :     memset(foo,' ',4);
     528           0 :     if ( str!=NULL && *str!='\0' ) {
     529           0 :         foo[0] = *str;
     530           0 :         if ( str[1]!='\0' ) {
     531           0 :             foo[1] = str[1];
     532           0 :             if ( str[2]!='\0' ) {
     533           0 :                 foo[2] = str[2];
     534           0 :                 if ( str[3]!='\0' )
     535           0 :                     foo[3] = str[3];
     536             :             }
     537             :         }
     538             :     }
     539           0 : return( (foo[0]<<24) | (foo[1]<<16) | (foo[2]<<8) | foo[3] );
     540             : }
     541             : 
     542           0 : static char *OTList2Str(OTLookup **otll) {
     543             :     char *ret, *pt;
     544             :     int len, i;
     545             : 
     546           0 :     if ( otll==NULL )
     547           0 : return( NULL );
     548           0 :     len = 0;
     549           0 :     for ( i=0; otll[i]!=NULL; ++i )
     550           0 :         len += strlen(otll[i]->lookup_name) +2;
     551           0 :     if ( len==0 )
     552           0 : return( copy( "" ));
     553             : 
     554           0 :     ret = pt = malloc(len+1);
     555           0 :     for ( i=0; otll[i]!=NULL; ++i ) {
     556           0 :         strcpy(pt,otll[i]->lookup_name);
     557           0 :         strcat(pt,", ");
     558           0 :         pt += strlen(pt);
     559             :     }
     560           0 :     pt[-2] = '\0';
     561           0 : return( ret );
     562             : }
     563             : 
     564           0 : static OTLookup **Str2OTLList(SplineFont *sf,char *str ) {
     565             :     int cnt;
     566             :     char *pt, *ept;
     567             :     OTLookup **ret;
     568             : 
     569           0 :     if ( str==NULL )
     570           0 : return( NULL );
     571           0 :     while ( *str==' ' )
     572           0 :         ++str;
     573           0 :     if ( *str=='\0' )
     574           0 : return( NULL );
     575             : 
     576           0 :     pt = str;
     577           0 :     cnt = 0;
     578           0 :     while ( (pt = strchr(pt+1,','))!=NULL )
     579           0 :         ++cnt;
     580             : 
     581           0 :     ret = malloc( (cnt+2)*sizeof(OTLookup *));
     582           0 :     pt = str;
     583           0 :     cnt = 0;
     584           0 :     while ( (ept = strchr(pt,','))!=NULL ) {
     585           0 :         *ept = '\0';
     586           0 :         ret[cnt] = SFFindLookup(sf,pt);
     587           0 :         if ( ret[cnt]==NULL ) {
     588           0 :             ff_post_error(_("Unknown lookup"), _("Unknown lookup name: %60.60s"),
     589             :                 pt );
     590           0 :             *ept = ',';
     591           0 :             free(ret);
     592           0 : return( (OTLookup **) -1 );
     593             :         }
     594           0 :         *ept = ',';
     595           0 :         ++cnt;
     596           0 :         pt = ept;
     597           0 :         while ( *pt==',' || *pt==' ' ) ++pt;
     598           0 :         if ( *pt=='\0' )
     599           0 :     break;
     600             :     }
     601           0 :     if ( *pt!='\0' ) {
     602           0 :         ret[cnt] = SFFindLookup(sf,pt);
     603           0 :         if ( ret[cnt]==NULL ) {
     604           0 :             ff_post_error(_("Unknown lookup"), _("Unknown lookup name: %60.60s"),
     605             :                 pt );
     606           0 :             free(ret);
     607           0 : return( (OTLookup **) -1 );
     608             :         }
     609           0 :         ++cnt;
     610             :     }
     611           0 :     ret[cnt] = NULL;
     612           0 : return( ret );
     613             : }
     614             :     
     615           0 : static void JLanguageMatrixInit(struct matrixinit *mi, struct jstf_lang *jl) {
     616             :     struct matrix_data *md;
     617             :     int i, cnt;
     618             :     struct jstf_lang *jlang;
     619             : 
     620           0 :     memset(mi,0,sizeof(*mi));
     621           0 :     mi->col_cnt = 7;
     622           0 :     mi->col_init = jstf_lang_ci;
     623             : 
     624           0 :     md = NULL;
     625           0 :     cnt = 0;
     626           0 :     for ( jlang = jl; jlang!=NULL; jlang=jlang->next )
     627           0 :         cnt += jlang->cnt;
     628           0 :     md = calloc(mi->col_cnt*(cnt+10),sizeof(struct matrix_data));
     629           0 :     cnt = 0;
     630           0 :     for ( jlang = jl; jlang!=NULL; jlang=jlang->next ) {
     631           0 :         for ( i=0; i<jlang->cnt; ++i ) {
     632           0 :             md[7*cnt+0].u.md_str = copy(Tag2Str(jl->lang));
     633           0 :             md[7*cnt+1].u.md_str  = OTList2Str(jl->prios[i].enableExtend);
     634           0 :             md[7*cnt+2].u.md_str  = OTList2Str(jl->prios[i].disableExtend);
     635           0 :             md[7*cnt+3].u.md_str  = OTList2Str(jl->prios[i].maxExtend);
     636           0 :             md[7*cnt+4].u.md_str  = OTList2Str(jl->prios[i].enableShrink);
     637           0 :             md[7*cnt+5].u.md_str  = OTList2Str(jl->prios[i].disableShrink);
     638           0 :             md[7*cnt+6].u.md_str  = OTList2Str(jl->prios[i].maxShrink);
     639           0 :             ++cnt;
     640             :         }
     641             :     }
     642           0 :     mi->matrix_data = md;
     643           0 :     mi->initial_row_cnt = cnt;
     644           0 : }
     645             : 
     646           0 : static int JSTF_Language_OK(GGadget *g, GEvent *e) {
     647             : 
     648           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     649           0 :         Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     650             :         int rows, i, j, k, cnt;
     651           0 :         struct matrix_data *strings = GMatrixEditGet(GWidgetGetControl(jd->lgw,CID_Languages), &rows);
     652           0 :         int cols = GMatrixEditGetColCnt(GWidgetGetControl(jd->lgw,CID_Languages));
     653           0 :         struct jstf_lang *head=NULL, *last=NULL, *cur;
     654             : 
     655           0 :         for ( i=0; i<rows; ++i ) if ( !(strings[i*cols+0].u.md_str[0]&0x80) ) {
     656           0 :             for ( j=i, cnt=0; j<rows; ++j )
     657           0 :                 if ( strcmp(strings[j*cols+0].u.md_str, strings[i*cols+0].u.md_str)==0 )
     658           0 :                     ++cnt;
     659           0 :             cur = chunkalloc(sizeof(struct jstf_lang));
     660           0 :             if ( head==NULL )
     661           0 :                 head = cur;
     662             :             else
     663           0 :                 last->next = cur;
     664           0 :             last = cur;
     665           0 :             cur->lang = Str2Tag(strings[i*cols+0].u.md_str);
     666           0 :             cur->cnt  = cnt;
     667           0 :             cur->prios=calloc(cnt,sizeof(struct jstf_prio));
     668           0 :             for ( j=i, cnt=0; j<rows; ++j ) {
     669           0 :                 if ( strcmp(strings[j*cols+0].u.md_str, strings[i*cols+0].u.md_str)==0 ) {
     670           0 :                     cur->prios[cnt].enableExtend = Str2OTLList(jd->sf,strings[j*cols+1].u.md_str );
     671           0 :                     cur->prios[cnt].disableExtend = Str2OTLList(jd->sf,strings[j*cols+2].u.md_str );
     672           0 :                     cur->prios[cnt].maxExtend = Str2OTLList(jd->sf,strings[j*cols+3].u.md_str );
     673           0 :                     cur->prios[cnt].enableShrink = Str2OTLList(jd->sf,strings[j*cols+4].u.md_str );
     674           0 :                     cur->prios[cnt].disableShrink = Str2OTLList(jd->sf,strings[j*cols+5].u.md_str );
     675           0 :                     cur->prios[cnt].maxShrink = Str2OTLList(jd->sf,strings[j*cols+6].u.md_str );
     676           0 :                     if ( cur->prios[cnt].enableExtend == (OTLookup **) -1 ||
     677           0 :                             cur->prios[cnt].disableExtend == (OTLookup **) -1 ||
     678           0 :                             cur->prios[cnt].maxExtend == (OTLookup **) -1 ||
     679           0 :                             cur->prios[cnt].enableShrink == (OTLookup **) -1 ||
     680           0 :                             cur->prios[cnt].disableShrink == (OTLookup **) -1 ||
     681           0 :                             cur->prios[cnt].maxShrink == (OTLookup **) -1 ) {
     682           0 :                         JstfLangFree(head);
     683           0 :                         for ( k=0; k<rows; ++k )
     684           0 :                             strings[k*cols+0].u.md_str[0] &= ~0x80;
     685           0 : return( true );
     686             :                     }
     687           0 :                     ++cnt;
     688             :                 }
     689             :             }
     690           0 :             for ( j=rows-1; j>=i; --j )
     691           0 :                 if ( strcmp(strings[j*cols+0].u.md_str, strings[i*cols+0].u.md_str)==0 )
     692           0 :                     strings[j*cols+0].u.md_str[0] |= 0x80;
     693             :         }
     694           0 :         JstfLangFree( *jd->here );
     695           0 :         *jd->here = head;
     696           0 :         jd->ldone = true;
     697             :     }
     698           0 : return( true );
     699             : }
     700             : 
     701           0 : static int JSTF_Language_Cancel(GGadget *g, GEvent *e) {
     702             : 
     703           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     704           0 :         Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     705           0 :         jd->ldone = true;
     706             :     }
     707           0 : return( true );
     708             : }
     709             : 
     710           0 : static int langs_e_h(GWindow gw, GEvent *event) {
     711             : 
     712           0 :     if ( event->type==et_close ) {
     713           0 :         Jstf_Dlg *jd = GDrawGetUserData(gw);
     714           0 :         jd->ldone = true;
     715           0 :     } else if ( event->type == et_char ) {
     716           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     717           0 :             help("justify.html#language-dlg");
     718           0 : return( true );
     719             :         }
     720           0 : return( false );
     721             :     }
     722             : 
     723           0 : return( true );
     724             : }
     725             : 
     726           0 : static char *JSTF_Langs(GGadget *g, int r, int c) {
     727             :     int rows, i, k, j;
     728           0 :     struct matrix_data *strings = GMatrixEditGet(g, &rows);
     729           0 :     int cols = GMatrixEditGetColCnt(g);
     730           0 :     Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     731             :     GRect pos;
     732             :     GWindow gw;
     733             :     GWindowAttrs wattrs;
     734             :     GGadgetCreateData gcd[4], boxes[3];
     735             :     GGadgetCreateData *varray[6], *harray3[8];
     736             :     GTextInfo label[4];
     737             :     struct matrixinit mi;
     738             : 
     739           0 :     jd->ldone = false;
     740           0 :     jd->here = (struct jstf_lang **) &strings[cols*r+3].u.md_addr;
     741             : 
     742           0 :     memset(&wattrs,0,sizeof(wattrs));
     743           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     744           0 :     wattrs.event_masks = ~(1<<et_charup);
     745           0 :     wattrs.is_dlg = true;
     746           0 :     wattrs.restrict_input_to_me = 1;
     747           0 :     wattrs.undercursor = 1;
     748           0 :     wattrs.cursor = ct_pointer;
     749           0 :     wattrs.utf8_window_title = _("Justified Languages");
     750           0 :     pos.x = pos.y = 0;
     751           0 :     pos.width =GDrawPointsToPixels(NULL,GGadgetScale(268));
     752           0 :     pos.height = GDrawPointsToPixels(NULL,375);
     753           0 :     jd->lgw = gw = GDrawCreateTopWindow(NULL,&pos,langs_e_h,jd,&wattrs);
     754             : 
     755           0 :     memset(&gcd,0,sizeof(gcd));
     756           0 :     memset(&boxes,0,sizeof(boxes));
     757           0 :     memset(&label,0,sizeof(label));
     758           0 :     k=j=0;
     759           0 :     JLanguageMatrixInit(&mi,*jd->here);
     760           0 :     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[1].gd.pos.y+14;
     761           0 :     gcd[k].gd.pos.width = 900;
     762           0 :     gcd[k].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     763           0 :     gcd[k].gd.cid = CID_Languages;
     764           0 :     gcd[k].gd.u.matrix = &mi;
     765           0 :     gcd[k].gd.popup_msg = (unichar_t *) _(
     766             :         "A list of languages and the lookups turned on and off\n"
     767             :         "for each to accomplish justification.  A language may\n"
     768             :         "appear more than once, in which case second (or third,\n"
     769             :         "etc.) will be tried if the first fails.");
     770           0 :     gcd[k].creator = GMatrixEditCreate;
     771           0 :     varray[j++] = &gcd[k++]; varray[j++] = NULL;
     772             : 
     773           0 :     gcd[k].gd.pos.x = 30-3; 
     774           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     775           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
     776           0 :     label[k].text = (unichar_t *) _("_OK");
     777           0 :     label[k].text_is_1byte = true;
     778           0 :     label[k].text_in_resource = true;
     779           0 :     gcd[k].gd.label = &label[k];
     780           0 :     gcd[k].gd.handle_controlevent = JSTF_Language_OK;
     781           0 :     gcd[k].gd.cid = CID_OK;
     782           0 :     gcd[k++].creator = GButtonCreate;
     783             : 
     784           0 :     gcd[k].gd.pos.x = -30;
     785           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     786           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     787           0 :     label[k].text = (unichar_t *) _("_Cancel");
     788           0 :     label[k].text_is_1byte = true;
     789           0 :     label[k].text_in_resource = true;
     790           0 :     gcd[k].gd.label = &label[k];
     791           0 :     gcd[k].gd.handle_controlevent = JSTF_Language_Cancel;
     792           0 :     gcd[k].gd.cid = CID_Cancel;
     793           0 :     gcd[k++].creator = GButtonCreate;
     794             : 
     795           0 :     harray3[0] = harray3[2] = harray3[3] = harray3[4] = harray3[6] = GCD_Glue;
     796           0 :     harray3[7] = NULL;
     797           0 :     harray3[1] = &gcd[k-2]; harray3[5] = &gcd[k-1];
     798             : 
     799           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     800           0 :     boxes[0].gd.u.boxelements = harray3;
     801           0 :     boxes[0].creator = GHBoxCreate;
     802           0 :     varray[j++] = &boxes[0]; varray[j++] = NULL; varray[j] = NULL;
     803             :     
     804           0 :     boxes[1].gd.pos.x = boxes[1].gd.pos.y = 2;
     805           0 :     boxes[1].gd.flags = gg_enabled|gg_visible;
     806           0 :     boxes[1].gd.u.boxelements = varray;
     807           0 :     boxes[1].creator = GHVGroupCreate;
     808             : 
     809           0 :     GGadgetsCreate(gw,boxes+1);
     810             : 
     811           0 :     for ( i=0; i<mi.initial_row_cnt; ++i ) {
     812           0 :         free( mi.matrix_data[2*i+0].u.md_str );
     813             :     }
     814           0 :     free( mi.matrix_data );
     815             : 
     816           0 :     GMatrixEditSetNewText(gcd[0].ret,S_("Language|New"));
     817           0 :     GMatrixEditSetUpDownVisible(gcd[0].ret,true);
     818           0 :     GHVBoxSetExpandableCol(boxes[0].ret,gb_expandgluesame);
     819             : 
     820           0 :     GHVBoxFitWindow(boxes[1].ret);
     821             : 
     822           0 :     GDrawSetVisible(gw,true);
     823           0 :     while ( !jd->ldone )
     824           0 :         GDrawProcessOneEvent(NULL);
     825           0 :     GDrawDestroyWindow(gw);
     826           0 : return( NULL );
     827             : }
     828             : 
     829             : /* ************************************************************************** */
     830             : /* dlg which presents a list of scripts and associated information            */
     831             : /* ************************************************************************** */
     832             : 
     833           0 : static void JScriptMatrixInit(struct matrixinit *mi,Justify *js) {
     834             :     struct matrix_data *md;
     835             :     int k, cnt;
     836             :     Justify *jscript;
     837             : 
     838           0 :     memset(mi,0,sizeof(*mi));
     839           0 :     mi->col_cnt = 4;
     840           0 :     mi->col_init = justify_ci;
     841             : 
     842           0 :     md = NULL;
     843           0 :     for ( k=0; k<2; ++k ) {
     844           0 :         cnt = 0;
     845           0 :         for ( jscript=js; jscript!=NULL; jscript = jscript->next ) {
     846           0 :             if ( k ) {
     847           0 :                 md[4*cnt+0].u.md_str = copy(Tag2Str(jscript->script));
     848           0 :                 md[4*cnt+1].u.md_str  = copy(jscript->extenders);
     849             :                 /* Nothing in 4*cnt+2 */
     850           0 :                 md[4*cnt+3].u.md_addr = JstfLangsCopy(jscript->langs);
     851             :             }
     852           0 :             ++cnt;
     853             :         }
     854           0 :         if ( md==NULL )
     855           0 :             md = calloc(4*(cnt+10),sizeof(struct matrix_data));
     856             :     }
     857           0 :     mi->matrix_data = md;
     858           0 :     mi->initial_row_cnt = cnt;
     859           0 : }
     860             : 
     861           0 : static int JSTF_Script_OK(GGadget *g, GEvent *e) {
     862             : 
     863           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     864           0 :         Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     865           0 :         SplineFont *sf = jd->sf;
     866           0 :         Justify *head=NULL, *last=NULL, *cur;
     867             :         int rows, i;
     868           0 :         int cols = GMatrixEditGetColCnt(GWidgetGetControl(jd->gw,CID_Scripts));
     869           0 :         struct matrix_data *strings = GMatrixEditGet(GWidgetGetControl(jd->gw,CID_Scripts), &rows);
     870             : 
     871           0 :         for ( i=0; i<rows; ++i ) {
     872           0 :             cur = chunkalloc(sizeof(Justify));
     873           0 :             cur->script = Str2Tag(strings[cols*i+0].u.md_str);
     874           0 :             cur->extenders = copy(strings[cols*i+1].u.md_str);
     875           0 :             cur->langs = strings[cols*i+3].u.md_addr;
     876           0 :             if ( head==NULL )
     877           0 :                 head = cur;
     878             :             else
     879           0 :                 last->next = cur;
     880           0 :             last = cur;
     881             :         }
     882           0 :         JustifyFree(sf->justify);
     883           0 :         sf->justify = head;
     884           0 :         jd->done = true;
     885             :     }
     886           0 : return( true );
     887             : }
     888             : 
     889           0 : static void Jstf_Cancel(Jstf_Dlg *jd) {
     890             :     int rows, i;
     891           0 :     int cols = GMatrixEditGetColCnt(GWidgetGetControl(jd->gw,CID_Scripts));
     892           0 :     struct matrix_data *strings = GMatrixEditGet(GWidgetGetControl(jd->gw,CID_Scripts), &rows);
     893             : 
     894           0 :     for ( i=0; i<rows; ++i ) {
     895           0 :         JstfLangFree(strings[cols*i+3].u.md_addr);
     896             :     }
     897           0 :     jd->done = true;
     898           0 : }
     899             : 
     900           0 : static int Justify_Cancel(GGadget *g, GEvent *e) {
     901             : 
     902           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     903           0 :         Jstf_Dlg *jd = GDrawGetUserData(GGadgetGetWindow(g));
     904           0 :         Jstf_Cancel(jd);
     905             :     }
     906           0 : return( true );
     907             : }
     908             : 
     909           0 : static int jscripts_e_h(GWindow gw, GEvent *event) {
     910             : 
     911           0 :     if ( event->type==et_close ) {
     912           0 :         Jstf_Dlg *jd = GDrawGetUserData(gw);
     913           0 :         Jstf_Cancel(jd);
     914           0 :     } else if ( event->type == et_char ) {
     915           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     916           0 :             help("justify.html");
     917           0 : return( true );
     918             :         }
     919           0 : return( false );
     920             :     }
     921             : 
     922           0 : return( true );
     923             : }
     924             : 
     925           0 : void JustifyDlg(SplineFont *sf) {
     926             :     Jstf_Dlg jd;
     927             :     GRect pos;
     928             :     GWindow gw;
     929             :     GWindowAttrs wattrs;
     930             :     GGadgetCreateData gcd[4], boxes[3];
     931             :     GGadgetCreateData *varray[6], *harray3[8];
     932             :     GTextInfo label[4];
     933             :     struct matrixinit mi;
     934             :     int i,j,k;
     935             : 
     936           0 :     LookupUIInit();
     937           0 :     JustUIInit();
     938             : 
     939           0 :     memset(&jd,0,sizeof(jd));
     940           0 :     jd.sf = sf;
     941             : 
     942           0 :     memset(&wattrs,0,sizeof(wattrs));
     943           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     944           0 :     wattrs.event_masks = ~(1<<et_charup);
     945           0 :     wattrs.is_dlg = true;
     946           0 :     wattrs.restrict_input_to_me = 1;
     947           0 :     wattrs.undercursor = 1;
     948           0 :     wattrs.cursor = ct_pointer;
     949           0 :     wattrs.utf8_window_title = _("Justified Scripts");
     950           0 :     pos.x = pos.y = 0;
     951           0 :     pos.width =GDrawPointsToPixels(NULL,GGadgetScale(268));
     952           0 :     pos.height = GDrawPointsToPixels(NULL,375);
     953           0 :     jd.gw = gw = GDrawCreateTopWindow(NULL,&pos,jscripts_e_h,&jd,&wattrs);
     954             : 
     955           0 :     JScriptMatrixInit(&mi,sf->justify);
     956             : 
     957           0 :     memset(&gcd,0,sizeof(gcd));
     958           0 :     memset(&boxes,0,sizeof(boxes));
     959           0 :     memset(&label,0,sizeof(label));
     960           0 :     k=j=0;
     961           0 :     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[1].gd.pos.y+14;
     962           0 :     gcd[k].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
     963           0 :     gcd[k].gd.cid = CID_Scripts;
     964           0 :     gcd[k].gd.u.matrix = &mi;
     965           0 :     gcd[k].gd.popup_msg = (unichar_t *) _( "A list of scripts with special justification needs");
     966           0 :     gcd[k].creator = GMatrixEditCreate;
     967           0 :     varray[j++] = &gcd[k++]; varray[j++] = NULL;
     968             : 
     969           0 :     gcd[k].gd.pos.x = 30-3; 
     970           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     971           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
     972           0 :     label[k].text = (unichar_t *) _("_OK");
     973           0 :     label[k].text_is_1byte = true;
     974           0 :     label[k].text_in_resource = true;
     975           0 :     gcd[k].gd.label = &label[k];
     976           0 :     gcd[k].gd.handle_controlevent = JSTF_Script_OK;
     977           0 :     gcd[k].gd.cid = CID_OK;
     978           0 :     gcd[k++].creator = GButtonCreate;
     979             : 
     980           0 :     gcd[k].gd.pos.x = -30;
     981           0 :     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
     982           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     983           0 :     label[k].text = (unichar_t *) _("_Cancel");
     984           0 :     label[k].text_is_1byte = true;
     985           0 :     label[k].text_in_resource = true;
     986           0 :     gcd[k].gd.label = &label[k];
     987           0 :     gcd[k].gd.handle_controlevent = Justify_Cancel;
     988           0 :     gcd[k].gd.cid = CID_Cancel;
     989           0 :     gcd[k++].creator = GButtonCreate;
     990             : 
     991           0 :     harray3[0] = harray3[2] = harray3[3] = harray3[4] = harray3[6] = GCD_Glue;
     992           0 :     harray3[7] = NULL;
     993           0 :     harray3[1] = &gcd[k-2]; harray3[5] = &gcd[k-1];
     994             : 
     995           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     996           0 :     boxes[0].gd.u.boxelements = harray3;
     997           0 :     boxes[0].creator = GHBoxCreate;
     998           0 :     varray[j++] = &boxes[0]; varray[j++] = NULL; varray[j] = NULL;
     999             :     
    1000           0 :     boxes[1].gd.pos.x = boxes[1].gd.pos.y = 2;
    1001           0 :     boxes[1].gd.flags = gg_enabled|gg_visible;
    1002           0 :     boxes[1].gd.u.boxelements = varray;
    1003           0 :     boxes[1].creator = GHVGroupCreate;
    1004             : 
    1005           0 :     GGadgetsCreate(gw,boxes+1);
    1006             : 
    1007           0 :     for ( i=0; i<mi.initial_row_cnt; ++i ) {
    1008           0 :         free( mi.matrix_data[2*i+0].u.md_str );
    1009             :     }
    1010           0 :     free( mi.matrix_data );
    1011             : 
    1012           0 :     GMatrixEditSetNewText(gcd[0].ret,S_("Script|New"));
    1013           0 :     GMatrixEditSetUpDownVisible(gcd[0].ret,true);
    1014           0 :     GMatrixEditShowColumn(gcd[0].ret,3,false);
    1015           0 :     GHVBoxSetExpandableCol(boxes[0].ret,gb_expandgluesame);
    1016             : 
    1017           0 :     GHVBoxFitWindow(boxes[1].ret);
    1018             : 
    1019           0 :     GDrawSetVisible(gw,true);
    1020           0 :     while ( !jd.done )
    1021           0 :         GDrawProcessOneEvent(NULL);
    1022           0 :     GDrawDestroyWindow(gw);
    1023           0 : }

Generated by: LCOV version 1.10