LCOV - code coverage report
Current view: top level - fontforgeexe - displayfonts.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 1657 0.0 %
Date: 2017-08-04 Functions: 0 44 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 "ffglib.h"
      28             : 
      29             : #include "autotrace.h"
      30             : #include "cvundoes.h"
      31             : #include "fontforgeui.h"
      32             : #include "lookups.h"
      33             : #include "print.h"
      34             : #include "sftextfieldP.h"
      35             : #include "splinesaveafm.h"
      36             : #include "splineutil2.h"
      37             : #include "tottfgpos.h"
      38             : #include <stdlib.h>
      39             : #include <math.h>
      40             : #include <time.h>
      41             : #include <unistd.h>
      42             : #include <ustring.h>
      43             : #include "utype.h"
      44             : #include <sys/types.h>
      45             : #if !defined(__MINGW32__)
      46             : #include <sys/wait.h>
      47             : #endif
      48             : #include <gkeysym.h>
      49             : #include "print.h"
      50             : 
      51             : typedef struct printffdlg {
      52             :     struct printinfo pi;
      53             :     GWindow gw;
      54             :     GWindow setup;
      55             :     GTimer *sizechanged;
      56             :     GTimer *dpichanged;
      57             :     GTimer *widthchanged;
      58             :     GTimer *resized;
      59             :     GTextInfo *scriptlangs;
      60             :     FontView *fv;
      61             :     CharView *cv;
      62             :     SplineSet *fit_to_path;
      63             :     uint8 script_unknown;
      64             :     uint8 insert_text;
      65             :     uint8 ready;
      66             :     int *done;
      67             : } PD;
      68             : 
      69             : static PD *printwindow;
      70             : 
      71             : static int lastdpi=0;
      72             : static unichar_t *old_bind_text = NULL;
      73             : 
      74             : /* ************************************************************************** */
      75             : /* *********************** Code for Page Setup dialog *********************** */
      76             : /* ************************************************************************** */
      77             : 
      78             : #define CID_lp          1001
      79             : #define CID_lpr         1002
      80             : #define CID_ghostview   1003
      81             : #define CID_File        1004
      82             : #define CID_Other       1005
      83             : #define CID_OtherCmd    1006
      84             : #define CID_Pagesize    1007
      85             : #define CID_CopiesLab   1008
      86             : #define CID_Copies      1009
      87             : #define CID_PrinterLab  1010
      88             : #define CID_Printer     1011
      89             : #define CID_PDFFile     1012
      90             : 
      91           0 : static void PG_SetEnabled(PD *pi) {
      92             :     int enable;
      93             : 
      94           0 :     enable = GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_lp)) ||
      95           0 :             GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_lpr));
      96             : 
      97           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->setup,CID_CopiesLab),enable);
      98           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->setup,CID_Copies),enable);
      99           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->setup,CID_PrinterLab),enable);
     100           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->setup,CID_Printer),enable);
     101             : 
     102           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->setup,CID_OtherCmd),
     103           0 :             GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_Other)));
     104           0 : }
     105             : 
     106           0 : static int PG_OK(GGadget *g, GEvent *e) {
     107           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     108           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     109             :         const unichar_t *ret;
     110           0 :         int err=false;
     111             :         int copies, pgwidth, pgheight;
     112             : 
     113           0 :         copies = GetInt8(pi->setup,CID_Copies,_("_Copies:"),&err);
     114           0 :         if ( err )
     115           0 : return(true);
     116             : 
     117           0 :         if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_Other)) &&
     118           0 :                 *_GGadgetGetTitle(GWidgetGetControl(pi->setup,CID_OtherCmd))=='\0' ) {
     119           0 :             ff_post_error(_("No Command Specified"),_("No Command Specified"));
     120           0 : return(true);
     121             :         }
     122             : 
     123           0 :         ret = _GGadgetGetTitle(GWidgetGetControl(pi->setup,CID_Pagesize));
     124           0 :         if ( uc_strstr(ret,"Letter")!=NULL ) {
     125           0 :             pgwidth = 612; pgheight = 792;
     126           0 :         } else if ( uc_strstr(ret,"Legal")!=NULL ) {
     127           0 :             pgwidth = 612; pgheight = 1008;
     128           0 :         } else if ( uc_strstr(ret,"A4")!=NULL ) {
     129           0 :             pgwidth = 595; pgheight = 842;
     130           0 :         } else if ( uc_strstr(ret,"A3")!=NULL ) {
     131           0 :             pgwidth = 842; pgheight = 1191;
     132           0 :         } else if ( uc_strstr(ret,"B4")!=NULL ) {
     133           0 :             pgwidth = 708; pgheight = 1000;
     134           0 :         } else if ( uc_strstr(ret,"B5")!=NULL ) {
     135           0 :             pgwidth = 516; pgheight = 728;
     136             :         } else {
     137           0 :             char *cret = cu_copy(ret), *pt;
     138             :             float pw,ph, scale;
     139           0 :             if ( sscanf(cret,"%gx%g",&pw,&ph)!=2 ) {
     140           0 :                 IError("Bad Pagesize must be a known name or <num>x<num><units>\nWhere <units> is one of pt (points), mm, cm, in" );
     141           0 : return( true );
     142             :             }
     143           0 :             pt = cret+strlen(cret)-1;
     144           0 :             while ( isspace(*pt) ) --pt;
     145           0 :             if ( strncmp(pt-2,"in",2)==0)
     146           0 :                 scale = 72;
     147           0 :             else if ( strncmp(pt-2,"cm",2)==0 )
     148           0 :                 scale = 72/2.54;
     149           0 :             else if ( strncmp(pt-2,"mm",2)==0 )
     150           0 :                 scale = 72/25.4;
     151           0 :             else if ( strncmp(pt-2,"pt",2)==0 )
     152           0 :                 scale = 1;
     153             :             else {
     154           0 :                 IError("Bad Pagesize units are unknown\nMust be one of pt (points), mm, cm, in" );
     155           0 : return( true );
     156             :             }
     157           0 :             pgwidth = pw*scale; pgheight = ph*scale;
     158           0 :             free(cret);
     159             :         }
     160             : 
     161           0 :         ret = _GGadgetGetTitle(GWidgetGetControl(pi->setup,CID_Printer));
     162           0 :         if ( uc_strcmp(ret,"<default>")==0 || *ret=='\0' )
     163           0 :             ret = NULL;
     164           0 :         pi->pi.printer = cu_copy(ret);
     165           0 :         pi->pi.pagewidth = pgwidth; pi->pi.pageheight = pgheight;
     166           0 :         pi->pi.copies = copies;
     167             : 
     168           0 :         if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_lp)))
     169           0 :             pi->pi.printtype = pt_lp;
     170           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_lpr)))
     171           0 :             pi->pi.printtype = pt_lpr;
     172           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_ghostview)))
     173           0 :             pi->pi.printtype = pt_ghostview;
     174           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_PDFFile)))
     175           0 :             pi->pi.printtype = pt_pdf;
     176           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(pi->setup,CID_Other))) {
     177           0 :             pi->pi.printtype = pt_other;
     178           0 :             printcommand = cu_copy(_GGadgetGetTitle(GWidgetGetControl(pi->setup,CID_OtherCmd)));
     179             :         } else
     180           0 :             pi->pi.printtype = pt_file;
     181             : 
     182           0 :         printtype = pi->pi.printtype;
     183           0 :         free(printlazyprinter); printlazyprinter = copy(pi->pi.printer);
     184           0 :         pagewidth = pgwidth; pageheight = pgheight;
     185             : 
     186           0 :         pi->pi.done = true;
     187           0 :         SavePrefs(true);
     188             :     }
     189           0 : return( true );
     190             : }
     191             : 
     192           0 : static int PG_Cancel(GGadget *g, GEvent *e) {
     193           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     194           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     195           0 :         pi->pi.done = true;
     196             :     }
     197           0 : return( true );
     198             : }
     199             : 
     200           0 : static int PG_RadioSet(GGadget *g, GEvent *e) {
     201           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     202           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     203           0 :         PG_SetEnabled(pi);
     204             :     }
     205           0 : return( true );
     206             : }
     207             : 
     208           0 : static int pg_e_h(GWindow gw, GEvent *event) {
     209           0 :     if ( event->type==et_close ) {
     210           0 :         PD *pi = GDrawGetUserData(gw);
     211           0 :         pi->pi.done = true;
     212           0 :     } else if ( event->type==et_char ) {
     213           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     214           0 :             help("print.html");
     215           0 : return( true );
     216             :         }
     217           0 : return( false );
     218             :     }
     219           0 : return( true );
     220             : }
     221             : 
     222           0 : static GTextInfo *PrinterList() {
     223             :     char line[400];
     224             :     FILE *printcap;
     225           0 :     GTextInfo *tis=NULL;
     226             :     int cnt;
     227             :     char *bpt, *cpt;
     228             : 
     229           0 :     printcap = fopen("/etc/printcap","r");
     230           0 :     if ( printcap==NULL ) {
     231           0 :         tis = calloc(2,sizeof(GTextInfo));
     232           0 :         tis[0].text = uc_copy("<default>");
     233           0 : return( tis );
     234             :     }
     235             : 
     236             :     while ( 1 ) {
     237           0 :         cnt=1;          /* leave room for default printer */
     238           0 :         while ( fgets(line,sizeof(line),printcap)!=NULL ) {
     239           0 :             if ( !isspace(*line) && *line!='#' ) {
     240           0 :                 if ( tis!=NULL ) {
     241           0 :                     bpt = strchr(line,'|');
     242           0 :                     cpt = strchr(line,':');
     243           0 :                     if ( cpt==NULL && bpt==NULL )
     244           0 :                         cpt = line+strlen(line)-1;
     245           0 :                     else if ( cpt!=NULL && bpt!=NULL && bpt<cpt )
     246           0 :                         cpt = bpt;
     247           0 :                     else if ( cpt==NULL )
     248           0 :                         cpt = bpt;
     249           0 :                     tis[cnt].text = uc_copyn(line,cpt-line);
     250             :                 }
     251           0 :                 ++cnt;
     252             :             }
     253             :         }
     254           0 :         if ( tis!=NULL ) {
     255           0 :             fclose(printcap);
     256           0 : return( tis );
     257             :         }
     258           0 :         tis = calloc((cnt+1),sizeof(GTextInfo));
     259           0 :         tis[0].text = uc_copy("<default>");
     260           0 :         rewind(printcap);
     261           0 :     }
     262             : }
     263             : 
     264           0 : static int progexists(char *prog) {
     265             :     char buffer[1025];
     266             : 
     267           0 : return( ProgramExists(prog,buffer)!=NULL );
     268             : }
     269             : 
     270           0 : static int PageSetup(PD *pi) {
     271             :     GRect pos;
     272             :     GWindowAttrs wattrs;
     273             :     GGadgetCreateData gcd[17], boxes[5], *radarray[4][5], *txtarray[3][5], *barray[9], *hvarray[5][2];
     274             :     GTextInfo label[17];
     275             :     char buf[10], pb[30];
     276             :     int pt;
     277             :     /* Don't translate these. we compare against the text */
     278             :     static GTextInfo pagesizes[] = {
     279             :         { (unichar_t *) "US Letter", NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     280             :         { (unichar_t *) "US Legal", NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     281             :         { (unichar_t *) "A3", NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     282             :         { (unichar_t *) "A4", NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     283             :         { (unichar_t *) "B4", NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
     284             :         GTEXTINFO_EMPTY
     285             :     };
     286             : 
     287           0 :     memset(&wattrs,0,sizeof(wattrs));
     288           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
     289           0 :     wattrs.event_masks = ~(1<<et_charup);
     290           0 :     wattrs.restrict_input_to_me = 1;
     291           0 :     wattrs.is_dlg = 1;
     292           0 :     wattrs.undercursor = 1;
     293           0 :     wattrs.cursor = ct_pointer;
     294           0 :     wattrs.utf8_window_title = _("Page Setup");
     295           0 :     pos.x = pos.y = 0;
     296           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,250));
     297           0 :     pos.height = GDrawPointsToPixels(NULL,174);
     298           0 :     pi->setup = GDrawCreateTopWindow(NULL,&pos,pg_e_h,pi,&wattrs);
     299             : 
     300           0 :     memset(&label,0,sizeof(label));
     301           0 :     memset(&gcd,0,sizeof(gcd));
     302             : 
     303             : /* program names also don't get translated */
     304           0 :     label[0].text = (unichar_t *) "lp";
     305           0 :     label[0].text_is_1byte = true;
     306           0 :     gcd[0].gd.label = &label[0];
     307           0 :     gcd[0].gd.mnemonic = 'l';
     308           0 :     gcd[0].gd.pos.x = 40; gcd[0].gd.pos.y = 6; 
     309           0 :     gcd[0].gd.flags = progexists("lp")? (gg_visible | gg_enabled):gg_visible;
     310           0 :     gcd[0].gd.cid = CID_lp;
     311           0 :     gcd[0].gd.handle_controlevent = PG_RadioSet;
     312           0 :     gcd[0].creator = GRadioCreate;
     313           0 :     radarray[0][0] = GCD_HPad10; radarray[0][1] = &gcd[0];
     314             : 
     315           0 :     label[1].text = (unichar_t *) "lpr";
     316           0 :     label[1].text_is_1byte = true;
     317           0 :     gcd[1].gd.label = &label[1];
     318           0 :     gcd[1].gd.mnemonic = 'r';
     319           0 :     gcd[1].gd.pos.x = gcd[0].gd.pos.x; gcd[1].gd.pos.y = 18+gcd[0].gd.pos.y; 
     320           0 :     gcd[1].gd.flags = progexists("lpr")? (gg_visible | gg_enabled):gg_visible;
     321           0 :     gcd[1].gd.cid = CID_lpr;
     322           0 :     gcd[1].gd.handle_controlevent = PG_RadioSet;
     323           0 :     gcd[1].creator = GRadioCreate;
     324           0 :     radarray[1][0] = GCD_HPad10; radarray[1][1] = &gcd[1];
     325             : 
     326           0 :     use_gv = false;
     327           0 :     label[2].text = (unichar_t *) "ghostview";
     328           0 :     label[2].text_is_1byte = true;
     329           0 :     gcd[2].gd.label = &label[2];
     330           0 :     gcd[2].gd.mnemonic = 'g';
     331           0 :     gcd[2].gd.pos.x = gcd[0].gd.pos.x+50; gcd[2].gd.pos.y = gcd[0].gd.pos.y;
     332           0 :     gcd[2].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
     333           0 :     if ( !progexists("ghostview") ) {
     334           0 :         if ( progexists("gv") ) {
     335           0 :             label[2].text = (unichar_t *) "gv";
     336           0 :             use_gv = true;
     337             :         } else
     338           0 :             gcd[2].gd.flags = gg_visible;
     339             :     }
     340           0 :     gcd[2].gd.cid = CID_ghostview;
     341           0 :     gcd[2].gd.handle_controlevent = PG_RadioSet;
     342           0 :     gcd[2].creator = GRadioCreate;
     343           0 :     radarray[0][2] = &gcd[2]; radarray[0][3] = GCD_ColSpan; radarray[0][4] =NULL;
     344             : 
     345           0 :     label[3].text = (unichar_t *) _("To _File");
     346           0 :     label[3].text_is_1byte = true;
     347           0 :     label[3].text_in_resource = true;
     348           0 :     gcd[3].gd.label = &label[3];
     349           0 :     gcd[3].gd.mnemonic = 'F';
     350           0 :     gcd[3].gd.pos.x = gcd[2].gd.pos.x; gcd[3].gd.pos.y = gcd[1].gd.pos.y; 
     351           0 :     gcd[3].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
     352           0 :     gcd[3].gd.cid = CID_File;
     353           0 :     gcd[3].gd.handle_controlevent = PG_RadioSet;
     354           0 :     gcd[3].creator = GRadioCreate;
     355           0 :     radarray[1][2] = &gcd[3];
     356             : 
     357           0 :     label[4].text = (unichar_t *) _("To P_DF File");
     358           0 :     label[4].text_is_1byte = true;
     359           0 :     label[4].text_in_resource = true;
     360           0 :     gcd[4].gd.label = &label[4];
     361           0 :     gcd[4].gd.mnemonic = 'F';
     362           0 :     gcd[4].gd.pos.x = gcd[2].gd.pos.x+70; gcd[4].gd.pos.y = gcd[1].gd.pos.y; 
     363           0 :     gcd[4].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
     364           0 :     gcd[4].gd.cid = CID_PDFFile;
     365           0 :     gcd[4].gd.handle_controlevent = PG_RadioSet;
     366           0 :     gcd[4].creator = GRadioCreate;
     367           0 :     radarray[1][3] = &gcd[4]; radarray[1][4] =NULL;
     368             : 
     369           0 :     label[5].text = (unichar_t *) _("_Other");
     370           0 :     label[5].text_is_1byte = true;
     371           0 :     label[5].text_in_resource = true;
     372           0 :     gcd[5].gd.label = &label[5];
     373           0 :     gcd[5].gd.mnemonic = 'O';
     374           0 :     gcd[5].gd.pos.x = gcd[1].gd.pos.x; gcd[5].gd.pos.y = 22+gcd[1].gd.pos.y; 
     375           0 :     gcd[5].gd.flags = gg_visible | gg_enabled | gg_utf8_popup | gg_rad_continueold;
     376           0 :     gcd[5].gd.cid = CID_Other;
     377           0 :     gcd[5].gd.handle_controlevent = PG_RadioSet;
     378           0 :     gcd[5].gd.popup_msg = (unichar_t *) _("Any other command with all its arguments.\nThe command must expect to deal with a postscript\nfile which it will find by reading its standard input.");
     379           0 :     gcd[5].creator = GRadioCreate;
     380           0 :     radarray[2][0] = GCD_HPad10; radarray[2][1] = &gcd[5];
     381             : 
     382           0 :     if ( (pt=pi->pi.printtype)==pt_unknown ) pt = pt_lp;
     383           0 :     if ( pt==pt_pdf ) pt = 4;           /* These two are out of order */
     384           0 :     else if ( pt==pt_other ) pt = 5;
     385           0 :     if ( !(gcd[pt].gd.flags&gg_enabled) ) pt = pt_file;             /* always enabled */
     386           0 :     gcd[pt].gd.flags |= gg_cb_on;
     387             : 
     388           0 :     label[6].text = (unichar_t *) (printcommand?printcommand:"");
     389           0 :     label[6].text_is_1byte = true;
     390           0 :     gcd[6].gd.label = &label[6];
     391           0 :     gcd[6].gd.mnemonic = 'O';
     392           0 :     gcd[6].gd.pos.x = gcd[2].gd.pos.x; gcd[6].gd.pos.y = gcd[5].gd.pos.y-4;
     393           0 :     gcd[6].gd.pos.width = 120;
     394           0 :     gcd[6].gd.flags = gg_visible | gg_enabled;
     395           0 :     gcd[6].gd.cid = CID_OtherCmd;
     396           0 :     gcd[6].creator = GTextFieldCreate;
     397           0 :     radarray[2][2] = &gcd[6]; radarray[2][3] = GCD_ColSpan; radarray[2][4] =NULL;
     398           0 :     radarray[3][0] = NULL;
     399             : 
     400           0 :     label[7].text = (unichar_t *) _("Page_Size:");
     401           0 :     label[7].text_is_1byte = true;
     402           0 :     label[7].text_in_resource = true;
     403           0 :     gcd[7].gd.label = &label[7];
     404           0 :     gcd[7].gd.mnemonic = 'S';
     405           0 :     gcd[7].gd.pos.x = 5; gcd[7].gd.pos.y = 24+gcd[5].gd.pos.y+6; 
     406           0 :     gcd[7].gd.flags = gg_visible | gg_enabled;
     407           0 :     gcd[7].creator = GLabelCreate;
     408           0 :     txtarray[0][0] = &gcd[7];
     409             : 
     410           0 :     if ( pi->pi.pagewidth==595 && pi->pi.pageheight==792 )
     411           0 :         strcpy(pb,"US Letter");               /* Pick a name, this is the default case */
     412           0 :     else if ( pi->pi.pagewidth==612 && pi->pi.pageheight==792 )
     413           0 :         strcpy(pb,"US Letter");
     414           0 :     else if ( pi->pi.pagewidth==612 && pi->pi.pageheight==1008 )
     415           0 :         strcpy(pb,"US Legal");
     416           0 :     else if ( pi->pi.pagewidth==595 && pi->pi.pageheight==842 )
     417           0 :         strcpy(pb,"A4");
     418           0 :     else if ( pi->pi.pagewidth==842 && pi->pi.pageheight==1191 )
     419           0 :         strcpy(pb,"A3");
     420           0 :     else if ( pi->pi.pagewidth==708 && pi->pi.pageheight==1000 )
     421           0 :         strcpy(pb,"B4");
     422             :     else
     423           0 :         sprintf(pb,"%dx%d mm", (int) (pi->pi.pagewidth*25.4/72),(int) (pi->pi.pageheight*25.4/72));
     424           0 :     label[8].text = (unichar_t *) pb;
     425           0 :     label[8].text_is_1byte = true;
     426           0 :     gcd[8].gd.label = &label[8];
     427           0 :     gcd[8].gd.mnemonic = 'S';
     428           0 :     gcd[8].gd.pos.x = 60; gcd[8].gd.pos.y = gcd[7].gd.pos.y-6;
     429           0 :     gcd[8].gd.pos.width = 90;
     430           0 :     gcd[8].gd.flags = gg_visible | gg_enabled;
     431           0 :     gcd[8].gd.cid = CID_Pagesize;
     432           0 :     gcd[8].gd.u.list = pagesizes;
     433           0 :     gcd[8].creator = GListFieldCreate;
     434           0 :     txtarray[0][1] = &gcd[8];
     435             : 
     436             : 
     437           0 :     label[9].text = (unichar_t *) _("_Copies:");
     438           0 :     label[9].text_is_1byte = true;
     439           0 :     label[9].text_in_resource = true;
     440           0 :     gcd[9].gd.label = &label[9];
     441           0 :     gcd[9].gd.mnemonic = 'C';
     442           0 :     gcd[9].gd.pos.x = 160; gcd[9].gd.pos.y = gcd[7].gd.pos.y; 
     443           0 :     gcd[9].gd.flags = gg_visible | gg_enabled;
     444           0 :     gcd[9].gd.cid = CID_CopiesLab;
     445           0 :     gcd[9].creator = GLabelCreate;
     446           0 :     txtarray[0][2] = &gcd[9];
     447             : 
     448           0 :     sprintf(buf,"%d",pi->pi.copies);
     449           0 :     label[10].text = (unichar_t *) buf;
     450           0 :     label[10].text_is_1byte = true;
     451           0 :     gcd[10].gd.label = &label[10];
     452           0 :     gcd[10].gd.mnemonic = 'C';
     453           0 :     gcd[10].gd.pos.x = 200; gcd[10].gd.pos.y = gcd[8].gd.pos.y;
     454           0 :     gcd[10].gd.pos.width = 40;
     455           0 :     gcd[10].gd.flags = gg_visible | gg_enabled;
     456           0 :     gcd[10].gd.cid = CID_Copies;
     457           0 :     gcd[10].creator = GTextFieldCreate;
     458           0 :     txtarray[0][3] = &gcd[10]; txtarray[0][4] = NULL;
     459             : 
     460             : 
     461           0 :     label[11].text = (unichar_t *) _("_Printer:");
     462           0 :     label[11].text_is_1byte = true;
     463           0 :     label[11].text_in_resource = true;
     464           0 :     gcd[11].gd.label = &label[11];
     465           0 :     gcd[11].gd.mnemonic = 'P';
     466           0 :     gcd[11].gd.pos.x = 5; gcd[11].gd.pos.y = 30+gcd[7].gd.pos.y+6; 
     467           0 :     gcd[11].gd.flags = gg_visible | gg_enabled;
     468           0 :     gcd[11].gd.cid = CID_PrinterLab;
     469           0 :     gcd[11].creator = GLabelCreate;
     470           0 :     txtarray[1][0] = &gcd[11];
     471             : 
     472           0 :     label[12].text = (unichar_t *) pi->pi.printer;
     473           0 :     label[12].text_is_1byte = true;
     474           0 :     if ( pi->pi.printer!=NULL )
     475           0 :         gcd[12].gd.label = &label[12];
     476           0 :     gcd[12].gd.mnemonic = 'P';
     477           0 :     gcd[12].gd.pos.x = 60; gcd[12].gd.pos.y = gcd[11].gd.pos.y-6;
     478           0 :     gcd[12].gd.pos.width = 90;
     479           0 :     gcd[12].gd.flags = gg_visible | gg_enabled;
     480           0 :     gcd[12].gd.cid = CID_Printer;
     481           0 :     gcd[12].gd.u.list = PrinterList();
     482           0 :     gcd[12].creator = GListFieldCreate;
     483           0 :     txtarray[1][1] = &gcd[12];
     484           0 :     txtarray[1][2] = GCD_ColSpan; txtarray[1][3] = GCD_Glue; txtarray[1][4] = NULL;
     485           0 :     txtarray[2][0] = NULL;
     486             : 
     487             : 
     488           0 :     gcd[13].gd.pos.x = 30-3; gcd[13].gd.pos.y = gcd[12].gd.pos.y+36;
     489           0 :     gcd[13].gd.pos.width = -1; gcd[13].gd.pos.height = 0;
     490           0 :     gcd[13].gd.flags = gg_visible | gg_enabled | gg_but_default;
     491           0 :     label[13].text = (unichar_t *) _("_OK");
     492           0 :     label[13].text_is_1byte = true;
     493           0 :     label[13].text_in_resource = true;
     494           0 :     gcd[13].gd.mnemonic = 'O';
     495           0 :     gcd[13].gd.label = &label[13];
     496           0 :     gcd[13].gd.handle_controlevent = PG_OK;
     497           0 :     gcd[13].creator = GButtonCreate;
     498             : 
     499           0 :     gcd[14].gd.pos.x = -30; gcd[14].gd.pos.y = gcd[13].gd.pos.y+3;
     500           0 :     gcd[14].gd.pos.width = -1; gcd[14].gd.pos.height = 0;
     501           0 :     gcd[14].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     502           0 :     label[14].text = (unichar_t *) _("_Cancel");
     503           0 :     label[14].text_is_1byte = true;
     504           0 :     label[14].text_in_resource = true;
     505           0 :     gcd[14].gd.label = &label[14];
     506           0 :     gcd[14].gd.mnemonic = 'C';
     507           0 :     gcd[14].gd.handle_controlevent = PG_Cancel;
     508           0 :     gcd[14].creator = GButtonCreate;
     509             : 
     510           0 :     barray[0] = barray[2] = barray[3] = barray[4] = barray[6] = GCD_Glue; barray[7] = NULL;
     511           0 :     barray[1] = &gcd[13]; barray[5] = &gcd[14];
     512             : 
     513           0 :     memset(boxes,0,sizeof(boxes));
     514             : 
     515           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
     516           0 :     boxes[2].gd.u.boxelements = radarray[0];
     517           0 :     boxes[2].creator = GHVBoxCreate;
     518             : 
     519           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
     520           0 :     boxes[3].gd.u.boxelements = txtarray[0];
     521           0 :     boxes[3].creator = GHVBoxCreate;
     522             : 
     523           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
     524           0 :     boxes[4].gd.u.boxelements = barray;
     525           0 :     boxes[4].creator = GHBoxCreate;
     526             : 
     527           0 :     hvarray[0][0] = &boxes[2]; hvarray[0][1] = NULL;
     528           0 :     hvarray[1][0] = &boxes[3]; hvarray[1][1] = NULL;
     529           0 :     hvarray[2][0] = GCD_Glue; hvarray[2][1] = NULL;
     530           0 :     hvarray[3][0] = &boxes[4]; hvarray[3][1] = NULL;
     531           0 :     hvarray[4][0] = NULL;
     532           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     533           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     534           0 :     boxes[0].gd.u.boxelements = hvarray[0];
     535           0 :     boxes[0].creator = GHVGroupCreate;
     536             : 
     537           0 :     GGadgetsCreate(pi->setup,boxes);
     538           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandgluesame);
     539           0 :     GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
     540           0 :     GTextInfoListFree(gcd[12].gd.u.list);
     541           0 :     PG_SetEnabled(pi);
     542           0 :     GHVBoxFitWindow(boxes[0].ret);
     543           0 :     GDrawSetVisible(pi->setup,true);
     544           0 :     while ( !pi->pi.done )
     545           0 :         GDrawProcessOneEvent(NULL);
     546           0 :     GDrawDestroyWindow(pi->setup);
     547           0 :     pi->pi.done = false;
     548           0 : return( pi->pi.printtype!=pt_unknown );
     549             : }
     550             : 
     551             : /* ************************************************************************** */
     552             : /* ************************* Code for Print dialog ************************** */
     553             : /* ************************************************************************** */
     554             : 
     555             : /* Slightly different from one in fontview */
     556           0 : static int FVSelCount(FontView *fv) {
     557           0 :     int i, cnt=0, gid;
     558           0 :     for ( i=0; i<fv->b.map->enccount; ++i )
     559           0 :         if ( fv->b.selected[i] && (gid=fv->b.map->map[i])!=-1 &&
     560           0 :                 SCWorthOutputting(fv->b.sf->glyphs[gid]))
     561           0 :             ++cnt;
     562           0 : return( cnt);
     563             : }
     564             : 
     565             :     /* CIDs for Print */
     566             : #define CID_TabSet      1000
     567             : #define CID_Display     1001
     568             : #define CID_Chars       1002
     569             : #define CID_MultiSize   1003
     570             : #define CID_PSLab       1005
     571             : #define CID_PointSize   1006
     572             : #define CID_OK          1009
     573             : #define CID_Cancel      1010
     574             : #define CID_Setup       1010
     575             : 
     576             :     /* CIDs for display */
     577             : #define CID_Font        2001
     578             : #define CID_AA          2002
     579             : #define CID_SizeLab     2003
     580             : #define CID_Size        2004
     581             : #define CID_pfb         2005
     582             : #define CID_ttf         2006
     583             : #define CID_otf         2007
     584             : #define CID_nohints     2008
     585             : #define CID_bitmap      2009
     586             : #define CID_pfaedit     2010
     587             : #define CID_SampleText  2011
     588             : #define CID_ScriptLang  2022
     589             : #define CID_Features    2023
     590             : #define CID_DPI         2024
     591             : #define CID_TopBox      2025
     592             : 
     593             :     /* CIDs for Insert Text */
     594             : #define CID_Bind        3001
     595             : #define CID_Scale       3002
     596             : #define CID_Start       3003
     597             : #define CID_Center      3004
     598             : #define CID_End         3005
     599             : #define CID_TextWidth   3006
     600             : #define CID_YOffset     3007
     601             : #define CID_GlyphAsUnit 3008
     602             : #define CID_ActualWidth 3009
     603             : 
     604           0 : static void PRT_SetEnabled(PD *pi) {
     605             :     int enable_ps;
     606             : 
     607           0 :     enable_ps = !GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Chars));
     608             : 
     609           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_PSLab),enable_ps);
     610           0 :     GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_PointSize),enable_ps);
     611           0 : }
     612             : 
     613           0 : static int PRT_OK(GGadget *g, GEvent *e) {
     614           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     615           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     616           0 :         int err = false;
     617           0 :         int di = pi->pi.fv!=NULL?0:pi->pi.mv!=NULL?2:1;
     618             :         char *ret;
     619             :         char *file;
     620             :         char buf[100];
     621             : 
     622           0 :         if ( pi->insert_text ) {
     623             :             SplineSet *ss, *end;
     624           0 :             int bound = GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Bind));
     625           0 :             int scale = GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Scale));
     626           0 :             int gunit = GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_GlyphAsUnit));
     627           0 :             int align = GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Start ))? 0 :
     628           0 :                         GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Center))? 1 : 2;
     629           0 :             int width = GetInt8(pi->gw,CID_TextWidth,_("Width"),&err);
     630           0 :             real offset = GetReal8(pi->gw,CID_YOffset,_("Offset"),&err);
     631           0 :             CharView *cv = pi->cv;
     632             :             LayoutInfo *sample;
     633           0 :             /* int dpi  =*/ GetInt8(pi->gw,CID_DPI,_("DPI"),&err);
     634           0 :             /* int size =*/ GetInt8(pi->gw,CID_Size,_("Size"),&err);
     635           0 :             if ( err )
     636           0 : return(true);
     637           0 :             free(old_bind_text);
     638           0 :             old_bind_text = GGadgetGetTitle(GWidgetGetControl(pi->gw,CID_SampleText));
     639           0 :             sample = LIConvertToPrint(
     640           0 :                         &((SFTextArea *) GWidgetGetControl(pi->gw,CID_SampleText))->li,
     641             :                         width, 50000, 72 );
     642           0 :             ss = LIConvertToSplines(sample, 72,cv->b.layerheads[cv->b.drawmode]->order2);
     643           0 :             LayoutInfo_Destroy(sample);
     644           0 :             free(sample);
     645           0 :             if ( bound && pi->fit_to_path )
     646           0 :                 SplineSetBindToPath(ss,scale,gunit,align,offset,pi->fit_to_path);
     647           0 :             if ( ss ) {
     648             :                 SplineSet *test;
     649           0 :                 CVPreserveState((CharViewBase *) cv);
     650           0 :                 end = NULL;
     651           0 :                 for ( test=ss; test!=NULL; test=test->next ) {
     652             :                     SplinePoint *sp;
     653           0 :                     end = test;
     654           0 :                     for ( sp=test->first; ; ) {
     655           0 :                         sp->selected = true;
     656           0 :                         if ( sp->next==NULL )
     657           0 :                     break;
     658           0 :                         sp = sp->next->to;
     659           0 :                         if ( sp==test->first )
     660           0 :                     break;
     661           0 :                     }
     662             :                 }
     663           0 :                 end->next = cv->b.layerheads[cv->b.drawmode]->splines;
     664           0 :                 cv->b.layerheads[cv->b.drawmode]->splines = ss;
     665           0 :                 CVCharChangedUpdate((CharViewBase *) cv);
     666             :             }
     667             :         } else {
     668           0 :             pi->pi.pt = GTabSetGetSel(GWidgetGetControl(pi->gw,CID_TabSet))==0 ? pt_fontsample :
     669           0 :                        GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_Chars))? pt_chars:
     670           0 :                        GGadgetIsChecked(GWidgetGetControl(pi->gw,CID_MultiSize))? pt_multisize:
     671             :                        pt_fontdisplay;
     672           0 :             if ( pi->pi.pt==pt_fontdisplay ) {
     673           0 :                 pi->pi.pointsize = GetInt8(pi->gw,CID_PointSize,_("_Pointsize:"),&err);
     674           0 :                 if ( err )
     675           0 : return(true);
     676           0 :                 if ( pi->pi.pointsize<1 || pi->pi.pointsize>200 ) {
     677           0 :                     ff_post_error(_("Invalid point size"),_("Invalid point size"));
     678           0 : return(true);
     679             :                 }
     680             :             }
     681           0 :             if ( pi->pi.printtype==pt_unknown )
     682           0 :                 if ( !PageSetup(pi))
     683           0 : return(true);
     684             : 
     685           0 :             if ( pi->pi.printtype==pt_file || pi->pi.printtype==pt_pdf ) {
     686           0 :                 sprintf(buf,"pr-%.90s.%s", pi->pi.mainsf->fontname,
     687           0 :                         pi->pi.printtype==pt_file?"ps":"pdf");
     688           0 :                 ret = gwwv_save_filename(_("Print To File..."),buf,
     689             :                         pi->pi.printtype==pt_pdf?"*.pdf":"*.ps");
     690           0 :                 if ( ret==NULL )
     691           0 : return(true);
     692           0 :                 file = utf82def_copy(ret);
     693           0 :                 free(ret);
     694           0 :                 pi->pi.out = fopen(file,"wb");
     695           0 :                 if ( pi->pi.out==NULL ) {
     696           0 :                     ff_post_error(_("Print Failed"),_("Failed to open file %s for output"), file);
     697           0 :                     free(file);
     698           0 : return(true);
     699             :                 }
     700             :             } else {
     701           0 :                 file = NULL;
     702           0 :                 pi->pi.out = tmpfile();
     703           0 :                 if ( pi->pi.out==NULL ) {
     704           0 :                     ff_post_error(_("Failed to open temporary output file"),_("Failed to open temporary output file"));
     705           0 : return(true);
     706             :                 }
     707             :             }
     708             : 
     709           0 :             pdefs[di].last_cs = pi->pi.mainmap->enc;
     710           0 :             pdefs[di].pt = pi->pi.pt;
     711           0 :             pdefs[di].pointsize = pi->pi.pointsize;
     712             : 
     713           0 :             if ( pi->pi.pt==pt_fontsample ) {
     714           0 :                 pi->pi.sample = LIConvertToPrint(
     715           0 :                         &((SFTextArea *) GWidgetGetControl(pi->gw,CID_SampleText))->li,
     716           0 :                         (pagewidth-1*72)*printdpi/72,
     717           0 :                         (pageheight-1*72)*printdpi/72,
     718             :                         printdpi);
     719             :             }
     720             : 
     721           0 :             DoPrinting(&pi->pi,file);
     722           0 :             free(file);
     723           0 :             if ( pi->pi.pt==pt_fontsample ) {
     724           0 :                 LayoutInfo_Destroy(pi->pi.sample);
     725           0 :                 free(pi->pi.sample);
     726             :             }
     727             :         }
     728             : 
     729           0 :         if ( pi->done!=NULL )
     730           0 :             *(pi->done) = true;
     731           0 :         GDrawDestroyWindow(pi->gw);
     732             :     }
     733           0 : return( true );
     734             : }
     735             : 
     736           0 : static int PRT_Setup(GGadget *g, GEvent *e) {
     737           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     738           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     739           0 :         PageSetup(pi);
     740             :     }
     741           0 : return( true );
     742             : }
     743             : 
     744           0 : static int PRT_RadioSet(GGadget *g, GEvent *e) {
     745           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     746           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
     747           0 :         PRT_SetEnabled(pi);
     748             :     }
     749           0 : return( true );
     750             : }
     751             : 
     752             : /* ************************************************************************** */
     753             : /* ************************ Code for Display dialog ************************* */
     754             : /* ************************************************************************** */
     755             : 
     756           0 : static void TextInfoDataFree(GTextInfo *ti) {
     757             :     int i;
     758             : 
     759           0 :     if ( ti==NULL )
     760           0 : return;
     761           0 :     for ( i=0; ti[i].text!=NULL || ti[i].line ; ++i )
     762           0 :         free(ti[i].userdata);
     763           0 :     GTextInfoListFree(ti);
     764             : }
     765             : 
     766           0 : static GTextInfo *FontNames(SplineFont *cur_sf, int insert_text) {
     767             :     int cnt;
     768             :     FontView *fv;
     769             :     SplineFont *sf;
     770             :     GTextInfo *ti;
     771           0 :     int selected = false, any_other=-1;
     772             : 
     773           0 :     for ( fv=fv_list, cnt=0; fv!=NULL; fv=(FontView *) (fv->b.next) )
     774           0 :         if ( (FontView *) (fv->b.nextsame)==NULL )
     775           0 :             ++cnt;
     776           0 :     ti = calloc(cnt+1,sizeof(GTextInfo));
     777           0 :     for ( fv=fv_list, cnt=0; fv!=NULL; fv=(FontView *) (fv->b.next) ) {
     778           0 :         if ( (FontView *) (fv->b.nextsame)==NULL ) {
     779           0 :             sf = fv->b.sf;
     780           0 :             if ( sf->cidmaster!=NULL ) sf = sf->cidmaster;
     781           0 :             ti[cnt].text = uc_copy(sf->fontname);
     782           0 :             ti[cnt].userdata = sf;
     783             :             /* In the print dlg, use the current font */
     784             :             /* In the insert_text dlg, use anything other than the current */
     785           0 :             if ( sf==cur_sf && !insert_text ) {
     786           0 :                 ti[cnt].selected = true;
     787           0 :                 selected = true;
     788           0 :             } else if ( cur_sf!=sf && !selected && insert_text ) {
     789           0 :                 if ( cur_sf->new )
     790           0 :                     any_other = cnt;
     791             :                 else {
     792           0 :                     ti[cnt].selected = true;
     793           0 :                     selected = true;
     794             :                 }
     795             :             }
     796           0 :             ++cnt;
     797             :         }
     798             :     }
     799           0 :     if ( !selected && any_other!=-1 )
     800           0 :         ti[any_other].selected = true;
     801           0 :     else if ( !selected )
     802           0 :         ti[0].selected = true;
     803           0 : return( ti );
     804             : }
     805             : 
     806           0 : static BDFFont *DSP_BestMatch(SplineFont *sf,int aa,int size) {
     807           0 :     BDFFont *bdf, *sizem=NULL;
     808             :     int a;
     809             : 
     810           0 :     for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
     811           0 :         if ( bdf->clut==NULL && !aa )
     812           0 :             a = 4;
     813           0 :         else if ( bdf->clut!=NULL && aa ) {
     814           0 :             if ( bdf->clut->clut_len==256 )
     815           0 :                 a = 4;
     816           0 :             else if ( bdf->clut->clut_len==16 )
     817           0 :                 a = 3;
     818             :             else
     819           0 :                 a = 2;
     820             :         } else
     821           0 :             a = 1;
     822           0 :         if ( bdf->pixelsize==size && a==4 )
     823           0 : return( bdf );
     824           0 :         if ( sizem==NULL )
     825           0 :             sizem = bdf;
     826             :         else {
     827           0 :             int sdnew = bdf->pixelsize-size, sdold = sizem->pixelsize-size;
     828           0 :             if ( sdnew<0 ) sdnew = -sdnew;
     829           0 :             if ( sdold<0 ) sdold = -sdold;
     830           0 :             if ( sdnew<sdold )
     831           0 :                 sizem = bdf;
     832           0 :             else if ( sdnew==sdold ) {
     833             :                 int olda;
     834           0 :                 if ( sizem->clut==NULL && !aa )
     835           0 :                     olda = 4;
     836           0 :                 else if ( sizem->clut!=NULL && aa ) {
     837           0 :                     if ( sizem->clut->clut_len==256 )
     838           0 :                         olda = 4;
     839           0 :                     else if ( sizem->clut->clut_len==16 )
     840           0 :                         olda = 3;
     841             :                     else
     842           0 :                         olda = 2;
     843             :                 } else
     844           0 :                     olda = 1;
     845           0 :                 if ( a>olda )
     846           0 :                     sizem = bdf;
     847             :             }
     848             :         }
     849             :     }
     850           0 : return( sizem );        
     851             : }
     852             : 
     853           0 : static BDFFont *DSP_BestMatchDlg(PD *di) {
     854           0 :     GTextInfo *sel = GGadgetGetListItemSelected(GWidgetGetControl(di->gw,CID_Font));
     855             :     SplineFont *sf;
     856             :     int val;
     857             :     unichar_t *end;
     858             : 
     859           0 :     if ( sel==NULL )
     860           0 : return( NULL );
     861           0 :     sf = sel->userdata;
     862           0 :     val = u_strtol(_GGadgetGetTitle(GWidgetGetControl(di->gw,CID_Size)),&end,10);
     863           0 :     if ( *end!='\0' || val<4 )
     864           0 : return( NULL );
     865             : 
     866           0 : return( DSP_BestMatch(sf,GGadgetIsChecked(GWidgetGetControl(di->gw,CID_AA)),val) );
     867             : }
     868             : 
     869           0 : static enum sftf_fonttype DSP_FontType(PD *di) {
     870             :     int type;
     871           0 :     type = GGadgetIsChecked(GWidgetGetControl(di->gw,CID_pfb))? sftf_pfb :
     872           0 :            GGadgetIsChecked(GWidgetGetControl(di->gw,CID_ttf))? sftf_ttf :
     873           0 :            GGadgetIsChecked(GWidgetGetControl(di->gw,CID_otf))? sftf_otf :
     874           0 :            GGadgetIsChecked(GWidgetGetControl(di->gw,CID_nohints))? sftf_nohints :
     875           0 :            GGadgetIsChecked(GWidgetGetControl(di->gw,CID_pfaedit))? sftf_pfaedit :
     876             :            sftf_bitmap;
     877           0 : return( type );
     878             : }
     879             : 
     880           0 : static void DSP_SetFont(PD *di,int doall) {
     881             :     unichar_t *end;
     882           0 :     int size = u_strtol(_GGadgetGetTitle(GWidgetGetControl(di->gw,CID_Size)),&end,10);
     883           0 :     GTextInfo *sel = GGadgetGetListItemSelected(GWidgetGetControl(di->gw,CID_Font));
     884             :     SplineFont *sf;
     885           0 :     int aa = GGadgetIsChecked(GWidgetGetControl(di->gw,CID_AA));
     886             :     int type;
     887             :     SFTextArea *g;
     888             :     int layer;
     889             : 
     890           0 :     if ( sel==NULL || *end )
     891           0 : return;
     892           0 :     sf = sel->userdata;
     893             : 
     894           0 :     type = DSP_FontType(di);
     895             : 
     896           0 :     g = (SFTextArea *) GWidgetGetControl(di->gw,CID_SampleText);
     897           0 :     layer = di->fv!=NULL && di->fv->b.sf==sf ? di->fv->b.active_layer : ly_fore;
     898           0 :     if ( !LI_SetFontData( &g->li, doall?0:-1,-1,
     899             :             sf,layer,type,size,aa,g->g.inner.width))
     900           0 :         ff_post_error(_("Bad Font"),_("Bad Font"));
     901             : }
     902             : 
     903           0 : static void DSP_ChangeFontCallback(void *context,SplineFont *sf,enum sftf_fonttype type,
     904             :         int size, int aa, uint32 script, uint32 lang, uint32 *feats) {
     905           0 :     PD *di = context;
     906             :     char buf[16];
     907             :     int i,j,cnt;
     908             :     uint32 *tags;
     909             :     GTextInfo **ti;
     910             : 
     911           0 :     GGadgetSetChecked(GWidgetGetControl(di->gw,CID_AA),aa);
     912             : 
     913           0 :     sprintf(buf,"%d",size);
     914           0 :     GGadgetSetTitle8(GWidgetGetControl(di->gw,CID_Size),buf);
     915             : 
     916             :     {
     917             :         GTextInfo **ti;
     918             :         int i,set; int32 len;
     919           0 :         ti = GGadgetGetList(GWidgetGetControl(di->gw,CID_Font),&len);
     920           0 :         for ( i=0; i<len; ++i )
     921           0 :             if ( ti[i]->userdata == sf )
     922           0 :         break;
     923           0 :         if ( i<len ) {
     924           0 :             GGadgetSelectOneListItem(GWidgetGetControl(di->gw,CID_Font),i);
     925             :             /*GGadgetSetTitle(GWidgetGetControl(di->gw,CID_Font),ti[i]->text);*/
     926             :         }
     927           0 :         set = hasFreeType() && !sf->onlybitmaps && sf->subfontcnt==0 &&
     928           0 :                 !sf->strokedfont && !sf->multilayer;
     929           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_pfb),set);
     930           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_ttf),set);
     931           0 :         set = hasFreeType() && !sf->onlybitmaps &&
     932           0 :                 !sf->strokedfont && !sf->multilayer;
     933           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_otf),set);
     934           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_nohints),hasFreeType());
     935           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_bitmap),sf->bitmaps!=NULL);
     936           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_pfaedit),!sf->onlybitmaps);
     937             :     }
     938             : 
     939           0 :     if ( type==sftf_pfb )
     940           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_pfb),true);
     941           0 :     else if ( type==sftf_ttf )
     942           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_ttf),true);
     943           0 :     else if ( type==sftf_otf )
     944           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_otf),true);
     945           0 :     else if ( type==sftf_nohints )
     946           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_nohints),true);
     947           0 :     else if ( type==sftf_pfaedit )
     948           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_pfaedit),true);
     949             :     else
     950           0 :         GGadgetSetChecked(GWidgetGetControl(di->gw,CID_bitmap),true);
     951             : 
     952           0 :     if ( script==0 ) script = DEFAULT_SCRIPT;
     953           0 :     if ( lang  ==0 ) lang   = DEFAULT_LANG;
     954           0 :     buf[0] = script>>24; buf[1] = script>>16; buf[2] = script>>8; buf[3] = script;
     955           0 :     buf[4] = '{';
     956           0 :     buf[5] = lang>>24; buf[6] = lang>>16; buf[7] = lang>>8; buf[8] = lang;
     957           0 :     buf[9] = '}';
     958           0 :     buf[10] = '\0';
     959           0 :     GGadgetSetTitle8(GWidgetGetControl(di->gw,CID_ScriptLang),buf);
     960             : 
     961           0 :     tags = SFFeaturesInScriptLang(sf,-2,script,lang);
     962           0 :     if ( tags[0]==0 ) {
     963           0 :         free(tags);
     964           0 :         tags = SFFeaturesInScriptLang(sf,-2,script,DEFAULT_LANG);
     965             :     }
     966           0 :     for ( cnt=0; tags[cnt]!=0; ++cnt );
     967           0 :     if ( feats!=NULL )
     968           0 :         for ( i=0; feats[i]!=0; ++i ) {
     969           0 :             for ( j=0; tags[j]!=0; ++j ) {
     970           0 :                 if ( feats[i]==tags[j] )
     971           0 :             break;
     972             :             }
     973           0 :             if ( tags[j]==0 )
     974           0 :                 ++cnt;
     975             :         }
     976           0 :     ti = malloc((cnt+2)*sizeof(GTextInfo *));
     977           0 :     for ( i=0; tags[i]!=0; ++i ) {
     978           0 :         ti[i] = calloc( 1,sizeof(GTextInfo));
     979           0 :         ti[i]->fg = ti[i]->bg = COLOR_DEFAULT;
     980           0 :         if ( (tags[i]>>24)<' ' || (tags[i]>>24)>0x7e )
     981           0 :             sprintf( buf, "<%d,%d>", tags[i]>>16, tags[i]&0xffff );
     982             :         else {
     983           0 :             buf[0] = tags[i]>>24; buf[1] = tags[i]>>16; buf[2] = tags[i]>>8; buf[3] = tags[i]; buf[4] = 0;
     984             :         }
     985           0 :         ti[i]->text = uc_copy(buf);
     986           0 :         ti[i]->userdata = (void *) (intpt) tags[i];
     987           0 :         if ( feats!=NULL ) {
     988           0 :             for ( j=0; feats[j]!=0; ++j ) {
     989           0 :                 if ( feats[j] == tags[i] ) {
     990           0 :                     ti[i]->selected = true;
     991           0 :             break;
     992             :                 }
     993             :             }
     994             :         }
     995             :     }
     996           0 :     cnt = i;
     997           0 :     if ( feats!=NULL )
     998           0 :         for ( i=0; feats[i]!=0; ++i ) {
     999           0 :             for ( j=0; tags[j]!=0; ++j ) {
    1000           0 :                 if ( feats[i]==tags[j] )
    1001           0 :             break;
    1002             :             }
    1003           0 :             if ( tags[j]==0 ) {
    1004           0 :                 ti[cnt] = calloc( 1,sizeof(GTextInfo));
    1005           0 :                 ti[cnt]->bg = COLOR_DEFAULT;
    1006           0 :                 ti[cnt]->fg = COLOR_CREATE(0x70,0x70,0x70);
    1007           0 :                 ti[cnt]->selected = true;
    1008           0 :                 buf[0] = feats[i]>>24; buf[1] = feats[i]>>16; buf[2] = feats[i]>>8; buf[3] = feats[i]; buf[4] = 0;
    1009           0 :                 ti[cnt]->text = uc_copy(buf);
    1010           0 :                 ti[cnt++]->userdata = (void *) (intpt) feats[i];
    1011             :             }
    1012             :         }
    1013           0 :     ti[cnt] = calloc(1,sizeof(GTextInfo));
    1014             :     /* These will become ordered because the list widget will do that */
    1015           0 :     GGadgetSetList(GWidgetGetControl(di->gw,CID_Features),ti,false);
    1016           0 :     free(tags);
    1017           0 : }
    1018             : 
    1019           0 : static int DSP_AAState(SplineFont *sf,BDFFont *bestbdf) {
    1020             :     /* What should AntiAlias look like given the current set of bitmaps */
    1021           0 :     int anyaa=0, anybit=0;
    1022             :     BDFFont *bdf;
    1023             : 
    1024           0 :     for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next )
    1025           0 :         if ( bdf->clut==NULL )
    1026           0 :             anybit = true;
    1027             :         else
    1028           0 :             anyaa = true;
    1029           0 :     if ( anybit && anyaa )
    1030           0 : return( gg_visible | gg_enabled | (bestbdf!=NULL && bestbdf->clut!=NULL ? gg_cb_on : 0) );
    1031           0 :     else if ( anybit )
    1032           0 : return( gg_visible );
    1033           0 :     else if ( anyaa )
    1034           0 : return( gg_visible | gg_cb_on );
    1035             : 
    1036           0 : return( gg_visible );
    1037             : }
    1038             : 
    1039           0 : static int DSP_FontChanged(GGadget *g, GEvent *e) {
    1040           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
    1041           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1042           0 :         GTextInfo *sel = GGadgetGetListItemSelected(g);
    1043             :         SplineFont *sf;
    1044             :         BDFFont *best;
    1045           0 :         int flags, pick = 0, i;
    1046             :         char size[12]; unichar_t usize[12];
    1047             :         uint16 cnt;
    1048             : 
    1049           0 :         if ( sel==NULL )
    1050           0 : return( true );
    1051           0 :         sf = sel->userdata;
    1052             : 
    1053           0 :         TextInfoDataFree(di->scriptlangs);
    1054           0 :         di->scriptlangs = SLOfFont(sf);
    1055           0 :         GGadgetSetList(GWidgetGetControl(di->gw,CID_ScriptLang),
    1056             :                 GTextInfoArrayFromList(di->scriptlangs,&cnt),false);
    1057             : 
    1058           0 :         if ( GGadgetIsChecked(GWidgetGetControl(di->gw,CID_bitmap)) && sf->bitmaps==NULL )
    1059           0 :             pick = true;
    1060           0 :         GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_bitmap),sf->bitmaps!=NULL);
    1061           0 :         if ( !hasFreeType() || sf->onlybitmaps ) {
    1062           0 :             best = DSP_BestMatchDlg(di);
    1063           0 :             flags = DSP_AAState(sf,best);
    1064           0 :             GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_AA),flags&gg_enabled);
    1065           0 :             GGadgetSetChecked(GWidgetGetControl(di->gw,CID_AA),flags&gg_cb_on);
    1066           0 :             GGadgetSetChecked(GWidgetGetControl(di->gw,CID_bitmap),true);
    1067           0 :             for ( i=CID_pfb; i<=CID_nohints; ++i )
    1068           0 :                 GGadgetSetEnabled(GWidgetGetControl(di->gw,i),false);
    1069           0 :             if ( best!=NULL ) {
    1070           0 :                 sprintf( size, "%d", best->pixelsize );
    1071           0 :                 uc_strcpy(usize,size);
    1072           0 :                 GGadgetSetTitle(GWidgetGetControl(di->gw,CID_Size),usize);
    1073             :             }
    1074           0 :             pick = true;
    1075           0 :         } else if ( sf->subfontcnt!=0 ) {
    1076           0 :             for ( i=CID_pfb; i<CID_otf; ++i ) {
    1077           0 :                 GGadgetSetEnabled(GWidgetGetControl(di->gw,i),false);
    1078           0 :                 if ( GGadgetIsChecked(GWidgetGetControl(di->gw,i)) )
    1079           0 :                     pick = true;
    1080             :             }
    1081           0 :             GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_otf),true);
    1082           0 :             if ( pick )
    1083           0 :                 GGadgetSetChecked(GWidgetGetControl(di->gw,CID_otf),true);
    1084             :         } else {
    1085           0 :             for ( i=CID_pfb; i<=CID_otf; ++i )
    1086           0 :                 GGadgetSetEnabled(GWidgetGetControl(di->gw,i),true);
    1087           0 :             if ( pick )
    1088           0 :                 GGadgetSetChecked(GWidgetGetControl(di->gw,CID_pfb),true);
    1089             :         }
    1090           0 :         if ( pick )
    1091           0 :             DSP_SetFont(di,false);
    1092             :         else
    1093           0 :             SFTFSetFont(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,sf);
    1094             :     }
    1095           0 : return( true );
    1096             : }
    1097             : 
    1098           0 : static int DSP_AAChange(GGadget *g, GEvent *e) {
    1099           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    1100           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1101           0 :         if ( GGadgetIsChecked(GWidgetGetControl(di->gw,CID_bitmap)) ) {
    1102           0 :             int val = u_strtol(_GGadgetGetTitle(GWidgetGetControl(di->gw,CID_Size)),NULL,10);
    1103           0 :             int bestdiff = 8000, bdfdiff;
    1104           0 :             BDFFont *bdf, *best=NULL;
    1105           0 :             GTextInfo *sel = GGadgetGetListItemSelected(GWidgetGetControl(di->gw,CID_Font));
    1106             :             SplineFont *sf;
    1107           0 :             int aa = GGadgetIsChecked(GWidgetGetControl(di->gw,CID_AA));
    1108           0 :             if ( sel==NULL )
    1109           0 : return( true );
    1110           0 :             sf = sel->userdata;
    1111           0 :             for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
    1112           0 :                 if ( (aa && bdf->clut) || (!aa && bdf->clut==NULL)) {
    1113           0 :                     if ((bdfdiff = bdf->pixelsize-val)<0 ) bdfdiff = -bdfdiff;
    1114           0 :                     if ( bdfdiff<bestdiff ) {
    1115           0 :                         best = bdf;
    1116           0 :                         bestdiff = bdfdiff;
    1117           0 :                         if ( bdfdiff==0 )
    1118           0 :             break;
    1119             :                     }
    1120             :                 }
    1121             :             }
    1122           0 :             if ( best!=NULL ) {
    1123             :                 char size[12]; unichar_t usize[12];
    1124           0 :                 sprintf( size, "%d", best->pixelsize );
    1125           0 :                 uc_strcpy(usize,size);
    1126           0 :                 GGadgetSetTitle(GWidgetGetControl(di->gw,CID_Size),usize);
    1127             :             }
    1128           0 :             DSP_SetFont(di,false);
    1129             :         } else
    1130           0 :             SFTFSetAntiAlias(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,
    1131           0 :                     GGadgetIsChecked(GWidgetGetControl(di->gw,CID_AA)));
    1132             :     }
    1133           0 : return( true );
    1134             : }
    1135             : 
    1136           0 : static int DSP_SizeChanged(GGadget *g, GEvent *e) {
    1137           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textfocuschanged &&
    1138           0 :             !e->u.control.u.tf_focus.gained_focus ) {
    1139           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1140           0 :         int err=false;
    1141           0 :         int size = GetInt8(di->gw,CID_Size,_("_Size:"),&err);
    1142           0 :         if ( err || size<4 )
    1143           0 : return( true );
    1144           0 :         if ( GWidgetGetControl(di->gw,CID_SampleText)==NULL )
    1145           0 : return( true );         /* Happens during startup */
    1146           0 :         if ( GGadgetIsChecked(GWidgetGetControl(di->gw,CID_bitmap)) ) {
    1147           0 :             GTextInfo *sel = GGadgetGetListItemSelected(GWidgetGetControl(di->gw,CID_Font));
    1148             :             SplineFont *sf;
    1149           0 :             BDFFont *bdf, *best=NULL;
    1150           0 :             int aa = GGadgetIsChecked(GWidgetGetControl(di->gw,CID_AA));
    1151           0 :             if ( sel==NULL )
    1152           0 : return( true );
    1153           0 :             sf = sel->userdata;
    1154           0 :             for ( bdf = sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
    1155           0 :                 if ( bdf->pixelsize==size ) {
    1156           0 :                     if (( bdf->clut && aa ) || ( bdf->clut==NULL && !aa )) {
    1157           0 :                         best = bdf;
    1158           0 :             break;
    1159             :                     }
    1160           0 :                     best = bdf;
    1161             :                 }
    1162             :             }
    1163           0 :             if ( best==NULL ) {
    1164           0 :                 char buf[100], *pt=buf, *end=buf+sizeof(buf)-10;
    1165             :                 unichar_t ubuf[12];
    1166           0 :                 int lastsize = 0;
    1167           0 :                 for ( bdf=sf->bitmaps; bdf!=NULL && pt<end; bdf=bdf->next ) {
    1168           0 :                     if ( bdf->pixelsize!=lastsize ) {
    1169           0 :                         sprintf( pt, "%d,", bdf->pixelsize );
    1170           0 :                         lastsize = bdf->pixelsize;
    1171           0 :                         pt += strlen(pt);
    1172             :                     }
    1173             :                 }
    1174           0 :                 if ( pt!=buf )
    1175           0 :                     pt[-1] = '\0';
    1176           0 :                 ff_post_error(_("Bad Size"),_("Requested bitmap size not available in font. Font supports %s"),buf);
    1177           0 :                 best = DSP_BestMatchDlg(di);
    1178           0 :                 if ( best!=NULL ) {
    1179           0 :                     sprintf( buf, "%d", best->pixelsize);
    1180           0 :                     uc_strcpy(ubuf,buf);
    1181           0 :                     GGadgetSetTitle(GWidgetGetControl(di->gw,CID_Size),ubuf);
    1182           0 :                     size = best->pixelsize;
    1183             :                 }
    1184             :             }
    1185           0 :             if ( best==NULL )
    1186           0 : return(true);
    1187           0 :             GGadgetSetChecked(GWidgetGetControl(di->gw,CID_AA),best->clut!=NULL );
    1188           0 :             DSP_SetFont(di,false);
    1189             :         } else
    1190           0 :             SFTFSetSize(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,size);
    1191           0 :     } else if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1192             :         /* Don't change the font on each change to the text field, that might */
    1193             :         /*  look rather odd. But wait until we think they may have finished */
    1194             :         /*  typing. Either when they change the focus (above) or when they */
    1195             :         /*  just don't do anything for a while */
    1196           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1197           0 :         if ( di->sizechanged!=NULL )
    1198           0 :             GDrawCancelTimer(di->sizechanged);
    1199           0 :         di->sizechanged = GDrawRequestTimer(di->gw,600,0,NULL);
    1200             :     }
    1201           0 : return( true );
    1202             : }
    1203             : 
    1204           0 : static void DSP_SizeChangedTimer(PD *di) {
    1205             :     GEvent e;
    1206             : 
    1207           0 :     di->sizechanged = NULL;
    1208           0 :     memset(&e,0,sizeof(e));
    1209           0 :     e.type = et_controlevent;
    1210           0 :     e.u.control.g = GWidgetGetControl(di->gw,CID_Size);
    1211           0 :     e.u.control.subtype = et_textfocuschanged;
    1212           0 :     e.u.control.u.tf_focus.gained_focus = false;
    1213           0 :     DSP_SizeChanged(e.u.control.g,&e);
    1214           0 : }
    1215             : 
    1216             : 
    1217           0 : static int DSP_WidthChanged(GGadget *g, GEvent *e) {
    1218           0 :     if ( e==NULL ||
    1219           0 :             (e->type==et_controlevent && e->u.control.subtype == et_textfocuschanged &&
    1220           0 :              !e->u.control.u.tf_focus.gained_focus )) {
    1221           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1222           0 :         int err=false;
    1223           0 :         int width = GetInt8(di->gw,CID_TextWidth,_("Width"),&err);
    1224           0 :         GGadget *sample = GWidgetGetControl(di->gw,CID_SampleText);
    1225             :         GRect outer;
    1226             :         int bp;
    1227           0 :         if ( err || width<20 || width>2000 )
    1228           0 : return( true );
    1229           0 :         if ( !di->ready )
    1230           0 : return( true );
    1231           0 :         bp = GBoxBorderWidth(di->gw,sample->box);
    1232           0 :         GGadgetGetSize(sample,&outer);
    1233           0 :         outer.width = rint(width*lastdpi/72.0)+2*bp;
    1234           0 :         GGadgetSetDesiredSize(sample,&outer,NULL);
    1235           0 :         GHVBoxFitWindow(GWidgetGetControl(di->gw,CID_TopBox));
    1236           0 :     } else if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1237             :         /* Don't change the font on each change to the text field, that might */
    1238             :         /*  look rather odd. But wait until we think they may have finished */
    1239             :         /*  typing. Either when they change the focus (above) or when they */
    1240             :         /*  just don't do anything for a while */
    1241           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1242           0 :         if ( di->widthchanged!=NULL )
    1243           0 :             GDrawCancelTimer(di->widthchanged);
    1244           0 :         di->widthchanged = GDrawRequestTimer(di->gw,600,0,NULL);
    1245             :     }
    1246           0 : return( true );
    1247             : }
    1248             : 
    1249           0 : static void DSP_WidthChangedTimer(PD *di) {
    1250             : 
    1251           0 :     di->widthchanged = NULL;
    1252           0 :     DSP_WidthChanged(GWidgetGetControl(di->gw,CID_TextWidth),NULL);
    1253           0 : }
    1254             : 
    1255           0 : static void DSP_JustResized(PD *di) {
    1256           0 :     GGadget *sample = GWidgetGetControl(di->gw,CID_SampleText);
    1257           0 :     GGadget *widthfield = GWidgetGetControl(di->gw,CID_TextWidth);
    1258             :     char buffer[20];
    1259             : 
    1260           0 :     di->resized = NULL;
    1261           0 :     if ( lastdpi!=0 && widthfield!=NULL ) {
    1262           0 :         sprintf( buffer, "%d", (int) rint( sample->inner.width*72/lastdpi ));
    1263           0 :         GGadgetSetTitle8(widthfield,buffer);
    1264             :     }
    1265           0 : }
    1266             : 
    1267           0 : static int DSP_DpiChanged(GGadget *g, GEvent *e) {
    1268           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textfocuschanged &&
    1269           0 :             !e->u.control.u.tf_focus.gained_focus ) {
    1270           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1271           0 :         int err=false;
    1272           0 :         int dpi = GetInt8(di->gw,CID_DPI,_("DPI"),&err);
    1273           0 :         GGadget *sample = GWidgetGetControl(di->gw,CID_SampleText);
    1274           0 :         GGadget *widthfield = GWidgetGetControl(di->gw,CID_TextWidth);
    1275           0 :         if ( err || dpi<20 || dpi>300 )
    1276           0 : return( true );
    1277           0 :         if ( !di->ready )
    1278           0 : return( true );         /* Happens during startup */
    1279           0 :         if ( lastdpi==dpi )
    1280           0 : return( true );
    1281           0 :         SFTFSetDPI(sample,dpi);
    1282           0 :         lastdpi = dpi;
    1283           0 :         if ( widthfield!=NULL ) {
    1284           0 :             DSP_WidthChanged(widthfield,NULL);
    1285             :         } else {
    1286           0 :             GGadgetRedraw(sample);
    1287             :         }
    1288           0 :     } else if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1289             :         /* Don't change the font on each change to the text field, that might */
    1290             :         /*  look rather odd. But wait until we think they may have finished */
    1291             :         /*  typing. Either when they change the focus (above) or when they */
    1292             :         /*  just don't do anything for a while */
    1293           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1294           0 :         if ( di->dpichanged!=NULL )
    1295           0 :             GDrawCancelTimer(di->dpichanged);
    1296           0 :         di->dpichanged = GDrawRequestTimer(di->gw,600,0,NULL);
    1297             :     }
    1298           0 : return( true );
    1299             : }
    1300             : 
    1301           0 : static void DSP_DpiChangedTimer(PD *di) {
    1302             :     GEvent e;
    1303             : 
    1304           0 :     di->dpichanged = NULL;
    1305           0 :     memset(&e,0,sizeof(e));
    1306           0 :     e.type = et_controlevent;
    1307           0 :     e.u.control.g = GWidgetGetControl(di->gw,CID_Size);
    1308           0 :     e.u.control.subtype = et_textfocuschanged;
    1309           0 :     e.u.control.u.tf_focus.gained_focus = false;
    1310           0 :     DSP_DpiChanged(e.u.control.g,&e);
    1311           0 : }
    1312             : 
    1313           0 : static int DSP_Refresh(GGadget *g, GEvent *e) {
    1314           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1315           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1316           0 :         GGadget *sample = GWidgetGetControl(di->gw,CID_SampleText);
    1317           0 :         GGadget *fontnames = GWidgetGetControl(di->gw,CID_Font);
    1318           0 :         GTextInfo *sel = GGadgetGetListItemSelected(fontnames);
    1319             :         GTextInfo *fn;
    1320             : 
    1321           0 :         SFTFRefreshFonts(sample);               /* Clear any font info and get new font maps, etc. */
    1322           0 :         SFTFProvokeCallback(sample);            /* Refresh the feature list too */
    1323             : 
    1324             :         /* One thing we don't have to worry about is a font being removed */
    1325             :         /*  if that happens we just close this window. Too hard to fix up for */
    1326             :         /* But a font might be added... */
    1327           0 :         fn = FontNames(sel!=NULL? (SplineFont *) (sel->userdata) : di->pi.mainsf, di->insert_text );
    1328           0 :         GGadgetSetList(fontnames,GTextInfoArrayFromList(fn,NULL),false);
    1329           0 :         GGadgetSetEnabled(fontnames,fn[1].text!=NULL);
    1330           0 :         GTextInfoListFree(fn);
    1331             :     }
    1332           0 : return( true );
    1333             : }
    1334             : 
    1335           0 : static int DSP_RadioSet(GGadget *g, GEvent *e) {
    1336           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    1337           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1338           0 :         if ( GGadgetIsChecked(GWidgetGetControl(di->gw,CID_bitmap)) ) {
    1339           0 :             BDFFont *best = DSP_BestMatchDlg(di);
    1340           0 :             GTextInfo *sel = GGadgetGetListItemSelected(GWidgetGetControl(di->gw,CID_Font));
    1341             :             SplineFont *sf;
    1342             :             int flags;
    1343             :             char size[12]; unichar_t usize[12];
    1344             : 
    1345           0 :             if ( sel!=NULL ) {
    1346           0 :                 sf = sel->userdata;
    1347           0 :                 flags = DSP_AAState(sf,best);
    1348           0 :                 GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_AA),flags&gg_enabled);
    1349           0 :                 GGadgetSetChecked(GWidgetGetControl(di->gw,CID_AA),flags&gg_cb_on);
    1350           0 :                 if ( best!=NULL ) {
    1351           0 :                     sprintf( size, "%g",
    1352           0 :                             rint(best->pixelsize*72.0/SFTFGetDPI(GWidgetGetControl(di->gw,CID_SampleText))) );
    1353           0 :                     uc_strcpy(usize,size);
    1354           0 :                     GGadgetSetTitle(GWidgetGetControl(di->gw,CID_Size),usize);
    1355             :                 }
    1356             :             }
    1357           0 :             DSP_SetFont(di,false);
    1358             :         } else {
    1359             :             /*GGadgetSetEnabled(GWidgetGetControl(di->gw,CID_AA),true);*/
    1360           0 :             SFTFSetFontType(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,
    1361             :                     DSP_FontType(di));
    1362             :         }
    1363             :     }
    1364           0 : return( true );
    1365             : }
    1366             : 
    1367           0 : static int DSP_ScriptLangChanged(GGadget *g, GEvent *e) {
    1368             : 
    1369           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1370           0 :         const unichar_t *sstr = _GGadgetGetTitle(g);
    1371           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1372             :         uint32 script, lang;
    1373             : 
    1374           0 :         if ( e->u.control.u.tf_changed.from_pulldown!=-1 ) {
    1375           0 :             GGadgetSetTitle8(g,di->scriptlangs[e->u.control.u.tf_changed.from_pulldown].userdata );
    1376           0 :             sstr = _GGadgetGetTitle(g);
    1377             :         } else {
    1378           0 :             if ( u_strlen(sstr)<4 || !isalpha(sstr[0]) || !isalnum(sstr[1]) /*|| !isalnum(sstr[2]) || !isalnum(sstr[3])*/ )
    1379           0 : return( true );
    1380           0 :             if ( u_strlen(sstr)==4 )
    1381             :                 /* No language, we'll use default */;
    1382           0 :             else if ( u_strlen(sstr)!=10 || sstr[4]!='{' || sstr[9]!='}' ||
    1383           0 :                     !isalpha(sstr[5]) || !isalpha(sstr[6]) || !isalpha(sstr[7])  )
    1384           0 : return( true );
    1385             :         }
    1386           0 :         script = DEFAULT_SCRIPT;
    1387           0 :         lang = DEFAULT_LANG;
    1388           0 :         if ( u_strlen(sstr)>=4 )
    1389           0 :             script = (sstr[0]<<24) | (sstr[1]<<16) | (sstr[2]<<8) | sstr[3];
    1390           0 :         if ( sstr[4]=='{' && u_strlen(sstr)>=9 )
    1391           0 :             lang = (sstr[5]<<24) | (sstr[6]<<16) | (sstr[7]<<8) | sstr[8];
    1392           0 :         SFTFSetScriptLang(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,script,lang);
    1393             :     }
    1394           0 : return( true );
    1395             : }
    1396             : 
    1397           0 : static int DSP_Menu(GGadget *g, GEvent *e) {
    1398             : 
    1399           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonpress ) {
    1400           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1401           0 :         GGadget *st = GWidgetGetControl(di->gw,CID_SampleText);
    1402             :         GEvent fudge;
    1403             :         GPoint p;
    1404           0 :         memset(&fudge,0,sizeof(fudge));
    1405           0 :         fudge.type = et_mousedown;
    1406           0 :         fudge.w = st->base;
    1407           0 :         p.x = g->inner.x+g->inner.width/2;
    1408           0 :         p.y = g->inner.y+g->inner.height;
    1409           0 :         GDrawTranslateCoordinates(g->base,st->base,&p);
    1410           0 :         fudge.u.mouse.x = p.x; fudge.u.mouse.y = p.y;
    1411           0 :         SFTFPopupMenu((SFTextArea *) st,&fudge);
    1412             :     }
    1413           0 : return( true );
    1414             : }
    1415             : 
    1416           0 : static int DSP_FeaturesChanged(GGadget *g, GEvent *e) {
    1417             : 
    1418           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
    1419           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1420             :         uint32 *feats;
    1421             :         int32 len;
    1422           0 :         GTextInfo **ti = GGadgetGetList(g,&len);
    1423             :         int i,cnt;
    1424             : 
    1425           0 :         for ( i=cnt=0; i<len; ++i )
    1426           0 :             if ( ti[i]->selected ) ++cnt;
    1427           0 :         feats = malloc((cnt+1)*sizeof(uint32));
    1428           0 :         for ( i=cnt=0; i<len; ++i )
    1429           0 :             if ( ti[i]->selected )
    1430           0 :                 feats[cnt++] = (intpt) ti[i]->userdata;
    1431           0 :         feats[cnt] = 0;
    1432             :         /* These will be ordered because the list widget will do that */
    1433           0 :         SFTFSetFeatures(GWidgetGetControl(di->gw,CID_SampleText),-1,-1,feats);
    1434             :     }
    1435           0 : return( true );
    1436             : }
    1437             : 
    1438           0 : static int PRT_Bind(GGadget *g, GEvent *e) {
    1439           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    1440           0 :         PD *pi = GDrawGetUserData(GGadgetGetWindow(g));
    1441           0 :         int on = GGadgetIsChecked(g);
    1442           0 :         GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_Scale),on);
    1443           0 :         GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_Start),on);
    1444           0 :         GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_Center),on);
    1445           0 :         GGadgetSetEnabled(GWidgetGetControl(pi->gw,CID_End),on);
    1446             :     }
    1447           0 : return( true );
    1448             : }
    1449             : 
    1450           0 : static int DSP_TextChanged(GGadget *g, GEvent *e) {
    1451           0 :     if ( e==NULL ||
    1452           0 :             (e->type==et_controlevent && e->u.control.subtype == et_textchanged )) {
    1453           0 :         PD *di = GDrawGetUserData(GGadgetGetWindow(g));
    1454           0 :         const unichar_t *txt = _GGadgetGetTitle(g);
    1455             :         const unichar_t *pt;
    1456           0 :         SFTextArea *ta = (SFTextArea *) g;
    1457           0 :         LayoutInfo *li = &ta->li;
    1458             :         char buffer[200];
    1459             : 
    1460           0 :         for ( pt=txt; *pt!='\0' && ScriptFromUnicode(*pt,NULL)==DEFAULT_SCRIPT; ++pt);
    1461           0 :         if ( *pt=='\0' ) {
    1462           0 :             if ( !di->script_unknown ) {
    1463           0 :                 di->script_unknown = true;
    1464           0 :                 if ( li->fontlist!=NULL ) {
    1465           0 :                     li->fontlist->script = DEFAULT_SCRIPT;
    1466           0 :                     li->fontlist->lang   = DEFAULT_LANG;
    1467             :                 }
    1468           0 :                 GGadgetSetTitle8(GWidgetGetControl(di->gw,CID_ScriptLang),"DFLT{dflt}");
    1469             :             }
    1470           0 :         } else if ( di->script_unknown ) {
    1471           0 :             uint32 script = ScriptFromUnicode(*pt,NULL);
    1472             :             struct fontlist *fl;
    1473             :             unichar_t buf[20];
    1474           0 :             for ( fl=li->fontlist; fl!=NULL && ta->sel_start>fl->end; fl=fl->next );
    1475           0 :             if ( fl!=NULL && (fl->script==DEFAULT_SCRIPT || fl->script==0 )) {
    1476           0 :                 for ( fl=li->fontlist; fl!=NULL; fl=fl->next ) {
    1477           0 :                     if ( fl->script==DEFAULT_SCRIPT || fl->script == 0 ) {
    1478           0 :                         fl->script = script;
    1479           0 :                         fl->lang = DEFAULT_LANG;
    1480             :                     }
    1481             :                 }
    1482           0 :                 buf[0] = (script>>24)&0xff;
    1483           0 :                 buf[1] = (script>>16)&0xff;
    1484           0 :                 buf[2] = (script>>8 )&0xff;
    1485           0 :                 buf[3] = (script    )&0xff;
    1486           0 :                 uc_strcpy(buf+4,"{dflt}");
    1487           0 :                 GGadgetSetTitle(GWidgetGetControl(di->gw,CID_ScriptLang),buf);
    1488             :             }
    1489           0 :             di->script_unknown = false;
    1490             :         }
    1491             : 
    1492           0 :         if ( di->insert_text && lastdpi!=0) {
    1493           0 :             sprintf( buffer,_("Text Width:%4d"), (int) rint(li->xmax*72.0/lastdpi));
    1494           0 :             GGadgetSetTitle8(GWidgetGetControl(di->gw,CID_ActualWidth),buffer);
    1495             :         }
    1496             :     }
    1497           0 : return( true );
    1498             : }
    1499             : 
    1500           0 : static int DSP_Done(GGadget *g, GEvent *e) {
    1501           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1502           0 :         GWindow gw = GGadgetGetWindow(g);
    1503           0 :         PD *di = GDrawGetUserData(gw);
    1504           0 :         if ( di->done!=NULL )
    1505           0 :             *(di->done) = true;
    1506           0 :         GDrawDestroyWindow(di->gw);
    1507             :     }
    1508           0 : return( true );
    1509             : }
    1510             : 
    1511           0 : static int dsp_e_h(GWindow gw, GEvent *event) {
    1512           0 :     if ( event->type==et_close ) {
    1513           0 :         PD *di = GDrawGetUserData(gw);
    1514           0 :         if ( di->done!=NULL )
    1515           0 :             *(di->done) = true;
    1516           0 :         GDrawDestroyWindow(di->gw);
    1517           0 :     } else if ( event->type==et_destroy ) {
    1518           0 :         PD *di = GDrawGetUserData(gw);
    1519           0 :         TextInfoDataFree(di->scriptlangs);
    1520           0 :         free(di);
    1521           0 :         if ( di==printwindow )
    1522           0 :             printwindow = NULL;
    1523           0 :     } else if ( event->type==et_char ) {
    1524           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
    1525           0 :             help("display.html");
    1526           0 : return( true );
    1527           0 :         } else if ( GMenuIsCommand(event,H_("Quit|Ctl+Q") )) {
    1528           0 :             MenuExit(NULL,NULL,NULL);
    1529           0 :     return( false );
    1530           0 :         } else if ( GMenuIsCommand(event,H_("Close|Ctl+Shft+Q") )) {
    1531           0 :             PD *di = GDrawGetUserData(gw);
    1532           0 :             di->pi.done = true;
    1533             :         }
    1534           0 : return( false );
    1535           0 :     } else if ( event->type==et_timer ) {
    1536           0 :         PD *di = GDrawGetUserData(gw);
    1537           0 :         if ( event->u.timer.timer==di->sizechanged )
    1538           0 :             DSP_SizeChangedTimer(di);
    1539           0 :         else if ( event->u.timer.timer==di->dpichanged )
    1540           0 :             DSP_DpiChangedTimer(di);
    1541           0 :         else if ( event->u.timer.timer==di->widthchanged )
    1542           0 :             DSP_WidthChangedTimer(di);
    1543           0 :         else if ( event->u.timer.timer==di->resized )
    1544           0 :             DSP_JustResized(di);
    1545           0 :     } else if ( event->type==et_resize ) {
    1546           0 :         PD *di = GDrawGetUserData(gw);
    1547           0 :         if ( di->resized!=NULL )
    1548           0 :             GDrawCancelTimer(di->resized);
    1549           0 :         di->resized = GDrawRequestTimer(di->gw,300,0,NULL);
    1550             :     }
    1551           0 : return( true );
    1552             : }
    1553             :     
    1554           0 : static void _PrintFFDlg(FontView *fv,SplineChar *sc,MetricsView *mv,
    1555             :         int isprint,CharView *cv,SplineSet *fit_to_path) {
    1556             :     GRect pos;
    1557             :     GWindowAttrs wattrs;
    1558             :     GGadgetCreateData gcd[20], boxes[15], mgcd[5], pgcd[8], vbox, tgcd[14],
    1559             :             *harray[8], *farray[8], *barray[4],
    1560             :             *barray2[8], *varray[11], *varray2[9], *harray2[5],
    1561             :             *varray3[4][4], *ptarray[4], *varray4[4], *varray5[4][2],
    1562             :             *regenarray[9], *varray6[3], *tarray[18], *alarray[6],
    1563             :             *patharray[5], *oarray[4];
    1564             :     GTextInfo label[20], mlabel[5], plabel[8], tlabel[14];
    1565             :     GTabInfo aspects[3];
    1566             :     int dpi;
    1567             :     char buf[12], dpibuf[12], sizebuf[12], widthbuf[12], pathlen[32];
    1568           0 :     SplineFont *sf = fv!=NULL ? fv->b.sf : sc!=NULL ? sc->parent : mv->fv->b.sf;
    1569           0 :     int hasfreetype = hasFreeType();
    1570           0 :     BDFFont *bestbdf=DSP_BestMatch(sf,true,12);
    1571             :     unichar_t *temp;
    1572             :     int cnt;
    1573           0 :     int fromwindow = fv!=NULL?0:sc!=NULL?1:2;
    1574             :     PD *active;
    1575           0 :     int done = false;
    1576           0 :     int width = 300;
    1577             :     extern int _GScrollBar_Width;
    1578             : 
    1579           0 :     if ( printwindow!=NULL && isprint ) {
    1580           0 :         GDrawSetVisible(printwindow->gw,true);
    1581           0 :         GDrawRaise(printwindow->gw);
    1582           0 : return;
    1583             :     }
    1584             : 
    1585           0 :     if ( sf->cidmaster )
    1586           0 :         sf = sf->cidmaster;
    1587             : 
    1588           0 :     active = calloc(1,sizeof(PD));
    1589           0 :     if ( isprint )
    1590           0 :         printwindow = active;
    1591           0 :     active->fv = fv;
    1592             : 
    1593           0 :     if ( mv!=NULL ) {
    1594           0 :         PI_Init(&active->pi,(FontViewBase *) mv->fv,sc);
    1595           0 :         active->pi.mv = mv;
    1596             :     } else
    1597           0 :         PI_Init(&active->pi,(FontViewBase *) fv,sc);
    1598           0 :     active->cv = cv;
    1599           0 :     active->fit_to_path = fit_to_path;
    1600           0 :     active->insert_text = !isprint;
    1601           0 :     active->done = isprint ? NULL : &done;
    1602             : 
    1603           0 :     memset(&wattrs,0,sizeof(wattrs));
    1604           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    1605           0 :     wattrs.event_masks = ~(1<<et_charup);
    1606           0 :     wattrs.restrict_input_to_me = false;
    1607           0 :     wattrs.undercursor = 1;
    1608           0 :     wattrs.cursor = ct_pointer;
    1609           0 :     wattrs.is_dlg = true;
    1610           0 :     wattrs.utf8_window_title = isprint ? _("Print") : _("Insert Text Outlines");
    1611           0 :     pos.x = pos.y = 0;
    1612           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,410));
    1613           0 :     pos.height = GDrawPointsToPixels(NULL,330);
    1614           0 :     active->gw = GDrawCreateTopWindow(NULL,&pos,dsp_e_h,active,&wattrs);
    1615             : 
    1616           0 :     memset(&vbox,0,sizeof(vbox));
    1617           0 :     memset(&label,0,sizeof(label));
    1618           0 :     memset(&mlabel,0,sizeof(mlabel));
    1619           0 :     memset(&plabel,0,sizeof(plabel));
    1620           0 :     memset(&tlabel,0,sizeof(tlabel));
    1621           0 :     memset(&gcd,0,sizeof(gcd));
    1622           0 :     memset(&mgcd,0,sizeof(mgcd));
    1623           0 :     memset(&pgcd,0,sizeof(pgcd));
    1624           0 :     memset(&tgcd,0,sizeof(tgcd));
    1625           0 :     memset(&boxes,0,sizeof(boxes));
    1626             : 
    1627           0 :     label[0].text = (unichar_t *) sf->fontname;
    1628           0 :     label[0].text_is_1byte = true;
    1629           0 :     gcd[0].gd.label = &label[0];
    1630           0 :     gcd[0].gd.popup_msg = (unichar_t *) _("Select some text, then use this list to change the\nfont in which those characters are displayed.");
    1631           0 :     gcd[0].gd.pos.x = 12; gcd[0].gd.pos.y = 6; 
    1632           0 :     gcd[0].gd.pos.width = 150;
    1633           0 :     gcd[0].gd.cid = CID_Font;
    1634           0 :     gcd[0].gd.u.list = FontNames(sf,active->insert_text);
    1635           0 :     gcd[0].gd.flags = (fv_list==NULL || gcd[0].gd.u.list[1].text==NULL ) ?
    1636             :             (gg_visible | gg_utf8_popup):
    1637             :             (gg_visible | gg_enabled | gg_utf8_popup);
    1638           0 :     gcd[0].gd.handle_controlevent = DSP_FontChanged;
    1639           0 :     gcd[0].creator = GListButtonCreate;
    1640           0 :     varray[0] = &gcd[0]; varray[1] = NULL;
    1641             : 
    1642           0 :     label[2].text = (unichar_t *) _("_Size:");
    1643           0 :     label[2].text_is_1byte = true;
    1644           0 :     label[2].text_in_resource = true;
    1645           0 :     gcd[2].gd.label = &label[2];
    1646           0 :     gcd[2].gd.pos.x = 210; gcd[2].gd.pos.y = gcd[0].gd.pos.y+6; 
    1647           0 :     gcd[2].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1648           0 :     if ( isprint )
    1649           0 :         gcd[2].gd.popup_msg = (unichar_t *) _("Select some text, this specifies the point\nsize of those characters");
    1650             :     else
    1651           0 :         gcd[2].gd.popup_msg = (unichar_t *) _("Select some text, this specifies the vertical\nsize of those characters in em-units");
    1652           0 :     gcd[2].gd.cid = CID_SizeLab;
    1653           0 :     gcd[2].creator = GLabelCreate;
    1654           0 :     harray[0] = &gcd[2];
    1655             : 
    1656           0 :     if ( bestbdf !=NULL && ( !hasfreetype || sf->onlybitmaps ))
    1657           0 :         sprintf( buf, "%d", bestbdf->pixelsize );
    1658             :     else
    1659           0 :         strcpy(buf,"12");
    1660           0 :     label[3].text = (unichar_t *) buf;
    1661           0 :     label[3].text_is_1byte = true;
    1662           0 :     gcd[3].gd.label = &label[3];
    1663           0 :     gcd[3].gd.pos.x = 240; gcd[3].gd.pos.y = gcd[0].gd.pos.y+3; 
    1664           0 :     gcd[3].gd.pos.width = 40;
    1665           0 :     gcd[3].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1666           0 :     gcd[3].gd.cid = CID_Size;
    1667           0 :     gcd[3].gd.handle_controlevent = DSP_SizeChanged;
    1668           0 :     gcd[3].gd.popup_msg = (unichar_t *) _("Select some text, this specifies the pixel\nsize of those characters");
    1669           0 :     gcd[3].creator = GNumericFieldCreate;
    1670           0 :     harray[1] = &gcd[3]; harray[2] = GCD_HPad10;
    1671             : 
    1672           0 :     label[1].text = (unichar_t *) _("_AA");
    1673           0 :     label[1].text_is_1byte = true;
    1674           0 :     label[1].text_in_resource = true;
    1675           0 :     gcd[1].gd.label = &label[1];
    1676           0 :     gcd[1].gd.pos.x = 170; gcd[1].gd.pos.y = gcd[0].gd.pos.y+3; 
    1677           0 :     gcd[1].gd.flags = gg_visible | gg_enabled | gg_cb_on | gg_utf8_popup;
    1678           0 :     if ( sf->bitmaps!=NULL && ( !hasfreetype || sf->onlybitmaps ))
    1679           0 :         gcd[1].gd.flags = DSP_AAState(sf,bestbdf);
    1680           0 :     if ( !isprint )
    1681           0 :         gcd[1].gd.flags = gg_enabled | gg_cb_on | gg_utf8_popup;
    1682           0 :     gcd[1].gd.popup_msg = (unichar_t *) _("Select some text, this controls whether those characters will be\nAntiAlias (greymap) characters, or bitmap characters");
    1683           0 :     gcd[1].gd.handle_controlevent = DSP_AAChange;
    1684           0 :     gcd[1].gd.cid = CID_AA;
    1685           0 :     gcd[1].creator = GCheckBoxCreate;
    1686           0 :     harray[3] = &gcd[1]; harray[4] = GCD_Glue; harray[5] = NULL;
    1687             : 
    1688           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
    1689           0 :     boxes[2].gd.u.boxelements = harray;
    1690           0 :     boxes[2].creator = GHBoxCreate;
    1691           0 :     varray[2] = &boxes[2]; varray[3] = NULL;
    1692             : 
    1693           0 :     label[4].text = (unichar_t *) "pfb";
    1694           0 :     label[4].text_is_1byte = true;
    1695           0 :     gcd[4].gd.label = &label[4];
    1696           0 :     gcd[4].gd.pos.x = gcd[0].gd.pos.x; gcd[4].gd.pos.y = 24+gcd[3].gd.pos.y; 
    1697           0 :     gcd[4].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1698           0 :     gcd[4].gd.cid = CID_pfb;
    1699           0 :     gcd[4].gd.handle_controlevent = DSP_RadioSet;
    1700           0 :     gcd[4].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1701           0 :     gcd[4].creator = GRadioCreate;
    1702           0 :     if ( sf->subfontcnt!=0 || !hasfreetype || sf->onlybitmaps || sf->strokedfont || sf->multilayer ) gcd[4].gd.flags = gg_visible| gg_utf8_popup;
    1703           0 :     farray[0] = &gcd[4];
    1704             : 
    1705           0 :     label[5].text = (unichar_t *) "ttf";
    1706           0 :     label[5].text_is_1byte = true;
    1707           0 :     gcd[5].gd.label = &label[5];
    1708           0 :     gcd[5].gd.pos.x = 46; gcd[5].gd.pos.y = gcd[4].gd.pos.y; 
    1709           0 :     gcd[5].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1710           0 :     gcd[5].gd.cid = CID_ttf;
    1711           0 :     gcd[5].gd.handle_controlevent = DSP_RadioSet;
    1712           0 :     gcd[5].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1713           0 :     gcd[5].creator = GRadioCreate;
    1714           0 :     if ( sf->subfontcnt!=0 || !hasfreetype || sf->onlybitmaps || sf->strokedfont || sf->multilayer ) gcd[5].gd.flags = gg_visible| gg_utf8_popup;
    1715           0 :     else if ( sf->layers[ly_fore].order2 ) gcd[5].gd.flags |= gg_cb_on;
    1716           0 :     farray[1] = &gcd[5];
    1717             : 
    1718           0 :     label[6].text = (unichar_t *) "otf";
    1719           0 :     label[6].text_is_1byte = true;
    1720           0 :     gcd[6].gd.label = &label[6];
    1721           0 :     gcd[6].gd.pos.x = 114; gcd[6].gd.pos.y = gcd[4].gd.pos.y; 
    1722           0 :     gcd[6].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1723           0 :     gcd[6].gd.cid = CID_otf;
    1724           0 :     gcd[6].gd.handle_controlevent = DSP_RadioSet;
    1725           0 :     gcd[6].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1726           0 :     gcd[6].creator = GRadioCreate;
    1727           0 :     if ( !hasfreetype || sf->onlybitmaps || sf->strokedfont || sf->multilayer ) gcd[6].gd.flags = gg_visible| gg_utf8_popup;
    1728           0 :     else if ( sf->subfontcnt!=0 || !sf->layers[ly_fore].order2 ) gcd[6].gd.flags |= gg_cb_on;
    1729           0 :     farray[2] = &gcd[6];
    1730             : 
    1731           0 :     label[7].text = (unichar_t *) _("nohints");
    1732           0 :     label[7].text_is_1byte = true;
    1733           0 :     gcd[7].gd.label = &label[7];
    1734           0 :     gcd[7].gd.pos.x = 114; gcd[7].gd.pos.y = gcd[4].gd.pos.y; 
    1735           0 :     gcd[7].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1736           0 :     gcd[7].gd.cid = CID_nohints;
    1737           0 :     gcd[7].gd.handle_controlevent = DSP_RadioSet;
    1738           0 :     gcd[7].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1739           0 :     gcd[7].creator = GRadioCreate;
    1740           0 :     if ( !hasfreetype || sf->onlybitmaps ) gcd[7].gd.flags = gg_visible| gg_utf8_popup;
    1741           0 :     else if ( sf->strokedfont || sf->multilayer ) gcd[7].gd.flags |= gg_cb_on;
    1742           0 :     farray[3] = &gcd[7];
    1743             :     
    1744             : 
    1745           0 :     label[8].text = (unichar_t *) "bitmap";
    1746           0 :     label[8].text_is_1byte = true;
    1747           0 :     gcd[8].gd.label = &label[8];
    1748           0 :     gcd[8].gd.pos.x = 148; gcd[8].gd.pos.y = gcd[4].gd.pos.y; 
    1749           0 :     gcd[8].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1750           0 :     gcd[8].gd.cid = CID_bitmap;
    1751           0 :     gcd[8].gd.handle_controlevent = DSP_RadioSet;
    1752           0 :     gcd[8].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1753           0 :     gcd[8].creator = GRadioCreate;
    1754           0 :     if ( sf->bitmaps==NULL ) gcd[8].gd.flags = gg_visible| gg_utf8_popup;
    1755           0 :     else if ( sf->onlybitmaps ) gcd[8].gd.flags |= gg_cb_on;
    1756           0 :     farray[4] = &gcd[8];
    1757             : 
    1758           0 :     label[9].text = (unichar_t *) "FontForge";
    1759           0 :     label[9].text_is_1byte = true;
    1760           0 :     gcd[9].gd.label = &label[9];
    1761           0 :     gcd[9].gd.pos.x = 200; gcd[9].gd.pos.y = gcd[4].gd.pos.y; 
    1762           0 :     gcd[9].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1763           0 :     gcd[9].gd.cid = CID_pfaedit;
    1764           0 :     gcd[9].gd.handle_controlevent = DSP_RadioSet;
    1765           0 :     gcd[9].gd.popup_msg = (unichar_t *) _("Specifies file format used to pass the font to freetype\n  pfb -- is the standard postscript type1\n  ttf -- is truetype\n  otf -- is opentype\n  nohints -- freetype rasterizes without hints\n  bitmap -- not passed to freetype for rendering\n    bitmap fonts must already be generated\n  FontForge -- uses FontForge's own rasterizer, not\n    freetype's. Only as last resort");
    1766           0 :     gcd[9].creator = GRadioCreate;
    1767           0 :     if ( sf->onlybitmaps ) gcd[9].gd.flags = gg_visible | gg_utf8_popup;
    1768           0 :     if ( !hasfreetype && sf->bitmaps==NULL ) gcd[9].gd.flags |= gg_cb_on;
    1769           0 :     else if ( sf->onlybitmaps ) gcd[9].gd.flags = gg_visible| gg_utf8_popup;
    1770           0 :     farray[5] = &gcd[9]; farray[6] = GCD_Glue; farray[7] = NULL;
    1771             : 
    1772           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
    1773           0 :     boxes[3].gd.u.boxelements = farray;
    1774           0 :     boxes[3].creator = GHBoxCreate;
    1775           0 :     varray[4] = &boxes[3]; varray[5] = NULL;
    1776           0 :     if ( !isprint ) {
    1777             :         int k;
    1778           0 :         for ( k=4; k<=9; ++k )
    1779           0 :             gcd[k].gd.flags &= ~gg_visible;
    1780           0 :         boxes[3].gd.flags = gg_enabled;
    1781             :     }
    1782             : 
    1783           0 :     label[10].text = (unichar_t *) "DFLT{dflt}";
    1784           0 :     label[10].text_is_1byte = true;
    1785           0 :     gcd[10].gd.label = &label[10];
    1786           0 :     gcd[10].gd.popup_msg = (unichar_t *) _("Select some text, then use this list to specify\nthe current script & language.");
    1787           0 :     gcd[10].gd.pos.x = 12; gcd[10].gd.pos.y = 6; 
    1788           0 :     gcd[10].gd.pos.width = 150;
    1789           0 :     gcd[10].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1790           0 :     gcd[10].gd.cid = CID_ScriptLang;
    1791           0 :     gcd[10].gd.u.list = active->scriptlangs = SLOfFont(sf);
    1792           0 :     gcd[10].gd.handle_controlevent = DSP_ScriptLangChanged;
    1793           0 :     gcd[10].creator = GListFieldCreate;
    1794           0 :     varray[6] = GCD_Glue; varray[7] = NULL;
    1795           0 :     varray[8] = &gcd[10]; varray[9] = NULL; varray[10] = NULL;
    1796             : 
    1797           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
    1798           0 :     boxes[4].gd.u.boxelements = varray;
    1799           0 :     boxes[4].creator = GHVBoxCreate;
    1800           0 :     harray2[1] = &boxes[4];
    1801             : 
    1802           0 :     gcd[11].gd.popup_msg = (unichar_t *) _("Select some text, then use this list to specify\nactive features.");
    1803           0 :     gcd[11].gd.pos.width = 50;
    1804           0 :     gcd[11].gd.flags = gg_visible | gg_enabled | gg_utf8_popup | gg_list_alphabetic | gg_list_multiplesel;
    1805           0 :     gcd[11].gd.cid = CID_Features;
    1806           0 :     gcd[11].gd.handle_controlevent = DSP_FeaturesChanged;
    1807           0 :     gcd[11].creator = GListCreate;
    1808           0 :     harray2[0] = &gcd[11];
    1809             : 
    1810           0 :     label[12].image = &GIcon_menudelta;
    1811           0 :     gcd[12].gd.label = &label[12];
    1812           0 :     gcd[12].gd.popup_msg = (unichar_t *) _("Menu");
    1813           0 :     gcd[12].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1814           0 :     gcd[12].gd.handle_controlevent = DSP_Menu;
    1815           0 :     gcd[12].creator = GButtonCreate;
    1816             : 
    1817           0 :     varray6[0] = GCD_Glue; varray6[1] = &gcd[12]; varray6[2] = NULL;
    1818           0 :     vbox.gd.flags = gg_enabled|gg_visible;
    1819           0 :     vbox.gd.u.boxelements = varray6;
    1820           0 :     vbox.creator = GVBoxCreate;
    1821             : 
    1822           0 :     harray2[2] = &vbox; harray2[3] = GCD_Glue; harray2[4] = NULL;
    1823             : 
    1824           0 :     boxes[5].gd.flags = gg_enabled|gg_visible;
    1825           0 :     boxes[5].gd.u.boxelements = harray2;
    1826           0 :     boxes[5].creator = GHBoxCreate;
    1827           0 :     varray2[0] = &boxes[5]; varray2[1] = NULL;
    1828             : 
    1829             : 
    1830           0 :     gcd[13].gd.pos.x = 5; gcd[13].gd.pos.y = 20+gcd[13].gd.pos.y; 
    1831           0 :     gcd[13].gd.pos.width = 400; gcd[13].gd.pos.height = 236; 
    1832           0 :     gcd[13].gd.flags = gg_visible | gg_enabled | gg_textarea_wrap | gg_text_xim;
    1833           0 :     gcd[13].gd.handle_controlevent = DSP_TextChanged;
    1834           0 :     gcd[13].gd.cid = CID_SampleText;
    1835           0 :     gcd[13].creator = SFTextAreaCreate;
    1836           0 :     varray2[2] = &gcd[13]; varray2[3] = NULL;
    1837             : 
    1838           0 :     gcd[14].gd.flags = gg_visible | gg_enabled ;
    1839           0 :     gcd[14].creator = GLineCreate;
    1840           0 :     varray2[4] = &gcd[14]; varray2[5] = NULL;
    1841             : 
    1842           0 :     label[15].text = (unichar_t *) _("DPI:");
    1843           0 :     label[15].text_is_1byte = true;
    1844           0 :     gcd[15].gd.label = &label[15];
    1845           0 :     gcd[15].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1846           0 :     gcd[15].gd.popup_msg = (unichar_t *) _("Specifies screen dots per inch");
    1847           0 :     gcd[15].creator = GLabelCreate;
    1848             : 
    1849           0 :     if ( lastdpi==0 )
    1850           0 :         lastdpi = GDrawPointsToPixels(NULL,72);
    1851           0 :     dpi = lastdpi;
    1852           0 :     sprintf( dpibuf, "%d", dpi );
    1853           0 :     label[16].text = (unichar_t *) dpibuf;
    1854           0 :     label[16].text_is_1byte = true;
    1855           0 :     gcd[16].gd.label = &label[16];
    1856           0 :     gcd[16].gd.pos.width = 50;
    1857           0 :     gcd[16].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1858           0 :     gcd[16].gd.popup_msg = (unichar_t *) _("Specifies screen dots per inch");
    1859           0 :     gcd[16].gd.cid = CID_DPI;
    1860           0 :     gcd[16].gd.handle_controlevent = DSP_DpiChanged;
    1861           0 :     gcd[16].creator = GNumericFieldCreate;
    1862             : 
    1863           0 :     regenarray[0] = &gcd[15]; regenarray[1] = &gcd[16]; regenarray[2] = GCD_Glue;
    1864           0 :     if ( isprint ) {
    1865           0 :         gcd[17].gd.flags = gg_visible | gg_enabled | gg_utf8_popup ;
    1866           0 :         gcd[17].gd.popup_msg = (unichar_t *) _("FontForge does not update this window when a change is made to the font.\nIf a font has changed press the button to force an update");
    1867           0 :         label[17].text = (unichar_t *) _("_Refresh");
    1868           0 :         label[17].text_is_1byte = true;
    1869           0 :         label[17].text_in_resource = true;
    1870           0 :         gcd[17].gd.label = &label[17];
    1871           0 :         gcd[17].gd.handle_controlevent = DSP_Refresh;
    1872           0 :         gcd[17].creator = GButtonCreate;
    1873           0 :         regenarray[3] = &gcd[17]; regenarray[4] = NULL;
    1874             :     } else {
    1875           0 :         label[17].text = (unichar_t *) _("Text Width:    0");
    1876           0 :         label[17].text_is_1byte = true;
    1877           0 :         gcd[17].gd.label = &label[17];
    1878           0 :         gcd[17].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1879           0 :         gcd[17].gd.cid = CID_ActualWidth;
    1880           0 :         gcd[17].creator = GLabelCreate;
    1881             : 
    1882           0 :         label[18].text = (unichar_t *) _("Wrap Pos:");
    1883           0 :         label[18].text_is_1byte = true;
    1884           0 :         gcd[18].gd.label = &label[18];
    1885           0 :         gcd[18].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1886           0 :         gcd[18].gd.popup_msg = (unichar_t *) _("The text will wrap to a new line after this many em-units");
    1887           0 :         gcd[18].creator = GLabelCreate;
    1888             : 
    1889           0 :         sprintf( widthbuf, "%d", width );
    1890           0 :         label[19].text = (unichar_t *) widthbuf;
    1891           0 :         label[19].text_is_1byte = true;
    1892           0 :         gcd[19].gd.label = &label[19];
    1893           0 :         gcd[19].gd.pos.width = 50;
    1894           0 :         gcd[19].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1895           0 :         gcd[19].gd.popup_msg = (unichar_t *) _("The text will wrap to a new line after this many em-units");
    1896           0 :         gcd[19].gd.cid = CID_TextWidth;
    1897           0 :         gcd[19].gd.handle_controlevent = DSP_WidthChanged;
    1898           0 :         gcd[19].creator = GNumericFieldCreate;
    1899           0 :         regenarray[3] = &gcd[17]; regenarray[4] = GCD_Glue;
    1900           0 :         regenarray[5] = &gcd[18]; regenarray[6] = &gcd[19]; regenarray[7] = NULL;
    1901           0 :         gcd[13].gd.pos.width = GDrawPixelsToPoints(NULL,width*dpi/72) + _GScrollBar_Width+4;
    1902             :     }
    1903             : 
    1904           0 :     boxes[12].gd.flags = gg_enabled|gg_visible;
    1905           0 :     boxes[12].gd.u.boxelements = regenarray;
    1906           0 :     boxes[12].creator = GHBoxCreate;
    1907           0 :     varray2[6] = &boxes[12]; varray2[7] = NULL; varray2[8] = NULL;
    1908             : 
    1909           0 :     boxes[6].gd.flags = gg_enabled|gg_visible;
    1910           0 :     boxes[6].gd.u.boxelements = varray2;
    1911           0 :     boxes[6].creator = GHVBoxCreate;
    1912             : 
    1913           0 :     if ( isprint ) {
    1914           0 :         memset(aspects,0,sizeof(aspects));
    1915           0 :         aspects[0].text = (unichar_t *) _("Display");
    1916           0 :         aspects[0].text_is_1byte = true;
    1917           0 :         aspects[0].gcd = &boxes[6];
    1918             : 
    1919           0 :         plabel[0].text = (unichar_t *) _("_Full Font Display");
    1920           0 :         plabel[0].text_is_1byte = true;
    1921           0 :         plabel[0].text_in_resource = true;
    1922           0 :         pgcd[0].gd.label = &plabel[0];
    1923           0 :         pgcd[0].gd.pos.x = 12; pgcd[0].gd.pos.y = 6; 
    1924           0 :         pgcd[0].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1925           0 :         pgcd[0].gd.cid = CID_Display;
    1926           0 :         pgcd[0].gd.handle_controlevent = PRT_RadioSet;
    1927           0 :         pgcd[0].gd.popup_msg = (unichar_t *) _("Displays all the glyphs in the font on a rectangular grid at the given point size");
    1928           0 :         pgcd[0].creator = GRadioCreate;
    1929           0 :         varray3[0][0] = GCD_HPad10; varray3[0][1] = &pgcd[0]; varray3[0][2] = GCD_Glue; varray3[0][3] = NULL;
    1930             : 
    1931           0 :         cnt = 1;
    1932           0 :         if ( fv!=NULL )
    1933           0 :             cnt = FVSelCount(fv);
    1934           0 :         else if ( mv!=NULL )
    1935           0 :             cnt = mv->glyphcnt;
    1936           0 :         plabel[1].text = (unichar_t *) (cnt==1?_("Full Pa_ge Glyph"):_("Full Pa_ge Glyphs"));
    1937           0 :         plabel[1].text_is_1byte = true;
    1938           0 :         plabel[1].text_in_resource = true;
    1939           0 :         pgcd[1].gd.label = &plabel[1];
    1940           0 :         pgcd[1].gd.flags = (cnt==0 ? (gg_visible | gg_utf8_popup ): (gg_visible | gg_enabled | gg_utf8_popup));
    1941           0 :         pgcd[1].gd.cid = CID_Chars;
    1942           0 :         pgcd[1].gd.handle_controlevent = PRT_RadioSet;
    1943           0 :         pgcd[1].gd.popup_msg = (unichar_t *) _("Displays all the selected characters, each on its own page, at an extremely large point size");
    1944           0 :         pgcd[1].creator = GRadioCreate;
    1945           0 :         varray3[1][0] = GCD_HPad10; varray3[1][1] = &pgcd[1]; varray3[1][2] = GCD_Glue; varray3[1][3] = NULL;
    1946             : 
    1947           0 :         plabel[2].text = (unichar_t *) (cnt==1?_("_Multi Size Glyph"):_("_Multi Size Glyphs"));
    1948           0 :         plabel[2].text_is_1byte = true;
    1949           0 :         plabel[2].text_in_resource = true;
    1950           0 :         pgcd[2].gd.label = &plabel[2];
    1951           0 :         pgcd[2].gd.flags = pgcd[1].gd.flags;
    1952           0 :         pgcd[2].gd.cid = CID_MultiSize;
    1953           0 :         pgcd[2].gd.handle_controlevent = PRT_RadioSet;
    1954           0 :         pgcd[2].gd.popup_msg = (unichar_t *) _("Displays all the selected characters, at several different point sizes");
    1955           0 :         pgcd[2].creator = GRadioCreate;
    1956             : 
    1957           0 :         if ( pdefs[fromwindow].pt==pt_chars && cnt==0 )
    1958           0 :             pdefs[fromwindow].pt = pt_fontdisplay;
    1959           0 :         if ( pdefs[fromwindow].pt == pt_fontsample )
    1960           0 :             pgcd[pt_fontdisplay].gd.flags |= gg_cb_on;
    1961             :         else
    1962           0 :             pgcd[pdefs[fromwindow].pt].gd.flags |= gg_cb_on;
    1963             : 
    1964           0 :         varray3[2][0] = GCD_HPad10; varray3[2][1] = &pgcd[2]; varray3[2][2] = GCD_Glue; varray3[2][3] = NULL;
    1965           0 :         varray3[3][0] = NULL;
    1966             : 
    1967           0 :         boxes[13].gd.flags = gg_enabled|gg_visible;
    1968           0 :         boxes[13].gd.u.boxelements = varray3[0];
    1969           0 :         boxes[13].creator = GHVBoxCreate;
    1970             : 
    1971           0 :         plabel[3].text = (unichar_t *) _("_Pointsize:");
    1972           0 :         plabel[3].text_is_1byte = true;
    1973           0 :         plabel[3].text_in_resource = true;
    1974           0 :         pgcd[3].gd.label = &plabel[3];
    1975           0 :         pgcd[3].gd.flags = gg_visible | gg_enabled;
    1976           0 :         pgcd[3].gd.cid = CID_PSLab;
    1977           0 :         pgcd[3].creator = GLabelCreate;
    1978           0 :         ptarray[0] = &pgcd[3];
    1979             : 
    1980           0 :         sprintf(sizebuf,"%d",active->pi.pointsize);
    1981           0 :         plabel[4].text = (unichar_t *) sizebuf;
    1982           0 :         plabel[4].text_is_1byte = true;
    1983           0 :         pgcd[4].gd.label = &plabel[4];
    1984           0 :         pgcd[4].gd.pos.width = 60;
    1985           0 :         pgcd[4].gd.flags = gg_visible | gg_enabled;
    1986           0 :         pgcd[4].gd.cid = CID_PointSize;
    1987           0 :         pgcd[4].creator = GNumericFieldCreate;
    1988           0 :         ptarray[1] = &pgcd[4]; ptarray[2] = GCD_Glue; ptarray[3] = NULL;
    1989             : 
    1990           0 :         boxes[8].gd.flags = gg_enabled|gg_visible;
    1991           0 :         boxes[8].gd.u.boxelements = ptarray;
    1992           0 :         boxes[8].creator = GHBoxCreate;
    1993             : 
    1994           0 :         varray4[0] = &boxes[13]; varray4[1] = &boxes[8]; varray4[2] = GCD_Glue; varray4[3] = NULL;
    1995           0 :         boxes[9].gd.flags = gg_enabled|gg_visible;
    1996           0 :         boxes[9].gd.u.boxelements = varray4;
    1997           0 :         boxes[9].creator = GVBoxCreate;
    1998             : 
    1999           0 :         aspects[1].text = (unichar_t *) _("Print");
    2000           0 :         aspects[1].text_is_1byte = true;
    2001           0 :         aspects[1].gcd = &boxes[9];
    2002             : 
    2003           0 :         mgcd[0].gd.pos.x = 4; mgcd[0].gd.pos.y = 6;
    2004           0 :         mgcd[0].gd.u.tabs = aspects;
    2005           0 :         mgcd[0].gd.flags = gg_visible | gg_enabled;
    2006           0 :         mgcd[0].gd.cid = CID_TabSet;
    2007           0 :         mgcd[0].creator = GTabSetCreate;
    2008             : 
    2009           0 :         mgcd[1].gd.pos.width = -1; mgcd[1].gd.pos.height = 0;
    2010           0 :         mgcd[1].gd.flags = gg_visible | gg_enabled ;
    2011           0 :         mlabel[1].text = (unichar_t *) _("S_etup");
    2012           0 :         mlabel[1].text_is_1byte = true;
    2013           0 :         mlabel[1].text_in_resource = true;
    2014           0 :         mgcd[1].gd.label = &mlabel[1];
    2015           0 :         mgcd[1].gd.handle_controlevent = PRT_Setup;
    2016           0 :         mgcd[1].creator = GButtonCreate;
    2017           0 :         barray[0] = GCD_Glue; barray[1] = &mgcd[1]; barray[2] = GCD_Glue; barray[3] = NULL;
    2018             : 
    2019           0 :         boxes[14].gd.flags = gg_enabled|gg_visible;
    2020           0 :         boxes[14].gd.u.boxelements = barray;
    2021           0 :         boxes[14].creator = GHBoxCreate;
    2022             : 
    2023           0 :         mgcd[2].gd.pos.width = -1; mgcd[2].gd.pos.height = 0;
    2024           0 :         mgcd[2].gd.flags = gg_visible | gg_enabled | gg_but_default;
    2025           0 :         mlabel[2].text = (unichar_t *) _("_Print");
    2026           0 :         mlabel[2].text_is_1byte = true;
    2027           0 :         mlabel[2].text_in_resource = true;
    2028           0 :         mgcd[2].gd.mnemonic = 'O';
    2029           0 :         mgcd[2].gd.label = &mlabel[2];
    2030           0 :         mgcd[2].gd.handle_controlevent = PRT_OK;
    2031           0 :         mgcd[2].gd.cid = CID_OK;
    2032           0 :         mgcd[2].creator = GButtonCreate;
    2033             : 
    2034           0 :         mgcd[3].gd.pos.width = -1; mgcd[3].gd.pos.height = 0;
    2035           0 :         mgcd[3].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    2036           0 :         mlabel[3].text = (unichar_t *) _("_Done");
    2037           0 :         mlabel[3].text_is_1byte = true;
    2038           0 :         mlabel[3].text_in_resource = true;
    2039           0 :         mgcd[3].gd.label = &mlabel[3];
    2040           0 :         mgcd[3].gd.cid = CID_Cancel;
    2041           0 :         mgcd[3].gd.handle_controlevent = DSP_Done;
    2042           0 :         mgcd[3].creator = GButtonCreate;
    2043           0 :         barray2[0] = GCD_Glue; barray2[1] = &mgcd[2]; barray2[2] = GCD_Glue;
    2044           0 :         barray2[3] = GCD_Glue; barray2[4] = &mgcd[3]; barray2[5] = GCD_Glue; barray2[6] = NULL;
    2045             : 
    2046           0 :         boxes[11].gd.flags = gg_enabled|gg_visible;
    2047           0 :         boxes[11].gd.u.boxelements = barray2;
    2048           0 :         boxes[11].creator = GHBoxCreate;
    2049             : 
    2050           0 :         varray5[0][0] = &mgcd[0]; varray5[0][1] = NULL;
    2051           0 :         varray5[1][0] = &boxes[14]; varray5[1][1] = NULL;
    2052           0 :         varray5[2][0] = &boxes[11]; varray5[2][1] = NULL;
    2053           0 :         varray5[3][0] = NULL;
    2054             : 
    2055           0 :         boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    2056           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
    2057           0 :         boxes[0].gd.u.boxelements = varray5[0];
    2058           0 :         boxes[0].gd.cid = CID_TopBox;
    2059           0 :         boxes[0].creator = GHVGroupCreate;
    2060             :     } else {
    2061           0 :         tarray[0] = &boxes[6]; tarray[1] = NULL;
    2062             : 
    2063           0 :         tgcd[0].gd.flags = fit_to_path==NULL ? gg_visible : (gg_visible | gg_enabled | gg_cb_on);
    2064           0 :         tlabel[0].text = (unichar_t *) _("Bind to Path");
    2065           0 :         tlabel[0].text_is_1byte = true;
    2066           0 :         tlabel[0].text_in_resource = true;
    2067           0 :         tgcd[0].gd.label = &tlabel[0];
    2068           0 :         tgcd[0].gd.handle_controlevent = PRT_Bind;
    2069           0 :         tgcd[0].gd.cid = CID_Bind;
    2070           0 :         tgcd[0].creator = GCheckBoxCreate;
    2071           0 :         patharray[0] = &tgcd[0]; patharray[1] = GCD_Glue;
    2072             : 
    2073           0 :         if ( fit_to_path==NULL ) {
    2074           0 :             tgcd[1].gd.flags = 0;
    2075           0 :             strcpy(pathlen,"0");
    2076             :         } else {
    2077           0 :             tgcd[1].gd.flags = gg_visible | gg_enabled;
    2078           0 :             sprintf(pathlen, _("Path Length: %g"), PathLength(fit_to_path));
    2079             :         }
    2080           0 :         tlabel[1].text = (unichar_t *) pathlen;
    2081           0 :         tlabel[1].text_is_1byte = true;
    2082           0 :         tlabel[1].text_in_resource = true;
    2083           0 :         tgcd[1].gd.label = &tlabel[1];
    2084           0 :         tgcd[1].creator = GLabelCreate;
    2085           0 :         patharray[2] = &tgcd[1]; patharray[3] = NULL;
    2086             : 
    2087           0 :         boxes[9].gd.flags = gg_enabled|gg_visible;
    2088           0 :         boxes[9].gd.u.boxelements = patharray;
    2089           0 :         boxes[9].creator = GHBoxCreate;
    2090           0 :         tarray[2] = &boxes[9]; tarray[3] = NULL;
    2091             : 
    2092           0 :         tgcd[2].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled | gg_cb_on);
    2093           0 :         tlabel[2].text = (unichar_t *) _("Scale so text width matches path length");
    2094           0 :         tlabel[2].text_is_1byte = true;
    2095           0 :         tlabel[2].text_in_resource = true;
    2096           0 :         tgcd[2].gd.label = &tlabel[2];
    2097           0 :         tgcd[2].gd.cid = CID_Scale;
    2098           0 :         tgcd[2].creator = GCheckBoxCreate;
    2099           0 :         tarray[4] = &tgcd[2]; tarray[5] = NULL;
    2100             : 
    2101           0 :         tgcd[3].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2102           0 :         tlabel[3].text = (unichar_t *) _("Rotate each glyph as a unit");
    2103           0 :         tlabel[3].text_is_1byte = true;
    2104           0 :         tlabel[3].text_in_resource = true;
    2105           0 :         tgcd[3].gd.label = &tlabel[3];
    2106           0 :         tgcd[3].gd.cid = CID_GlyphAsUnit;
    2107           0 :         tgcd[3].creator = GCheckBoxCreate;
    2108           0 :         tarray[6] = &tgcd[3]; tarray[7] = NULL;
    2109             : 
    2110           0 :         tgcd[4].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2111           0 :         tlabel[4].text = (unichar_t *) _("Align:");
    2112           0 :         tlabel[4].text_is_1byte = true;
    2113           0 :         tlabel[4].text_in_resource = true;
    2114           0 :         tgcd[4].gd.label = &tlabel[4];
    2115           0 :         tgcd[4].creator = GLabelCreate;
    2116           0 :         alarray[0] = &tgcd[4];
    2117             : 
    2118           0 :         tgcd[5].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled | gg_cb_on);
    2119           0 :         tlabel[5].text = (unichar_t *) _("At Start");
    2120           0 :         tlabel[5].text_is_1byte = true;
    2121           0 :         tlabel[5].text_in_resource = true;
    2122           0 :         tgcd[5].gd.label = &tlabel[5];
    2123           0 :         tgcd[5].gd.cid = CID_Start;
    2124           0 :         tgcd[5].creator = GRadioCreate;
    2125           0 :         alarray[1] = &tgcd[5];
    2126             : 
    2127           0 :         tgcd[6].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2128           0 :         tlabel[6].text = (unichar_t *) _("Centered");
    2129           0 :         tlabel[6].text_is_1byte = true;
    2130           0 :         tlabel[6].text_in_resource = true;
    2131           0 :         tgcd[6].gd.label = &tlabel[6];
    2132           0 :         tgcd[6].gd.cid = CID_Center;
    2133           0 :         tgcd[6].creator = GRadioCreate;
    2134           0 :         alarray[2] = &tgcd[6];
    2135             : 
    2136           0 :         tgcd[7].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2137           0 :         tlabel[7].text = (unichar_t *) _("At End");
    2138           0 :         tlabel[7].text_is_1byte = true;
    2139           0 :         tlabel[7].text_in_resource = true;
    2140           0 :         tgcd[7].gd.label = &tlabel[7];
    2141           0 :         tgcd[7].gd.cid = CID_End;
    2142           0 :         tgcd[7].creator = GRadioCreate;
    2143           0 :         alarray[3] = &tgcd[7];
    2144           0 :         alarray[4] = GCD_Glue; alarray[5] = NULL;
    2145             : 
    2146           0 :         boxes[8].gd.flags = gg_enabled|gg_visible;
    2147           0 :         boxes[8].gd.u.boxelements = alarray;
    2148           0 :         boxes[8].creator = GHBoxCreate;
    2149           0 :         tarray[8] = &boxes[8]; tarray[9] = NULL;
    2150             : 
    2151           0 :         tgcd[8].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2152           0 :         tlabel[8].text = (unichar_t *) _("Offset text from path by:");
    2153           0 :         tlabel[8].text_is_1byte = true;
    2154           0 :         tlabel[8].text_in_resource = true;
    2155           0 :         tgcd[8].gd.label = &tlabel[8];
    2156           0 :         tgcd[8].creator = GLabelCreate;
    2157           0 :         oarray[0] = &tgcd[8];
    2158             : 
    2159           0 :         tgcd[9].gd.flags = fit_to_path==NULL ? 0 : (gg_visible | gg_enabled);
    2160           0 :         tgcd[9].gd.pos.width = 60;
    2161           0 :         tlabel[9].text = (unichar_t *) "0";
    2162           0 :         tlabel[9].text_is_1byte = true;
    2163           0 :         tlabel[9].text_in_resource = true;
    2164           0 :         tgcd[9].gd.label = &tlabel[9];
    2165           0 :         tgcd[9].gd.cid = CID_YOffset;
    2166           0 :         tgcd[9].creator = GNumericFieldCreate;
    2167           0 :         oarray[1] = &tgcd[9]; oarray[2] = GCD_Glue; oarray[3] = NULL;
    2168             : 
    2169           0 :         boxes[13].gd.flags = gg_enabled|gg_visible;
    2170           0 :         boxes[13].gd.u.boxelements = oarray;
    2171           0 :         boxes[13].creator = GHBoxCreate;
    2172           0 :         tarray[10] = &boxes[13]; tarray[11] = NULL;
    2173             : 
    2174           0 :         tgcd[10].gd.flags = gg_visible | gg_enabled ;
    2175           0 :         tgcd[10].creator = GLineCreate;
    2176           0 :         tarray[12] = &tgcd[10]; tarray[13] = NULL;
    2177             : 
    2178           0 :         tgcd[11].gd.pos.width = -1; tgcd[11].gd.pos.height = 0;
    2179           0 :         tgcd[11].gd.flags = gg_visible | gg_enabled | gg_but_default;
    2180           0 :         tlabel[11].text = (unichar_t *) _("_Insert");
    2181           0 :         tlabel[11].text_is_1byte = true;
    2182           0 :         tlabel[11].text_in_resource = true;
    2183           0 :         tgcd[11].gd.mnemonic = 'O';
    2184           0 :         tgcd[11].gd.label = &tlabel[11];
    2185           0 :         tgcd[11].gd.handle_controlevent = PRT_OK;
    2186           0 :         tgcd[11].gd.cid = CID_OK;
    2187           0 :         tgcd[11].creator = GButtonCreate;
    2188             : 
    2189           0 :         tgcd[12].gd.pos.width = -1; tgcd[12].gd.pos.height = 0;
    2190           0 :         tgcd[12].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    2191           0 :         tlabel[12].text = (unichar_t *) _("_Cancel");
    2192           0 :         tlabel[12].text_is_1byte = true;
    2193           0 :         tlabel[12].text_in_resource = true;
    2194           0 :         tgcd[12].gd.label = &tlabel[12];
    2195           0 :         tgcd[12].gd.cid = CID_Cancel;
    2196           0 :         tgcd[12].gd.handle_controlevent = DSP_Done;
    2197           0 :         tgcd[12].creator = GButtonCreate;
    2198           0 :         barray2[0] = GCD_Glue; barray2[1] = &tgcd[11]; barray2[2] = GCD_Glue;
    2199           0 :         barray2[3] = GCD_Glue; barray2[4] = &tgcd[12]; barray2[5] = GCD_Glue; barray2[6] = NULL;
    2200             : 
    2201           0 :         boxes[11].gd.flags = gg_enabled|gg_visible;
    2202           0 :         boxes[11].gd.u.boxelements = barray2;
    2203           0 :         boxes[11].creator = GHBoxCreate;
    2204           0 :         tarray[14] = &boxes[11]; tarray[15] = NULL; tarray[16] = NULL;
    2205             : 
    2206           0 :         boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    2207           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
    2208           0 :         boxes[0].gd.u.boxelements = tarray;
    2209           0 :         boxes[0].gd.cid = CID_TopBox;
    2210           0 :         boxes[0].creator = GHVGroupCreate;
    2211             :     }
    2212             : 
    2213           0 :     GGadgetsCreate(active->gw,boxes);
    2214           0 :     GListSetSBAlwaysVisible(gcd[11].ret,true);
    2215           0 :     GListSetPopupCallback(gcd[11].ret,MV_FriendlyFeatures);
    2216             : 
    2217           0 :     GTextInfoListFree(gcd[0].gd.u.list);
    2218           0 :     DSP_SetFont(active,true);
    2219           0 :     if ( isprint ) {
    2220           0 :         SFTFSetDPI(gcd[13].ret,dpi);
    2221           0 :         temp = PrtBuildDef(sf,&((SFTextArea *) gcd[13].ret)->li,
    2222             :                 (void (*)(void *, int, uint32, uint32))LayoutInfoInitLangSys);
    2223           0 :         GGadgetSetTitle(gcd[13].ret, temp);
    2224           0 :         free(temp);
    2225             :     } else {
    2226           0 :         active->script_unknown = true;
    2227           0 :         if ( old_bind_text ) {
    2228           0 :             SFTextAreaReplace(gcd[13].ret,old_bind_text);
    2229           0 :             DSP_TextChanged(gcd[13].ret,NULL);
    2230             :         }
    2231             :     }
    2232           0 :     SFTFRegisterCallback(gcd[13].ret,active,DSP_ChangeFontCallback);
    2233             : 
    2234           0 :     GHVBoxSetExpandableRow(boxes[0].ret,0);
    2235           0 :     GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
    2236           0 :     GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
    2237           0 :     GHVBoxSetExpandableRow(boxes[4].ret,gb_expandglue);
    2238           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
    2239           0 :     GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
    2240           0 :     GHVBoxSetExpandableRow(boxes[6].ret,1);
    2241           0 :     GHVBoxSetExpandableCol(boxes[12].ret,gb_expandglue);
    2242           0 :     GHVBoxSetExpandableCol(boxes[11].ret,gb_expandglue);
    2243           0 :     GHVBoxSetExpandableRow(vbox.ret,gb_expandglue);
    2244           0 :     if ( isprint ) {
    2245           0 :         GHVBoxSetExpandableCol(boxes[8].ret,gb_expandglue);
    2246           0 :         GHVBoxSetExpandableRow(boxes[9].ret,gb_expandglue);
    2247           0 :         GHVBoxSetExpandableCol(boxes[13].ret,gb_expandglue);
    2248           0 :         GHVBoxSetExpandableCol(boxes[14].ret,gb_expandglue);
    2249             :     } else {
    2250           0 :         GHVBoxSetExpandableCol(boxes[8].ret,gb_expandglue);
    2251           0 :         GHVBoxSetExpandableRow(boxes[9].ret,gb_expandglue);
    2252           0 :         GHVBoxSetExpandableCol(boxes[13].ret,gb_expandglue);
    2253             :     }
    2254           0 :     GHVBoxFitWindow(boxes[0].ret);
    2255             : 
    2256           0 :     SFTextAreaSelect(gcd[13].ret,0,0);
    2257           0 :     SFTextAreaShow(gcd[13].ret,0);
    2258           0 :     SFTFProvokeCallback(gcd[13].ret);
    2259           0 :     GWidgetIndicateFocusGadget(gcd[13].ret);
    2260             : 
    2261           0 :     GDrawSetVisible(active->gw,true);
    2262           0 :     active->ready = true;
    2263           0 :     if ( !isprint ) {
    2264           0 :         while ( !done )
    2265           0 :             GDrawProcessOneEvent(NULL);
    2266             :     }
    2267             : }
    2268             : 
    2269           0 : void PrintFFDlg(FontView *fv,SplineChar *sc,MetricsView *mv) {
    2270           0 :     _PrintFFDlg(fv,sc,mv,true,NULL,NULL);
    2271           0 : }
    2272             : 
    2273           0 : static SplineSet *OnePathSelected(CharView *cv) {
    2274             :     RefChar *rf;
    2275           0 :     SplineSet *ss, *sel=NULL;
    2276             :     SplinePoint *sp;
    2277             : 
    2278           0 :     for ( ss = cv->b.layerheads[cv->b.drawmode]->splines; ss!=NULL; ss=ss->next ) {
    2279           0 :         for ( sp=ss->first; ; ) {
    2280           0 :             if ( sp->selected ) {
    2281           0 :                 if ( sel==NULL )
    2282           0 :                     sel = ss;
    2283           0 :                 else if ( sel!=ss )
    2284           0 : return( NULL );
    2285             :             }
    2286           0 :             if ( sp->next==NULL )
    2287           0 :         break;
    2288           0 :             sp = sp->next->to;
    2289           0 :             if ( sp==ss->first )
    2290           0 :         break;
    2291           0 :         }
    2292             :     }
    2293           0 :     if ( sel==NULL )
    2294           0 : return( NULL );
    2295             : 
    2296           0 :     for ( rf = cv->b.layerheads[cv->b.drawmode]->refs; rf!=NULL; rf=rf->next ) {
    2297           0 :         if ( rf->selected )
    2298           0 : return( NULL );
    2299             :     }
    2300           0 : return( sel );
    2301             : }
    2302             : 
    2303           0 : void InsertTextDlg(CharView *cv) {
    2304           0 :     _PrintFFDlg(NULL,cv->b.sc,NULL,false,cv,OnePathSelected(cv));
    2305           0 : }
    2306             : 
    2307           0 : void PrintWindowClose(void) {
    2308           0 :     if ( printwindow!=NULL )
    2309           0 :         GDrawDestroyWindow(printwindow->gw);
    2310           0 : }

Generated by: LCOV version 1.10