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