1 /* -*- coding: utf-8 -*- */
2 /* Copyright (C) 2000-2012 by George Williams */
3 /*
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13
14 * The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <fontforge-config.h>
30
31 #include "encoding.h"
32 #include "fontforgeui.h"
33 #include "gfile.h"
34 #include "gicons.h"
35 #include "gio.h"
36 #include "gkeysym.h"
37 #include "gresource.h"
38 #include "macbinary.h"
39 #include "mm.h"
40 #include "namelist.h"
41 #include "psfont.h"
42 #include "savefont.h"
43 #include "splinefill.h"
44 #include "splinesaveafm.h"
45 #include "splineutil.h"
46 #include "tottf.h"
47 #include "ustring.h"
48 #include "utype.h"
49 #include "woff.h"
50
51 #include <locale.h>
52 #include <math.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <time.h>
56 #include <unistd.h>
57
58 int ask_user_for_resolution = true;
59 int old_fontlog=false;
60
61 static int nfnt_warned = false, post_warned = false;
62
63 #define CID_MergeTables 100
64 #define CID_TTC_CFF 101
65 #define CID_Family 2000
66
67 #define CID_AppendFontLog 400
68 #define CID_FontLogBit 401
69 #define CID_Layers 402
70 #define CID_PrependTimestamp 403
71
72 #define CID_OK 1001
73 #define CID_PS_AFM 1002
74 #define CID_PS_PFM 1003
75 #define CID_PS_TFM 1004
76 #define CID_PS_HintSubs 1005
77 #define CID_PS_Flex 1006
78 #define CID_PS_Hints 1007
79 #define CID_PS_Restrict256 1008
80 #define CID_PS_Round 1009
81 #define CID_PS_OFM 1010
82 #define CID_PS_AFMmarks 1011
83 #define CID_TTF_Hints 1101
84 #define CID_TTF_FullPS 1102
85 #define CID_TTF_AppleMode 1103
86 #define CID_TTF_PfEdComments 1104
87 #define CID_TTF_PfEdColors 1105
88 #define CID_TTF_PfEd 1106
89 #define CID_TTF_TeXTable 1107
90 #define CID_TTF_OpenTypeMode 1108
91 #define CID_TTF_OldKern 1109
92 #define CID_TTF_GlyphMap 1110
93 #define CID_TTF_OFM 1111
94 #define CID_TTF_NoMacNames 1112
95 #define CID_TTF_PfEdLookups 1113
96 #define CID_TTF_PfEdGuides 1114
97 #define CID_TTF_PfEdLayers 1115
98 #define CID_FontLog 1116
99 #define CID_TTF_DummyDSIG 1117
100 #define CID_NativeKern 1118
101 #define CID_TTF_OldKernMappedOnly 1119
102 #define CID_TTF_FFTMTable 1120
103
104 struct gfc_data {
105 int done;
106 int sod_done;
107 int sod_which;
108 int sod_invoked;
109 int ret;
110 int family, familycnt;
111 GWindow gw;
112 GGadget *gfc;
113 GGadget *pstype;
114 GGadget *bmptype;
115 GGadget *bmpsizes;
116 GGadget *options;
117 GGadget *rename;
118 GGadget *validate;
119 int ps_flags; /* The ordering of these flags fields is */
120 int sfnt_flags; /* important. We index into them */
121 /* WAS otf_flags */
122 int psotb_flags; /* don't reorder or put junk in between */
123 uint8 optset[3];
124 SplineFont *sf;
125 EncMap *map;
126 int layer;
127 };
128
129 static GTextInfo formattypes[] = {
130 { (unichar_t *) N_("PS Type 1 (Ascii)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
131 { (unichar_t *) N_("PS Type 1 (Binary)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
132 #if __Mac
133 { (unichar_t *) N_("PS Type 1 (Resource)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
134 #else
135 { (unichar_t *) N_("PS Type 1 (MacBin)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
136 #endif
137 { (unichar_t *) N_("PS Type 1 (Multiple)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
138 { (unichar_t *) N_("PS Multiple Master(A)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
139 { (unichar_t *) N_("PS Multiple Master(B)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
140 { (unichar_t *) N_("PS Type 3"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
141 { (unichar_t *) N_("PS Type 0"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
142 { (unichar_t *) N_("PS CID"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
143 /* GT: "CFF (Bare)" means a CFF font without the normal OpenType wrapper */
144 /* GT: CFF is a font format that normally lives inside an OpenType font */
145 /* GT: but it is perfectly meaningful to remove all the OpenType complexity */
146 /* GT: and just leave a bare CFF font */
147 { (unichar_t *) N_("CFF (Bare)"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
148 { (unichar_t *) N_("CFF CID (Bare)"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
149 { (unichar_t *) N_("Type42"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
150 { (unichar_t *) N_("Type11 (CID 2)"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
151 { (unichar_t *) N_("TrueType"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
152 { (unichar_t *) N_("TrueType (Symbol)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
153 #if __Mac
154 { (unichar_t *) N_("TrueType (Resource)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
155 #else
156 { (unichar_t *) N_("TrueType (MacBin)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
157 #endif
158 { (unichar_t *) N_("TrueType (TTC)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
159 { (unichar_t *) N_("TrueType (Mac dfont)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
160 { (unichar_t *) N_("OpenType (CFF)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
161 { (unichar_t *) N_("OpenType (Mac dfont)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
162 { (unichar_t *) N_("OpenType CID"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
163 { (unichar_t *) N_("OpenType CID (dfont)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
164 { (unichar_t *) N_("SVG font"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
165 { (unichar_t *) N_("Unified Font Object (UFO3)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
166 { (unichar_t *) N_("Unified Font Object 2"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
167 { (unichar_t *) N_("Unified Font Object 3"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
168 { (unichar_t *) N_("Web Open Font (WOFF)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
169 { (unichar_t *) N_("Web Open Font (WOFF2)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
170 { (unichar_t *) N_("No Outline Font"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
171 GTEXTINFO_EMPTY
172 };
173 static GTextInfo bitmaptypes[] = {
174 { (unichar_t *) N_("BDF"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
175 { (unichar_t *) N_("In TTF/OTF"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
176 { (unichar_t *) N_("Apple bitmap only sfnt (dfont)"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
177 { (unichar_t *) N_("(faked) MS bitmap only sfnt (ttf)"), NULL, 0, 0, NULL, NULL, 1, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
178 { (unichar_t *) N_("X11 bitmap only sfnt (otb)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
179 #if __Mac
180 { (unichar_t *) N_("NFNT (Resource)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
181 #else
182 { (unichar_t *) N_("NFNT (MacBin)"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
183 #endif
184 /* OS/X doesn't seem to support NFNTs, so there's no point in putting them in a dfont */
185 /* { (unichar_t *) "NFNT (dfont)", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },*/
186 { (unichar_t *) N_("Win FON"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
187 { (unichar_t *) N_("Win FNT"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
188 { (unichar_t *) N_("Palm OS Bitmap"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
189 { (unichar_t *) N_("PS Type3 Bitmap"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
190 { (unichar_t *) N_("No Bitmap Fonts"), NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
191 GTEXTINFO_EMPTY
192 };
193
194 int old_validate = true;
195
196 extern int old_sfnt_flags;
197 extern int old_ps_flags;
198 extern int old_psotb_flags;
199
200 extern int oldformatstate;
201 extern int oldbitmapstate;
202
203 static const char *pfaeditflag = "SplineFontDB:";
204
ParseBitmapSizes(GGadget * g,char * msg,int * err)205 int32 *ParseBitmapSizes(GGadget *g,char *msg,int *err) {
206 const unichar_t *val = _GGadgetGetTitle(g), *pt; unichar_t *end, *end2;
207 int i;
208 int32 *sizes;
209
210 locale_t tmplocale; locale_t oldlocale; // Declare temporary locale storage.
211 switch_to_c_locale(&tmplocale, &oldlocale); // Switch to the C locale temporarily and cache the old locale.
212
213 *err = false;
214 end2 = NULL;
215 for ( i=1, pt = val; (end = u_strchr(pt,',')) || (end2=u_strchr(pt,' ')); ++i ) {
216 if ( end!=NULL && end2!=NULL ) {
217 if ( end2<end ) end = end2;
218 } else if ( end2!=NULL )
219 end = end2;
220 pt = end+1;
221 end2 = NULL;
222 }
223 sizes = malloc((i+1)*sizeof(int32));
224
225 for ( i=0, pt = val; *pt!='\0' ; ) {
226 sizes[i]=rint(u_strtod(pt,&end));
227 if ( msg!=_("Pixel List") )
228 /* No bit depth allowed */;
229 else if ( *end!='@' )
230 sizes[i] |= 0x10000;
231 else
232 sizes[i] |= (u_strtol(end+1,&end,10)<<16);
233 if ( sizes[i]>0 ) ++i;
234 if ( *end!=' ' && *end!=',' && *end!='\0' ) {
235 free(sizes);
236 GGadgetProtest8(msg);
237 *err = true;
238 break;
239 }
240 while ( *end==' ' || *end==',' ) ++end;
241 pt = end;
242 }
243 switch_to_old_locale(&tmplocale, &oldlocale); // Switch to the cached locale.
244 if ( *err )
245 return( NULL );
246 sizes[i] = 0;
247 return( sizes );
248 }
249
OPT_PSHints(GGadget * g,GEvent * e)250 static int OPT_PSHints(GGadget *g, GEvent *e) {
251 if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
252 GWindow gw = GGadgetGetWindow(g);
253 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
254 if ( GGadgetIsChecked(g)) {
255 int which = d->sod_which>1? d->sod_which-1 : d->sod_which;
256 int flags = (&d->ps_flags)[which];
257 /*GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_HintSubs),true);*/
258 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Flex),true);
259 /*GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_HintSubs),!(flags&ps_flag_nohintsubs));*/
260 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Flex),!(flags&ps_flag_noflex));
261 } else {
262 /*GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_HintSubs),false);*/
263 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Flex),false);
264 /*GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_HintSubs),false);*/
265 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Flex),false);
266 }
267 }
268 return( true );
269 }
270
OPT_Applemode(GGadget * g,GEvent * e)271 static int OPT_Applemode(GGadget *g, GEvent *e) {
272 if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
273 GWindow gw = GGadgetGetWindow(g);
274 if ( GGadgetIsChecked(g))
275 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OldKern),false);
276 }
277 return( true );
278 }
279
OPT_OldKern(GGadget * g,GEvent * e)280 static int OPT_OldKern(GGadget *g, GEvent *e) {
281 if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
282 GWindow gw = GGadgetGetWindow(g);
283 if ( GGadgetIsChecked(g))
284 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_AppleMode),false);
285 }
286 return( true );
287 }
288
sod_e_h(GWindow gw,GEvent * event)289 static int sod_e_h(GWindow gw, GEvent *event) {
290 if ( event->type==et_close ) {
291 struct gfc_data *d = GDrawGetUserData(gw);
292 d->sod_done = true;
293 } else if ( event->type == et_char ) {
294 if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
295 help("ui/dialogs/generate.html", "#generate-options");
296 return( true );
297 }
298 return( false );
299 } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
300 struct gfc_data *d = GDrawGetUserData(gw);
301 if ( GGadgetGetCid(event->u.control.g)==CID_OK ) {
302 if ( d->sod_which==0 ) { /* PostScript */
303 d->ps_flags = 0;
304 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_AFM)) )
305 d->ps_flags |= ps_flag_afm;
306 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_AFMmarks)) )
307 d->ps_flags |= ps_flag_afmwithmarks;
308 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_PFM)) )
309 d->ps_flags |= ps_flag_pfm;
310 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_TFM)) )
311 d->ps_flags |= ps_flag_tfm;
312 /*if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_HintSubs)) )*/
313 /*d->ps_flags |= ps_flag_nohintsubs;*/
314 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Flex)) )
315 d->ps_flags |= ps_flag_noflex;
316 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Hints)) )
317 d->ps_flags |= ps_flag_nohints;
318 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Round)) )
319 d->ps_flags |= ps_flag_round;
320 /*if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Restrict256)) )*/
321 /*d->ps_flags |= ps_flag_restrict256;*/
322 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_FontLog)) )
323 d->ps_flags |= ps_flag_outputfontlog;
324 } else if ( d->sod_which==1 || d->sod_which==2 ) { /* Open/TrueType */
325 d->sfnt_flags = 0;
326 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_Hints)) )
327 d->sfnt_flags |= ttf_flag_nohints;
328 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_FullPS)) )
329 d->sfnt_flags |= ttf_flag_shortps;
330 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_AppleMode)) )
331 d->sfnt_flags |= ttf_flag_applemode;
332 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_OpenTypeMode)) )
333 d->sfnt_flags |= ttf_flag_otmode;
334 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_OldKern)) &&
335 !(d->sfnt_flags&ttf_flag_applemode) )
336 d->sfnt_flags |= ttf_flag_oldkern;
337 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_DummyDSIG)) )
338 d->sfnt_flags |= ttf_flag_dummyDSIG;
339 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdComments)) )
340 d->sfnt_flags |= ttf_flag_pfed_comments;
341 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdColors)) )
342 d->sfnt_flags |= ttf_flag_pfed_colors;
343 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdLookups)) )
344 d->sfnt_flags |= ttf_flag_pfed_lookupnames;
345 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdGuides)) )
346 d->sfnt_flags |= ttf_flag_pfed_guides;
347 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdLayers)) )
348 d->sfnt_flags |= ttf_flag_pfed_layers;
349 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_FFTMTable)) )
350 d->sfnt_flags |= ttf_flag_noFFTMtable;
351 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_TeXTable)) )
352 d->sfnt_flags |= ttf_flag_TeXtable;
353 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_GlyphMap)) )
354 d->sfnt_flags |= ttf_flag_glyphmap;
355 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_OFM)) )
356 d->sfnt_flags |= ttf_flag_ofm;
357
358 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_AFM)) )
359 d->sfnt_flags |= ps_flag_afm;
360 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_AFMmarks)) )
361 d->sfnt_flags |= ps_flag_afmwithmarks;
362 /*if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_HintSubs)) )*/
363 /*d->sfnt_flags |= ps_flag_nohintsubs;*/
364 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Flex)) )
365 d->sfnt_flags |= ps_flag_noflex;
366 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Hints)) )
367 d->sfnt_flags |= ps_flag_nohints;
368 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Round)) )
369 d->sfnt_flags |= ps_flag_round;
370
371 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_FontLog)) )
372 d->sfnt_flags |= ps_flag_outputfontlog;
373 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_NativeKern)) )
374 d->sfnt_flags |= ttf_native_kern; // This applies mostly to U. F. O. right now.
375 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_OldKernMappedOnly)) )
376 d->sfnt_flags |= ttf_flag_oldkernmappedonly;
377 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_NoMacNames)) )
378 d->sfnt_flags |= ttf_flag_nomacnames;
379 } else { /* PS + OpenType Bitmap */
380 d->ps_flags = d->psotb_flags = 0;
381 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_AFMmarks)) )
382 d->psotb_flags = d->ps_flags |= ps_flag_afmwithmarks;
383 /*if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_HintSubs)) )*/
384 /*d->psotb_flags = d->ps_flags |= ps_flag_nohintsubs;*/
385 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Flex)) )
386 d->psotb_flags = d->ps_flags |= ps_flag_noflex;
387 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Hints)) )
388 d->psotb_flags = d->ps_flags |= ps_flag_nohints;
389 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_Round)) )
390 d->psotb_flags = d->ps_flags |= ps_flag_round;
391 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_PFM)) )
392 d->psotb_flags = d->ps_flags |= ps_flag_pfm;
393 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_PS_TFM)) )
394 d->psotb_flags = d->ps_flags |= ps_flag_tfm;
395
396 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_FullPS)) )
397 d->psotb_flags |= ttf_flag_shortps;
398 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdComments)) )
399 d->psotb_flags |= ttf_flag_pfed_comments;
400 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdColors)) )
401 d->psotb_flags |= ttf_flag_pfed_colors;
402 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdLookups)) )
403 d->psotb_flags |= ttf_flag_pfed_lookupnames;
404 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdGuides)) )
405 d->psotb_flags |= ttf_flag_pfed_guides;
406 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_PfEdLayers)) )
407 d->psotb_flags |= ttf_flag_pfed_layers;
408 if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_FFTMTable)) )
409 d->psotb_flags |= ttf_flag_noFFTMtable;
410 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_TeXTable)) )
411 d->psotb_flags |= ttf_flag_TeXtable;
412 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_GlyphMap)) )
413 d->psotb_flags |= ttf_flag_glyphmap;
414 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_OFM)) )
415 d->psotb_flags |= ttf_flag_ofm;
416 if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_NoMacNames)) )
417 d->psotb_flags |= ttf_flag_nomacnames;
418 }
419 d->sod_invoked = true;
420 }
421 d->sod_done = true;
422 }
423 return( true );
424 }
425
OptSetDefaults(GWindow gw,struct gfc_data * d,int which,int iscid)426 static void OptSetDefaults(GWindow gw,struct gfc_data *d,int which,int iscid) {
427 int w = which>1 ? which-1 : which;
428 int flags = (&d->ps_flags)[w];
429 int fs = GGadgetGetFirstListSelectedItem(d->pstype);
430 int bf = GGadgetGetFirstListSelectedItem(d->bmptype);
431 /* which==0 => pure postscript */
432 /* which==1 => truetype or bitmap in sfnt wrapper */
433 /* which==2 => opentype (ps) */
434 /* which==3 => generating an sfnt based bitmap only font with a postscript outline font */
435
436 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Hints),!(flags&ps_flag_nohints));
437 /*GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_HintSubs),!(flags&ps_flag_nohintsubs));*/
438 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Flex),!(flags&ps_flag_noflex));
439 /*GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Restrict256),flags&ps_flag_restrict256);*/
440 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Round),flags&ps_flag_round);
441
442 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_AFM),flags&ps_flag_afm);
443 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_AFMmarks),flags&ps_flag_afmwithmarks);
444 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_PFM),(flags&ps_flag_pfm) && !iscid);
445 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_TFM),flags&ps_flag_tfm);
446
447 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_Hints),!(flags&ttf_flag_nohints));
448 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_FullPS),!(flags&ttf_flag_shortps));
449 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OFM),flags&ttf_flag_ofm);
450 if ( d->optset[which] )
451 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_AppleMode),flags&ttf_flag_applemode);
452 else if ( which==0 || which==3 ) /* PostScript */
453 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_AppleMode),false);
454 else
455 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_AppleMode),(flags&ttf_flag_applemode));
456 if ( d->optset[which] )
457 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OpenTypeMode),flags&ttf_flag_otmode);
458 else if ( which==0 ) /* PostScript */
459 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OpenTypeMode),false);
460 else if ( (fs==ff_ttfmacbin || fs==ff_ttfdfont || fs==ff_otfdfont ||
461 fs==ff_otfciddfont || d->family==gf_macfamily || (fs==ff_none && bf==bf_sfnt_dfont)))
462 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OpenTypeMode),false);
463 else
464 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OpenTypeMode),(flags&ttf_flag_otmode));
465
466 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_PfEdComments),flags&ttf_flag_pfed_comments);
467 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_PfEdColors),flags&ttf_flag_pfed_colors);
468 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_PfEdLookups),flags&ttf_flag_pfed_lookupnames);
469 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_PfEdGuides),flags&ttf_flag_pfed_guides);
470 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_PfEdLayers),flags&ttf_flag_pfed_layers);
471 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_FFTMTable),
472 which!=0 && !(flags&ttf_flag_noFFTMtable));
473 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_TeXTable),flags&ttf_flag_TeXtable);
474 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_GlyphMap),flags&ttf_flag_glyphmap);
475 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OldKern),
476 (flags&ttf_flag_oldkern) && !GGadgetIsChecked(GWidgetGetControl(gw,CID_TTF_AppleMode)));
477 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_DummyDSIG),flags&ttf_flag_dummyDSIG);
478 GGadgetSetChecked(GWidgetGetControl(gw,CID_FontLog),flags&ps_flag_outputfontlog);
479 GGadgetSetChecked(GWidgetGetControl(gw,CID_NativeKern),flags&ttf_native_kern);
480 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_OldKernMappedOnly),flags&ttf_flag_oldkernmappedonly);
481 GGadgetSetChecked(GWidgetGetControl(gw,CID_TTF_NoMacNames),flags&ttf_flag_nomacnames);
482
483 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Hints),which!=1);
484 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Flex),which!=1);
485 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Round),which!=1);
486 if ( which!=1 && (flags&ps_flag_nohints)) {
487 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_Flex),false);
488 GGadgetSetChecked(GWidgetGetControl(gw,CID_PS_Flex),false);
489 }
490
491 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_AFM),which!=1);
492 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_AFMmarks),which!=1);
493 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_PFM),which==0 || which==3);
494 GGadgetSetEnabled(GWidgetGetControl(gw,CID_PS_TFM),which==0 || which==3);
495
496 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_Hints),which==1);
497 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_FullPS),which!=0);
498 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_AppleMode),which!=0 && which!=3);
499 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_OpenTypeMode),which!=0 && which!=3);
500 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_OldKern),which!=0 );
501 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_DummyDSIG),which!=0 );
502
503 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEd),which!=0);
504 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdComments),which!=0);
505 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdColors),which!=0);
506 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdLookups),which!=0);
507 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdGuides),which!=0);
508 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdColors),which!=0);
509 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_PfEdLayers),which!=0);
510 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_FFTMTable), which!=0);
511 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_TeXTable),which!=0);
512 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_GlyphMap),which!=0);
513 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_OFM),which!=0);
514
515 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_OldKernMappedOnly),which!=0 );
516 GGadgetSetEnabled(GWidgetGetControl(gw,CID_TTF_NoMacNames),which!=0 );
517
518 d->optset[which] = true;
519 }
520
521 #define OPT_Width 230
522 #define OPT_Height 233
523
SaveOptionsDlg(struct gfc_data * d,int which,int iscid)524 static void SaveOptionsDlg(struct gfc_data *d,int which,int iscid) {
525 int k,fontlog_k,group,group2;
526 GWindow gw;
527 GWindowAttrs wattrs;
528 GGadgetCreateData gcd[36];
529 GTextInfo label[36];
530 GRect pos;
531 GGadgetCreateData *hvarray1[21], *hvarray2[44], *hvarray3[8], *harray[7], *varray[11];
532 GGadgetCreateData boxes[6];
533
534 d->sod_done = false;
535 d->sod_which = which;
536
537 memset(&wattrs,0,sizeof(wattrs));
538 wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
539 wattrs.event_masks = ~(1<<et_charup);
540 wattrs.restrict_input_to_me = 1;
541 wattrs.undercursor = 1;
542 wattrs.cursor = ct_pointer;
543 wattrs.utf8_window_title = _("Options");
544 wattrs.is_dlg = true;
545 pos.x = pos.y = 0;
546 pos.width = GGadgetScale(GDrawPointsToPixels(NULL,OPT_Width));
547 pos.height = GDrawPointsToPixels(NULL,OPT_Height);
548 gw = GDrawCreateTopWindow(NULL,&pos,sod_e_h,d,&wattrs);
549
550 memset(&label,0,sizeof(label));
551 memset(&gcd,0,sizeof(gcd));
552 memset(boxes,0,sizeof(boxes));
553
554 k = 0;
555 gcd[k].gd.pos.x = 2; gcd[k].gd.pos.y = 2;
556 gcd[k].gd.pos.width = pos.width-4; gcd[k].gd.pos.height = pos.height-4;
557 gcd[k].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
558 gcd[k++].creator = GGroupCreate;
559
560 label[k].text = (unichar_t *) U_("PostScript®");
561 label[k].text_is_1byte = true;
562 gcd[k].gd.label = &label[k];
563 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = 5;
564 gcd[k].gd.flags = gg_enabled | gg_visible;
565 gcd[k++].creator = GLabelCreate;
566
567 group = k;
568 gcd[k].gd.pos.x = 4; gcd[k].gd.pos.y = 9;
569 gcd[k].gd.pos.width = OPT_Width-8; gcd[k].gd.pos.height = 72;
570 gcd[k].gd.flags = gg_enabled | gg_visible ;
571 gcd[k++].creator = GGroupCreate;
572
573 gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = 16;
574 gcd[k].gd.flags = gg_visible;
575 label[k].text = (unichar_t *) _("Round");
576 label[k].text_is_1byte = true;
577 gcd[k].gd.popup_msg = _("Do you want to round coordinates to integers (this saves space)?");
578 gcd[k].gd.label = &label[k];
579 gcd[k].gd.cid = CID_PS_Round;
580 gcd[k++].creator = GCheckBoxCreate;
581 hvarray1[0] = &gcd[k-1]; hvarray1[1] = GCD_ColSpan;
582
583 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
584 gcd[k].gd.flags = gg_visible;
585 label[k].text = (unichar_t *) _("Hints");
586 label[k].text_is_1byte = true;
587 gcd[k].gd.popup_msg = _("Do you want the font file to contain PostScript hints?");
588 gcd[k].gd.label = &label[k];
589 gcd[k].gd.handle_controlevent = OPT_PSHints;
590 gcd[k].gd.cid = CID_PS_Hints;
591 gcd[k++].creator = GCheckBoxCreate;
592 hvarray1[5] = &gcd[k-1]; hvarray1[6] = GCD_ColSpan;
593
594 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+4; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
595 gcd[k].gd.flags = gg_visible;
596 label[k].text = (unichar_t *) _("Flex Hints");
597 label[k].text_is_1byte = true;
598 gcd[k].gd.popup_msg = _("Do you want the font file to contain PostScript flex hints?");
599 gcd[k].gd.label = &label[k];
600 gcd[k].gd.cid = CID_PS_Flex;
601 gcd[k++].creator = GCheckBoxCreate;
602 hvarray1[10] = GCD_HPad10; hvarray1[11] = &gcd[k-1];
603 hvarray1[15] = GCD_Glue; hvarray1[16] = GCD_Glue;
604
605 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
606 gcd[k].gd.flags = 0;
607 label[k].text = (unichar_t *) _("Hint Substitution");
608 label[k].text_is_1byte = true;
609 gcd[k].gd.popup_msg = _("Do you want the font file to do hint substitution?");
610 gcd[k].gd.label = &label[k];
611 gcd[k].gd.cid = CID_PS_HintSubs;
612 gcd[k++].creator = GCheckBoxCreate;
613
614 gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
615 gcd[k].gd.flags = 0;
616 label[k].text = (unichar_t *) _("First 256");
617 label[k].text_is_1byte = true;
618 gcd[k].gd.popup_msg = _("Limit the font so that only the glyphs referenced in the first 256 encodings\nwill be included in the file");
619 gcd[k].gd.label = &label[k];
620 gcd[k].gd.cid = CID_PS_Restrict256;
621 gcd[k++].creator = GCheckBoxCreate;
622
623 gcd[k].gd.pos.x = 110; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
624 gcd[k].gd.flags = gg_visible;
625 label[k].text = (unichar_t *) _("Output AFM");
626 label[k].text_is_1byte = true;
627 gcd[k].gd.popup_msg = U_("The AFM file contains metrics information that many word-processors will read when using a PostScript® font.");
628 gcd[k].gd.label = &label[k];
629 gcd[k].gd.cid = CID_PS_AFM;
630 gcd[k++].creator = GCheckBoxCreate;
631 hvarray1[2] = &gcd[k-1]; hvarray1[3] = GCD_ColSpan; hvarray1[4] = NULL;
632
633 gcd[k].gd.pos.x = 112; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
634 gcd[k].gd.flags = gg_visible;
635 label[k].text = (unichar_t *) _("Composites in AFM");
636 label[k].text_is_1byte = true;
637 gcd[k].gd.popup_msg = U_("The AFM format allows some information about composites\n(roughly the same as mark to base anchor classes) to be\nincluded. However it tends to make AFM files huge as it\nis not stored in an efficient manner.");
638 gcd[k].gd.label = &label[k];
639 gcd[k].gd.cid = CID_PS_AFMmarks;
640 gcd[k++].creator = GCheckBoxCreate;
641 hvarray1[7] = GCD_HPad10; hvarray1[8] = &gcd[k-1]; hvarray1[9] = NULL;
642
643 gcd[k].gd.pos.x = gcd[k-2].gd.pos.x; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
644 gcd[k].gd.flags = gg_visible;
645 label[k].text = (unichar_t *) _("Output PFM");
646 label[k].text_is_1byte = true;
647 gcd[k].gd.popup_msg = U_("The PFM file contains information Windows needs to install a PostScript® font.");
648 gcd[k].gd.label = &label[k];
649 gcd[k].gd.cid = CID_PS_PFM;
650 gcd[k++].creator = GCheckBoxCreate;
651 hvarray1[12] = &gcd[k-1]; hvarray1[13] = GCD_ColSpan; hvarray1[14] = NULL;
652
653 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
654 gcd[k].gd.flags = gg_visible;
655 label[k].text = (unichar_t *) _("Output TFM & ENC");
656 label[k].text_is_1byte = true;
657 gcd[k].gd.popup_msg = U_("The tfm and enc files contain information TeX needs to install a PostScript® font.");
658 gcd[k].gd.label = &label[k];
659 gcd[k].gd.cid = CID_PS_TFM;
660 gcd[k++].creator = GCheckBoxCreate;
661 hvarray1[17] = &gcd[k-1]; hvarray1[18] = GCD_ColSpan; hvarray1[19] = NULL;
662 hvarray1[20] = NULL;
663
664 boxes[2].gd.flags = gg_enabled|gg_visible;
665 boxes[2].gd.u.boxelements = hvarray1;
666 boxes[2].gd.label = (GTextInfo *) &gcd[1];
667 boxes[2].creator = GHVGroupCreate;
668
669
670 label[k].text = (unichar_t *) _("SFNT");
671 label[k].text_is_1byte = true;
672 gcd[k].gd.label = &label[k];
673 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[group].gd.pos.y+gcd[group].gd.pos.height+6;
674 gcd[k].gd.flags = gg_enabled | gg_visible;
675 gcd[k++].creator = GLabelCreate;
676
677 group2 = k;
678 gcd[k].gd.pos.x = 4; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+4;
679 gcd[k].gd.pos.width = OPT_Width-8; gcd[k].gd.pos.height = 100;
680 gcd[k].gd.flags = gg_enabled | gg_visible ;
681 gcd[k++].creator = GGroupCreate;
682
683 gcd[k].gd.pos.x = gcd[group+1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+8;
684 gcd[k].gd.flags = gg_visible;
685 label[k].text = (unichar_t *) _("TrueType Hints");
686 label[k].text_is_1byte = true;
687 gcd[k].gd.popup_msg = _("Do you want the font file to contain truetype hints? This will not\ngenerate new instructions, it will just make use of whatever is associated\nwith each character.");
688 gcd[k].gd.label = &label[k];
689 gcd[k].gd.cid = CID_TTF_Hints;
690 gcd[k++].creator = GCheckBoxCreate;
691 hvarray2[0] = &gcd[k-1]; hvarray2[1] = GCD_ColSpan;
692
693 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
694 gcd[k].gd.flags = gg_visible;
695 label[k].text = (unichar_t *) _("PS Glyph Names");
696 label[k].text_is_1byte = true;
697 gcd[k].gd.popup_msg = _("Do you want the font file to contain the names of each glyph in the font?");
698 gcd[k].gd.label = &label[k];
699 gcd[k].gd.cid = CID_TTF_FullPS;
700 gcd[k++].creator = GCheckBoxCreate;
701 hvarray2[5] = &gcd[k-1]; hvarray2[6] = GCD_ColSpan;
702
703 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
704 gcd[k].gd.flags = gg_visible;
705 label[k].text = (unichar_t *) _("Apple");
706 label[k].text_is_1byte = true;
707 gcd[k].gd.popup_msg = _("Apple and MS/Adobe differ about the format of truetype and opentype files\nThis allows you to select which standard to follow for your font.\nThe main differences are:\n The requirements for the 'postscript' name in the name table conflict\n Bitmap data are stored in different tables\n Scaled composite characters are treated differently\n Use of GSUB rather than morx(t)/feat\n Use of GPOS rather than kern/opbd\n Use of GDEF rather than lcar/prop");
708 gcd[k].gd.label = &label[k];
709 gcd[k].gd.cid = CID_TTF_AppleMode;
710 gcd[k].gd.handle_controlevent = OPT_Applemode;
711 gcd[k++].creator = GCheckBoxCreate;
712 hvarray2[10] = &gcd[k-1]; hvarray2[11] = GCD_ColSpan;
713
714 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
715 gcd[k].gd.flags = gg_visible;
716 label[k].text = (unichar_t *) _("OpenType");
717 label[k].text_is_1byte = true;
718 gcd[k].gd.popup_msg = _("Apple and MS/Adobe differ about the format of truetype and opentype files\nThis allows you to select which standard to follow for your font.\nThe main differences are:\n The requirements for the 'postscript' name in the name table conflict\n Bitmap data are stored in different tables\n Scaled composite glyphs are treated differently\n Use of GSUB rather than morx(t)/feat\n Use of GPOS rather than kern/opbd\n Use of GDEF rather than lcar/prop");
719 gcd[k].gd.label = &label[k];
720 gcd[k].gd.cid = CID_TTF_OpenTypeMode;
721 gcd[k++].creator = GCheckBoxCreate;
722 hvarray2[15] = &gcd[k-1]; hvarray2[16] = GCD_ColSpan;
723
724 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+4; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
725 gcd[k].gd.flags = gg_visible;
726 label[k].text = (unichar_t *) _("Old style 'kern'");
727 label[k].text_is_1byte = true;
728 gcd[k].gd.popup_msg = _("Many applications still don't support 'GPOS' kerning.\nIf you want to include both 'GPOS' and old-style 'kern'\ntables set this check box.\nIt may not be set in conjunction with the Apple checkbox.\nThis may confuse other applications though.");
729 gcd[k].gd.label = &label[k];
730 gcd[k].gd.cid = CID_TTF_OldKern;
731 gcd[k].gd.handle_controlevent = OPT_OldKern;
732 gcd[k++].creator = GCheckBoxCreate;
733 hvarray2[20] = GCD_HPad10; hvarray2[21] = &gcd[k-1];
734
735 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+4; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
736 gcd[k].gd.flags = gg_visible;
737 label[k].text = (unichar_t *) _("Dummy 'DSIG'");
738 label[k].text_is_1byte = true;
739 gcd[k].gd.popup_msg = _(
740 "MS uses the presence of a 'DSIG' table to determine whether to use an OpenType\n"
741 "icon for the tt font. FontForge can't generate a useful 'DSIG' table, but it can\n"
742 "generate an empty one with no signature info. A pointless table.");
743 gcd[k].gd.label = &label[k];
744 gcd[k].gd.cid = CID_TTF_DummyDSIG;
745 gcd[k++].creator = GCheckBoxCreate;
746 hvarray2[25] = GCD_HPad10; hvarray2[26] = &gcd[k-1];
747
748 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
749 gcd[k].gd.flags = gg_visible;
750 label[k].text = (unichar_t *) _("Output Glyph Map");
751 label[k].text_is_1byte = true;
752 gcd[k].gd.popup_msg = _("When generating a truetype or opentype font it is occasionally\nuseful to know the mapping between truetype glyph ids and\nglyph names. Setting this option will cause FontForge to\nproduce a file (with extension .g2n) containing those data.");
753 gcd[k].gd.label = &label[k];
754 gcd[k].gd.cid = CID_TTF_GlyphMap;
755 gcd[k++].creator = GCheckBoxCreate;
756 hvarray2[30] = &gcd[k-1]; hvarray2[31] = GCD_ColSpan;
757
758 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
759 gcd[k].gd.flags = gg_visible;
760 label[k].text = (unichar_t *) _("Output OFM & CFG");
761 label[k].text_is_1byte = true;
762 gcd[k].gd.popup_msg = _("The ofm and cfg files contain information Omega needs to process a font.");
763 gcd[k].gd.label = &label[k];
764 gcd[k].gd.cid = CID_TTF_OFM;
765 gcd[k++].creator = GCheckBoxCreate;
766 hvarray2[35] = &gcd[k-1]; hvarray2[36] = GCD_ColSpan;
767
768 gcd[k].gd.pos.x = gcd[group+6].gd.pos.x; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
769 gcd[k].gd.flags = gg_visible;
770 label[k].text = (unichar_t *) _("PfaEdit Table");
771 label[k].text_is_1byte = true;
772 gcd[k].gd.popup_msg = _("The PfaEdit table is an extension to the TrueType format\nand contains various data used by FontForge\n(It should be called the FontForge table,\nbut isn't for historical reasons)");
773 gcd[k].gd.label = &label[k];
774 gcd[k].gd.cid = CID_TTF_PfEd;
775 gcd[k++].creator = GLabelCreate;
776 hvarray2[2] = &gcd[k-1]; hvarray2[3] = GCD_ColSpan; hvarray2[4] = NULL;
777
778 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+2; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y-4;
779 gcd[k].gd.flags = gg_visible;
780 label[k].text = (unichar_t *) _("Save Comments");
781 label[k].text_is_1byte = true;
782 gcd[k].gd.popup_msg = _("Save glyph comments in the PfEd table");
783 gcd[k].gd.label = &label[k];
784 gcd[k].gd.cid = CID_TTF_PfEdComments;
785 gcd[k++].creator = GCheckBoxCreate;
786 hvarray2[7] = GCD_HPad10; hvarray2[8] = &gcd[k-1]; hvarray2[9] = NULL;
787
788 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y-4;
789 gcd[k].gd.flags = gg_visible;
790 label[k].text = (unichar_t *) _("Save Colors");
791 label[k].text_is_1byte = true;
792 gcd[k].gd.popup_msg = _("Save glyph colors in the PfEd table");
793 gcd[k].gd.label = &label[k];
794 gcd[k].gd.cid = CID_TTF_PfEdColors;
795 gcd[k++].creator = GCheckBoxCreate;
796 hvarray2[12] = GCD_HPad10; hvarray2[13] = &gcd[k-1]; hvarray2[14] = NULL;
797
798 gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
799 gcd[k].gd.flags = gg_visible;
800 label[k].text = (unichar_t *) _("Lookup Names");
801 label[k].text_is_1byte = true;
802 gcd[k].gd.popup_msg = _("Preserve the names of the GPOS/GSUB lookups and subtables");
803 gcd[k].gd.label = &label[k];
804 gcd[k].gd.cid = CID_TTF_PfEdLookups;
805 gcd[k++].creator = GCheckBoxCreate;
806 hvarray2[17] = GCD_HPad10; hvarray2[18] = &gcd[k-1]; hvarray2[19] = NULL;
807
808 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
809 gcd[k].gd.flags = gg_visible;
810 label[k].text = (unichar_t *) _("Save Guides");
811 label[k].text_is_1byte = true;
812 gcd[k].gd.popup_msg = _("Save the guidelines in the Guide layer.");
813 gcd[k].gd.label = &label[k];
814 gcd[k].gd.cid = CID_TTF_PfEdGuides;
815 gcd[k++].creator = GCheckBoxCreate;
816 hvarray2[22] = GCD_HPad10; hvarray2[23] = &gcd[k-1]; hvarray2[24] = NULL;
817
818 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
819 gcd[k].gd.flags = gg_visible;
820 label[k].text = (unichar_t *) _("Save Layers");
821 label[k].text_is_1byte = true;
822 gcd[k].gd.popup_msg = _(
823 "Preserve any background and spiro layers.\n"
824 "Also if we output a truetype font from a\n"
825 "cubic database, save the cubic splines.");
826 gcd[k].gd.label = &label[k];
827 gcd[k].gd.cid = CID_TTF_PfEdLayers;
828 gcd[k++].creator = GCheckBoxCreate;
829 hvarray2[27] = GCD_HPad10; hvarray2[28] = &gcd[k-1]; hvarray2[29] = NULL;
830
831 gcd[k].gd.pos.x = gcd[k-3].gd.pos.x; gcd[k].gd.pos.y = gcd[k-5].gd.pos.y;
832 gcd[k].gd.flags = gg_visible;
833 label[k].text = (unichar_t *) _("FFTM Table");
834 label[k].text_is_1byte = true;
835 gcd[k].gd.popup_msg = _("The FFTM table is an extension to the TrueType format\nand contains a series of timestamps defined by FontForge\n");
836 gcd[k].gd.label = &label[k];
837 gcd[k].gd.cid = CID_TTF_FFTMTable;
838 gcd[k++].creator = GCheckBoxCreate;
839 hvarray2[32] = &gcd[k-1]; hvarray2[33] = GCD_ColSpan; hvarray2[34] = NULL;
840
841 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y;
842 gcd[k].gd.flags = gg_visible;
843 label[k].text = (unichar_t *) _("TeX Table");
844 label[k].text_is_1byte = true;
845 gcd[k].gd.popup_msg = _("The TeX table is an extension to the TrueType format\nand the various data you would expect to find in\na tfm file (that isn't already stored elsewhere\nin the ttf file)\n");
846 gcd[k].gd.label = &label[k];
847 gcd[k].gd.cid = CID_TTF_TeXTable;
848 gcd[k++].creator = GCheckBoxCreate;
849 hvarray2[37] = &gcd[k-1]; hvarray2[38] = GCD_ColSpan; hvarray2[39] = NULL;
850 hvarray2[40] = GCD_Glue; hvarray2[41] = GCD_Glue; hvarray2[42] = NULL;
851 hvarray2[43] = NULL;
852
853 boxes[3].gd.flags = gg_enabled|gg_visible;
854 boxes[3].gd.u.boxelements = hvarray2;
855 boxes[3].gd.label = (GTextInfo *) &gcd[group2-1];
856 boxes[3].creator = GHVGroupCreate;
857
858 fontlog_k = k;
859 gcd[k].gd.flags = gg_visible | gg_enabled;
860 label[k].text = (unichar_t *) _("Output FONTLOG.txt");
861 label[k].text_is_1byte = true;
862 gcd[k].gd.popup_msg = _(
863 "The FONTLOG is a text file containing relevant information\n"
864 "about the font including such things as its changelog.\n"
865 "(A general template is available in the OFL FAQ on http://scripts.sil.org/OFL-FAQ_web)\n"
866 "Usage within an open font project is highly recommended but not required.\n"
867 "If your font already contains a fontlog table (see the Element->Font Info)\n"
868 "and you check this box, then the internal fontlog information will be\n"
869 "appended to the file \"FONTLOG.txt\" in the same directory\n"
870 "as the font itself.");
871 gcd[k].gd.label = &label[k];
872 gcd[k].gd.cid = CID_FontLog;
873 gcd[k++].creator = GCheckBoxCreate;
874 hvarray3[0] = &gcd[k-1];
875
876 gcd[k].gd.pos.y = gcd[k-1].gd.pos.y; gcd[k].gd.pos.x = gcd[k-2].gd.pos.x;
877 gcd[k].gd.flags = gg_visible | gg_enabled;
878 label[k].text = (unichar_t *) _("Prefer native kerning");
879 label[k].text_is_1byte = true;
880 gcd[k].gd.popup_msg = _(
881 "Use native kerning structures (instead of a feature file) even when this might lose information.\n");
882 gcd[k].gd.label = &label[k];
883 gcd[k].gd.cid = CID_NativeKern;
884 gcd[k++].creator = GCheckBoxCreate;
885 hvarray3[1] = &gcd[k-1]; hvarray3[2]=NULL;
886
887 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y;
888 gcd[k].gd.flags = gg_visible | gg_enabled;
889 label[k].text = (unichar_t *) _("Windows-compatible \'kern\'");
890 label[k].text_is_1byte = true;
891 gcd[k].gd.popup_msg = _("If the old-style \'kern\' table contains unencoded glyphs\n(or glyphs encoded outside of the BMP), many Windows applications\nwon't have any kerning at all. This option excludes such\nproblematic glyphs from the old-style \'kern\' table.");
892 gcd[k].gd.label = &label[k];
893 gcd[k].gd.cid = CID_TTF_OldKernMappedOnly;
894 gcd[k++].creator = GCheckBoxCreate;
895 hvarray3[3] = &gcd[k-1]; hvarray3[4] = NULL;
896
897 gcd[k].gd.pos.x = gcd[k-1].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y;
898 gcd[k].gd.flags = gg_visible | gg_enabled;
899 label[k].text = (unichar_t *) _("No Mac Names");
900 label[k].text_is_1byte = true;
901 gcd[k].gd.popup_msg = _("Do not add duplicated name entries for legacy Mac platform. These name entries are only needed for some legacy Mac applications.");
902 gcd[k].gd.label = &label[k];
903 gcd[k].gd.cid = CID_TTF_NoMacNames;
904 gcd[k++].creator = GCheckBoxCreate;
905 hvarray3[5] = &gcd[k-1];
906
907 hvarray3[6] = NULL; hvarray3[7] = NULL;
908
909 boxes[4].gd.flags = gg_enabled|gg_visible;
910 boxes[4].gd.u.boxelements = hvarray3;
911 boxes[4].gd.label = NULL;
912 boxes[4].creator = GHVGroupCreate;
913
914 gcd[k].gd.pos.x = 30-3; gcd[k].gd.pos.y = gcd[group2].gd.pos.y+gcd[group2].gd.pos.height+10-3;
915 gcd[k].gd.pos.width = -1;
916 gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
917 label[k].text = (unichar_t *) _("_OK");
918 label[k].text_is_1byte = true;
919 label[k].text_in_resource = true;
920 gcd[k].gd.label = &label[k];
921 gcd[k].gd.cid = CID_OK;
922 gcd[k++].creator = GButtonCreate;
923 harray[0] = GCD_Glue; harray[1] = &gcd[k-1]; harray[2] = GCD_Glue;
924
925 gcd[k].gd.pos.x = -30; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
926 gcd[k].gd.pos.width = -1;
927 gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
928 label[k].text = (unichar_t *) _("_Cancel");
929 label[k].text_is_1byte = true;
930 label[k].text_in_resource = true;
931 gcd[k].gd.label = &label[k];
932 gcd[k++].creator = GButtonCreate;
933 harray[3] = GCD_Glue; harray[4] = &gcd[k-1]; harray[5] = GCD_Glue;
934 harray[6] = NULL;
935
936 boxes[5].gd.flags = gg_enabled|gg_visible;
937 boxes[5].gd.u.boxelements = harray;
938 boxes[5].creator = GHBoxCreate;
939
940 varray[0] = &boxes[2]; varray[1] = NULL;
941 varray[2] = &boxes[3]; varray[3] = NULL;
942 varray[4] = &boxes[4]; varray[5] = NULL;
943 varray[6] = GCD_Glue; varray[7] = NULL;
944 varray[8] = &boxes[5]; varray[9] = NULL;
945 varray[10] = NULL;
946
947 boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
948 boxes[0].gd.flags = gg_enabled|gg_visible;
949 boxes[0].gd.u.boxelements = varray;
950 boxes[0].creator = GHVGroupCreate;
951
952 GGadgetsCreate(gw,boxes);
953 GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
954 GHVBoxSetExpandableCol(boxes[4].ret,gb_expandgluesame);
955 GHVBoxFitWindow(boxes[0].ret);
956
957 OptSetDefaults(gw,d,which,iscid);
958
959 GDrawSetVisible(gw,true);
960 while ( !d->sod_done )
961 GDrawProcessOneEvent(NULL);
962 GDrawDestroyWindow(gw);
963 }
964
br_e_h(GWindow gw,GEvent * event)965 static int br_e_h(GWindow gw, GEvent *event) {
966 if ( event->type==et_close ) {
967 int *done = GDrawGetUserData(gw);
968 *done = -1;
969 } else if ( event->type == et_char ) {
970 return( false );
971 } else if ( event->type == et_map ) {
972 /* Above palettes */
973 GDrawRaise(gw);
974 } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
975 int *done = GDrawGetUserData(gw);
976 if ( GGadgetGetCid(event->u.control.g)==1001 )
977 *done = true;
978 else
979 *done = -1;
980 } else if ( event->type==et_controlevent && event->u.control.subtype == et_textchanged &&
981 GGadgetGetCid(event->u.control.g)==1003 ) {
982 GGadgetSetChecked(GWidgetGetControl(gw,1004),true);
983 }
984 return( true );
985 }
986
AskResolution(int bf,BDFFont * bdf)987 static int AskResolution(int bf,BDFFont *bdf) {
988 GRect pos;
989 static GWindow bdf_gw, fon_gw;
990 GWindow gw;
991 GWindowAttrs wattrs;
992 GGadgetCreateData gcd[10], *varray[22], *harray[7], *harray2[4], boxes[4];
993 GTextInfo label[10];
994 int done=-3;
995 int def_res = -1;
996 char buf[20];
997
998 if ( bdf!=NULL )
999 def_res = bdf->res;
1000
1001 if ( no_windowing_ui )
1002 return( -1 );
1003
1004 gw = bf==bf_bdf ? bdf_gw : fon_gw;
1005 if ( gw==NULL ) {
1006 memset(&wattrs,0,sizeof(wattrs));
1007 wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
1008 wattrs.event_masks = ~(1<<et_charup);
1009 wattrs.restrict_input_to_me = 1;
1010 wattrs.undercursor = 1;
1011 wattrs.cursor = ct_pointer;
1012 wattrs.utf8_window_title = _("BDF Resolution");
1013 wattrs.is_dlg = true;
1014 pos.x = pos.y = 0;
1015 pos.width = GGadgetScale(GDrawPointsToPixels(NULL,150));
1016 pos.height = GDrawPointsToPixels(NULL,130);
1017 gw = GDrawCreateTopWindow(NULL,&pos,br_e_h,&done,&wattrs);
1018 if ( bf==bf_bdf )
1019 bdf_gw = gw;
1020 else
1021 fon_gw = gw;
1022
1023 memset(&label,0,sizeof(label));
1024 memset(&gcd,0,sizeof(gcd));
1025 memset(&boxes,0,sizeof(boxes));
1026
1027 label[0].text = (unichar_t *) _("BDF Resolution");
1028 label[0].text_is_1byte = true;
1029 gcd[0].gd.label = &label[0];
1030 gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 7;
1031 gcd[0].gd.flags = gg_enabled|gg_visible;
1032 gcd[0].creator = GLabelCreate;
1033 harray2[0] = GCD_Glue; harray2[1] = &gcd[0]; harray2[2] = GCD_Glue; harray2[3] = NULL;
1034
1035 boxes[3].gd.flags = gg_enabled|gg_visible;
1036 boxes[3].gd.u.boxelements = harray2;
1037 boxes[3].creator = GHBoxCreate;
1038 varray[0] = &boxes[3]; varray[1] = GCD_ColSpan; varray[2] = NULL;
1039
1040 label[1].text = (unichar_t *) (bf==bf_bdf ? "75" : "96");
1041 label[1].text_is_1byte = true;
1042 gcd[1].gd.label = &label[1];
1043 gcd[1].gd.mnemonic = (bf==bf_bdf ? '7' : '9');
1044 gcd[1].gd.pos.x = 20; gcd[1].gd.pos.y = 13+7;
1045 gcd[1].gd.flags = gg_enabled|gg_visible;
1046 if ( (bf==bf_bdf ? 75 : 96)==def_res )
1047 gcd[1].gd.flags |= gg_cb_on;
1048 gcd[1].gd.cid = 75;
1049 gcd[1].creator = GRadioCreate;
1050 varray[3] = &gcd[1]; varray[4] = GCD_Glue; varray[5] = NULL;
1051
1052 label[2].text = (unichar_t *) (bf==bf_bdf ? "100" : "120");
1053 label[2].text_is_1byte = true;
1054 gcd[2].gd.label = &label[2];
1055 gcd[2].gd.mnemonic = '1';
1056 gcd[2].gd.pos.x = 20; gcd[2].gd.pos.y = gcd[1].gd.pos.y+17;
1057 gcd[2].gd.flags = gg_enabled|gg_visible;
1058 if ( (bf==bf_bdf ? 100 : 120)==def_res )
1059 gcd[2].gd.flags |= gg_cb_on;
1060 gcd[2].gd.cid = 100;
1061 gcd[2].creator = GRadioCreate;
1062 varray[6] = &gcd[2]; varray[7] = GCD_Glue; varray[8] = NULL;
1063
1064 label[3].text = (unichar_t *) _("_Guess");
1065 label[3].text_is_1byte = true;
1066 label[3].text_in_resource = true;
1067 gcd[3].gd.label = &label[3];
1068 gcd[3].gd.pos.x = 20; gcd[3].gd.pos.y = gcd[2].gd.pos.y+17;
1069 gcd[3].gd.flags = gg_enabled|gg_visible;
1070 if ( !((gcd[1].gd.flags|gcd[2].gd.flags)&gg_cb_on) )
1071 gcd[3].gd.flags |= gg_cb_on;
1072 gcd[3].gd.cid = -1;
1073 gcd[3].gd.popup_msg = _("Guess each font's resolution based on its pixel size");
1074 gcd[3].creator = GRadioCreate;
1075 varray[9] = &gcd[3]; varray[10] = GCD_Glue; varray[11] = NULL;
1076
1077 label[4].text = (unichar_t *) _("_Other");
1078 label[4].text_is_1byte = true;
1079 label[4].text_in_resource = true;
1080 gcd[4].gd.label = &label[4];
1081 gcd[4].gd.pos.x = 20; gcd[4].gd.pos.y = gcd[3].gd.pos.y+17;
1082 gcd[4].gd.flags = gg_enabled|gg_visible;
1083 gcd[4].gd.cid = 1004;
1084 gcd[4].creator = GRadioCreate;
1085
1086 label[5].text = (unichar_t *) (bf == bf_bdf ? "96" : "72");
1087 if ( def_res>0 ) {
1088 sprintf( buf, "%d", def_res );
1089 label[5].text = (unichar_t *) buf;
1090 }
1091 label[5].text_is_1byte = true;
1092 gcd[5].gd.label = &label[5];
1093 gcd[5].gd.pos.x = 70; gcd[5].gd.pos.y = gcd[4].gd.pos.y-3; gcd[5].gd.pos.width = 40;
1094 gcd[5].gd.flags = gg_enabled|gg_visible;
1095 gcd[5].gd.cid = 1003;
1096 gcd[5].creator = GTextFieldCreate;
1097 varray[12] = &gcd[4]; varray[13] = &gcd[5]; varray[14] = NULL;
1098 varray[15] = GCD_Glue; varray[16] = GCD_Glue; varray[17] = NULL;
1099
1100 gcd[6].gd.pos.x = 15-3; gcd[6].gd.pos.y = gcd[4].gd.pos.y+24;
1101 gcd[6].gd.pos.width = -1; gcd[6].gd.pos.height = 0;
1102 gcd[6].gd.flags = gg_visible | gg_enabled | gg_but_default;
1103 label[6].text = (unichar_t *) _("_OK");
1104 label[6].text_is_1byte = true;
1105 label[6].text_in_resource = true;
1106 gcd[6].gd.mnemonic = 'O';
1107 gcd[6].gd.label = &label[6];
1108 gcd[6].gd.cid = 1001;
1109 gcd[6].creator = GButtonCreate;
1110 harray[0] = GCD_Glue; harray[1] = &gcd[6]; harray[2] = GCD_Glue;
1111
1112 gcd[7].gd.pos.x = -15; gcd[7].gd.pos.y = gcd[6].gd.pos.y+3;
1113 gcd[7].gd.pos.width = -1; gcd[7].gd.pos.height = 0;
1114 gcd[7].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
1115 label[7].text = (unichar_t *) _("_Cancel");
1116 label[7].text_is_1byte = true;
1117 label[7].text_in_resource = true;
1118 gcd[7].gd.label = &label[7];
1119 gcd[7].gd.mnemonic = 'C';
1120 /*gcd[7].gd.handle_controlevent = CH_Cancel;*/
1121 gcd[7].gd.cid = 1002;
1122 gcd[7].creator = GButtonCreate;
1123 harray[3] = GCD_Glue; harray[4] = &gcd[7]; harray[5] = GCD_Glue;
1124 harray[6] = NULL;
1125
1126 boxes[2].gd.flags = gg_enabled|gg_visible;
1127 boxes[2].gd.u.boxelements = harray;
1128 boxes[2].creator = GHBoxCreate;
1129 varray[18] = &boxes[2]; varray[19] = GCD_ColSpan; varray[20] = NULL;
1130 varray[21] = NULL;
1131
1132 boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
1133 boxes[0].gd.flags = gg_enabled|gg_visible;
1134 boxes[0].gd.u.boxelements = varray;
1135 boxes[0].creator = GHVGroupCreate;
1136
1137 gcd[8].gd.pos.x = 2; gcd[8].gd.pos.y = 2;
1138 gcd[8].gd.pos.width = pos.width-4; gcd[8].gd.pos.height = pos.height-2;
1139 gcd[8].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
1140 gcd[8].creator = GGroupCreate;
1141
1142 GGadgetsCreate(gw,boxes);
1143 GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
1144 GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
1145 } else
1146 GDrawSetUserData(gw,&done);
1147
1148 GWidgetHidePalettes();
1149 GDrawSetVisible(gw,true);
1150 while ( true ) {
1151 done = 0;
1152 while ( !done )
1153 GDrawProcessOneEvent(NULL);
1154 if ( GGadgetIsChecked(GWidgetGetControl(gw,1004)) ) {
1155 int err = false;
1156 int res = GetInt8(gw,1003,_("Other ..."),&err);
1157 if ( res<10 )
1158 GGadgetProtest8( _("_Other"));
1159 else if ( !err ) {
1160 GDrawSetVisible(gw,false);
1161 return( res );
1162 }
1163 continue;
1164 }
1165 GDrawSetVisible(gw,false);
1166 if ( done==-1 )
1167 return( -2 );
1168 if ( GGadgetIsChecked(GWidgetGetControl(gw,75)) )
1169 return( bf == bf_bdf ? 75 : 96 );
1170 if ( GGadgetIsChecked(GWidgetGetControl(gw,100)) )
1171 return( bf == bf_bdf ? 100 : 120 );
1172 /*if ( GGadgetIsChecked(GWidgetGetControl(gw,-1)) )*/
1173 return( -1 );
1174 }
1175 }
1176
SearchDirForWernerFile(char * dir,char * filename)1177 static char *SearchDirForWernerFile(char *dir,char *filename) {
1178 char buffer[1025], buf2[200];
1179 FILE *file;
1180 int good = 0;
1181
1182 if ( dir==NULL || filename==NULL || \
1183 strlen(dir)+strlen(filename)>sizeof(buffer)-2 )
1184 return( NULL );
1185
1186 strcpy(buffer,dir);
1187 strcat(buffer,"/");
1188 strcat(buffer,filename);
1189 if ( (file=fopen(buffer,"r"))==NULL )
1190 return( NULL );
1191 if ( fgets(buf2,sizeof(buf2),file)!=NULL && \
1192 strncmp(buf2,pfaeditflag,strlen(pfaeditflag))==0 )
1193 good = 1;
1194 fclose( file );
1195 if ( good )
1196 return( copy(buffer) );
1197
1198 return( NULL );
1199 }
1200
GFileChooserFilterWernerSFDs(GGadget * g,GDirEntry * ent,const unichar_t * dir)1201 static enum fchooserret GFileChooserFilterWernerSFDs(GGadget *g,GDirEntry *ent,
1202 const unichar_t *dir) {
1203 enum fchooserret ret = GFileChooserDefFilter(g,ent,dir);
1204 char buf2[200];
1205 FILE *file;
1206
1207 if ( ret==fc_show && !ent->isdir ) {
1208 char *filename = malloc(u_strlen(dir)+u_strlen(ent->name)+5);
1209 cu_strcpy(filename,dir);
1210 strcat(filename,"/");
1211 cu_strcat(filename,ent->name);
1212 file = fopen(filename,"r");
1213 if ( file==NULL )
1214 ret = fc_hide;
1215 else {
1216 if ( fgets(buf2,sizeof(buf2),file)==NULL ||
1217 strncmp(buf2,pfaeditflag,strlen(pfaeditflag))==0 )
1218 ret = fc_hide;
1219 fclose(file);
1220 }
1221 free(filename);
1222 }
1223 return( ret );
1224 }
1225
GetWernerSFDFile(SplineFont * sf,EncMap * map)1226 static char *GetWernerSFDFile(SplineFont *sf,EncMap *map) {
1227 char *def=NULL, *ret;
1228 char buffer[100];
1229 int supl = sf->supplement;
1230
1231 for ( supl = sf->supplement; supl<sf->supplement+10 ; ++supl ) {
1232 if ( no_windowing_ui ) {
1233 if ( sf->subfontcnt!=0 ) {
1234 sprintf(buffer,"%.40s-%.40s-%d.sfd", sf->cidregistry,sf->ordering,supl);
1235 def = buffer;
1236 } else if ( strstrmatch(map->enc->enc_name,"big")!=NULL &&
1237 strchr(map->enc->enc_name,'5')!=NULL ) {
1238 if (strstrmatch(map->enc->enc_name,"hkscs")!=NULL )
1239 def = "Big5HKSCS.sfd";
1240 else
1241 def = "Big5.sfd";
1242 } else if ( strstrmatch(map->enc->enc_name,"sjis")!=NULL )
1243 def = "Sjis.sfd";
1244 else if ( strstrmatch(map->enc->enc_name,"Wansung")!=NULL ||
1245 strstrmatch(map->enc->enc_name,"EUC-KR")!=NULL )
1246 def = "Wansung.sfd";
1247 else if ( strstrmatch(map->enc->enc_name,"johab")!=NULL )
1248 def = "Johab.sfd";
1249 else if ( map->enc->is_unicodebmp || map->enc->is_unicodefull )
1250 def = "Unicode.sfd";
1251 }
1252 if ( def!=NULL ) {
1253 ret = SearchDirForWernerFile(".",def);
1254 if ( ret==NULL )
1255 ret = SearchDirForWernerFile(getFontForgeShareDir(),def);
1256 if ( ret!=NULL )
1257 return( ret );
1258 }
1259 if ( sf->subfontcnt!=0 )
1260 break;
1261 }
1262
1263 if ( no_windowing_ui )
1264 return( NULL );
1265
1266 /*if ( def==NULL )*/
1267 def = "*.sfd";
1268 ret = gwwv_open_filename(_("Find Sub Font Definition file"),NULL,"*.sfd",GFileChooserFilterWernerSFDs);
1269 return( ret );
1270 }
1271
AnyRefs(RefChar * refs)1272 static int AnyRefs(RefChar *refs) {
1273 int j;
1274 while ( refs!=NULL ) {
1275 for ( j=0; j<refs->layer_cnt; ++j )
1276 if ( refs->layers[j].splines!=NULL )
1277 return( true );
1278 refs = refs->next;
1279 }
1280 return( false );
1281 }
1282
1283 int will_prepend_timestamp = false;
1284
prepend_timestamp(struct gfc_data * d)1285 static void prepend_timestamp(struct gfc_data *d){
1286
1287 if (d->sf->familyname_with_timestamp)
1288 free(d->sf->familyname_with_timestamp);
1289 d->sf->familyname_with_timestamp = NULL;
1290
1291 if (will_prepend_timestamp){
1292 //prepend "YYMMDDHHMM-"
1293
1294 time_t rawtime;
1295 struct tm * timeinfo;
1296 time(&rawtime);
1297 timeinfo = localtime(&rawtime);
1298 char timestamp[11];
1299 strftime(timestamp, 11, "%y%m%d%H%M", timeinfo);
1300
1301 char* new_name;
1302 char* original_name = (d->sf->familyname) ? d->sf->familyname : d->sf->fontname;
1303 int i;
1304
1305 if (original_name!=NULL){
1306 //if we already have a timestamp prepended, we should remove it before appending a new one
1307 int timestamp_found = (original_name[10]=='-');
1308 for (i=0;i<10;i++)
1309 if (original_name[i]<'0' || original_name[i]>'9')
1310 timestamp_found = false;
1311
1312 if (timestamp_found)
1313 original_name = original_name + 11; //skip previous timestamp
1314
1315 new_name = malloc (sizeof(char) * (strlen(original_name) + 12));
1316 sprintf(new_name, "%s-%s", timestamp, original_name);
1317
1318 d->sf->familyname_with_timestamp = new_name;
1319 }
1320 }
1321 }
1322
DoSave(struct gfc_data * d,unichar_t * path)1323 static void DoSave(struct gfc_data *d,unichar_t *path) {
1324 int err=false;
1325 char *temp;
1326 int32 *sizes=NULL;
1327 int iscid, i;
1328 struct sflist *sfs=NULL, *cur, *last=NULL;
1329 static int psscalewarned=0, ttfscalewarned=0, psfnlenwarned=0;
1330 int flags;
1331 struct sflist *sfl;
1332 char **former;
1333 NameList *rename_to;
1334 GTextInfo *ti = GGadgetGetListItemSelected(d->rename);
1335 char *nlname = u2utf8_copy(ti->text);
1336 extern NameList *force_names_when_saving;
1337 int notdef_pos = SFFindNotdef(d->sf,-1);
1338 int layer = ly_fore;
1339 int likecff;
1340 char *buts[3];
1341
1342 prepend_timestamp(d);
1343
1344 buts[0] = _("_Yes");
1345 buts[1] = _("_No");
1346 buts[2] = NULL;
1347
1348 rename_to = NameListByName(nlname);
1349 free(nlname);
1350 if ( rename_to!=NULL && rename_to->uses_unicode ) {
1351 /* I'll let someone generate a font with utf8 names, but I won't let */
1352 /* them take a font and force it to unicode here. */
1353 ff_post_error(_("Namelist contains non-ASCII names"),_("Glyph names should be limited to characters in the ASCII character set, but there are names in this namelist which use characters outside that range."));
1354 return;
1355 }
1356
1357 for ( i=d->sf->glyphcnt-1; i>=1; --i ) if ( i!=notdef_pos )
1358 if ( d->sf->glyphs[i]!=NULL && strcmp(d->sf->glyphs[i]->name,".notdef")==0 &&
1359 (d->sf->glyphs[i]->layers[ly_fore].splines!=NULL || AnyRefs(d->sf->glyphs[i]->layers[ly_fore].refs )))
1360 break;
1361 if ( i>0 ) {
1362 if ( gwwv_ask(_("Notdef name"),(const char **) buts,0,1,_("The glyph at encoding %d is named \".notdef\" but contains an outline. Because it is called \".notdef\" it will not be included in the generated font. You may give it a new name using Element->Glyph Info. Do you wish to continue font generation (and omit this character)?"),d->map->backmap[i])==1 )
1363 return;
1364 }
1365
1366 if ( d->family==gf_none )
1367 layer = (intpt) GGadgetGetListItemSelected(GWidgetGetControl(d->gw,CID_Layers))->userdata;
1368
1369 temp = u2def_copy(path);
1370 oldformatstate = GGadgetGetFirstListSelectedItem(d->pstype);
1371 iscid = oldformatstate==ff_cid || oldformatstate==ff_cffcid ||
1372 oldformatstate==ff_otfcid || oldformatstate==ff_otfciddfont;
1373 if ( !iscid && (d->sf->cidmaster!=NULL || d->sf->subfontcnt>1)) {
1374 if ( gwwv_ask(_("Not a CID format"),(const char **) buts,0,1,_("You are attempting to save a CID font in a non-CID format. This is ok, but it means that only the current sub-font will be saved.\nIs that what you want?"))==1 )
1375 return;
1376 }
1377 if ( oldformatstate == ff_ttf || oldformatstate==ff_ttfsym ||
1378 oldformatstate==ff_ttfmacbin || oldformatstate==ff_ttfdfont ) {
1379 SplineChar *sc; RefChar *ref;
1380 for ( i=0; i<d->sf->glyphcnt; ++i ) if ( (sc = d->sf->glyphs[i])!=NULL ) {
1381 if ( sc->ttf_instrs_len!=0 && sc->instructions_out_of_date ) {
1382 if ( gwwv_ask(_("Instructions out of date"),(const char **) buts,0,1,_("The truetype instructions on glyph %s are out of date.\nDo you want to proceed anyway?"), sc->name)==1 ) {
1383 CharViewCreate(sc,(FontView *) d->sf->fv,-1);
1384 return;
1385 } else
1386 break;
1387 }
1388 for ( ref=sc->layers[ly_fore].refs; ref!=NULL ; ref=ref->next )
1389 if ( ref->point_match_out_of_date && ref->point_match ) {
1390 if ( gwwv_ask(_("Reference point match out of date"),(const char **) buts,0,1,_("In glyph %s the reference to %s is positioned by point matching, and the point numbers may no longer reflect the original intent.\nDo you want to proceed anyway?"), sc->name, ref->sc->name)==1 ) {
1391 CharViewCreate(sc,(FontView *) d->sf->fv,-1);
1392 return;
1393 } else
1394 goto end_of_loop;
1395 }
1396 }
1397 end_of_loop:;
1398 }
1399
1400 if ( d->sf->os2_version==1 && (oldformatstate>=ff_otf && oldformatstate<=ff_otfciddfont)) {
1401 ff_post_error(_("Bad OS/2 version"), _("OpenType fonts must have a version greater than 1\nUse Element->Font Info->OS/2->Misc to change this."));
1402 return;
1403 }
1404
1405 likecff = 0;
1406 if ( oldformatstate==ff_ttc ) {
1407 likecff = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TTC_CFF));
1408 }
1409
1410 if ( likecff || oldformatstate<=ff_cffcid ||
1411 (oldformatstate>=ff_otf && oldformatstate<=ff_otfciddfont)) {
1412 if ( d->sf->ascent+d->sf->descent!=1000 && !psscalewarned ) {
1413 if ( gwwv_ask(_("Non-standard Em-Size"),(const char **) buts,0,1,_("The convention is that PostScript fonts should have an Em-Size of 1000. But this font has a size of %d. This is not an error, but you might consider altering the Em-Size with the Element->Font Info->General dialog.\nDo you wish to continue to generate your font in spite of this?"),
1414 d->sf->ascent+d->sf->descent)==1 )
1415 return;
1416 psscalewarned = true;
1417 }
1418 if ( (strlen(d->sf->fontname)>31 || (d->sf->familyname!=NULL && strlen(d->sf->familyname)>31)) && !psfnlenwarned ) {
1419 if ( gwwv_ask(_("Bad Font Name"),(const char **) buts,0,1,_("Some versions of Windows will refuse to install postscript fonts if the fontname is longer than 31 characters. Do you want to continue anyway?"))==1 )
1420 return;
1421 psfnlenwarned = true;
1422 }
1423 } else if ( oldformatstate!=ff_none && oldformatstate!=ff_svg &&
1424 oldformatstate!=ff_ufo && oldformatstate!=ff_ufo2 && oldformatstate!=ff_ufo3 ) {
1425 int val = d->sf->ascent+d->sf->descent;
1426 int bit;
1427 for ( bit=0x800000; bit!=0; bit>>=1 )
1428 if ( bit==val )
1429 break;
1430 if ( bit==0 && !ttfscalewarned ) {
1431 if ( gwwv_ask(_("Non-standard Em-Size"),(const char **) buts,0,1,_("The convention is that TrueType fonts should have an Em-Size which is a power of 2. But this font has a size of %d. This is not an error, but you might consider altering the Em-Size with the Element->Font Info->General dialog.\nDo you wish to continue to generate your font in spite of this?"),val)==1 )
1432 return;
1433 ttfscalewarned = true;
1434 }
1435 }
1436
1437 if ( oldformatstate==ff_ttfsym && AlreadyMSSymbolArea(d->sf,d->map))
1438 /* Don't complain */;
1439 else if ( ((oldformatstate<ff_ptype0 && oldformatstate!=ff_multiple) ||
1440 oldformatstate==ff_ttfsym || oldformatstate==ff_cff ) &&
1441 d->map->enc->has_2byte ) {
1442 char *buts[3];
1443 buts[0] = _("_Yes");
1444 buts[1] = _("_Cancel");
1445 buts[2] = NULL;
1446 if ( gwwv_ask(_("Encoding Too Large"),(const char **) buts,0,1,_("Your font has a 2 byte encoding, but you are attempting to save it in a format that only supports one byte encodings. This means that you won't be able to access anything after the first 256 characters without reencoding the font.\n\nDo you want to proceed anyway?"))==1 )
1447 return;
1448 }
1449
1450 oldbitmapstate = GGadgetGetFirstListSelectedItem(d->bmptype);
1451 if ( oldbitmapstate!=bf_none )
1452 sizes = ParseBitmapSizes(d->bmpsizes,_("Pixel List"),&err);
1453 if ( err )
1454 return;
1455 if ( oldbitmapstate==bf_nfntmacbin && oldformatstate!=ff_pfbmacbin && !nfnt_warned ) {
1456 nfnt_warned = true;
1457 ff_post_notice(_("The 'NFNT' bitmap format is obsolete"),_("The 'NFNT' bitmap format is not used under OS/X (though you still need to create a (useless) bitmap font if you are saving a type1 PostScript resource)"));
1458 } else if ( oldformatstate==ff_pfbmacbin &&
1459 (oldbitmapstate!=bf_nfntmacbin || sizes[0]==0)) {
1460 ff_post_error(_("Needs bitmap font"),_("When generating a Mac Type1 resource font, you MUST generate at least one NFNT bitmap font to go with it. If you have not created any bitmaps for this font, cancel this dlg and use the Element->Bitmaps Available command to create one"));
1461 return;
1462 } else if ( oldformatstate==ff_pfbmacbin && !post_warned) {
1463 post_warned = true;
1464 ff_post_notice(_("The 'POST' type1 format is probably deprecated"),_("The 'POST' type1 format is probably deprecated and may not work in future version of the mac."));
1465 }
1466
1467 if ( d->family ) {
1468 cur = chunkalloc(sizeof(struct sflist));
1469 cur->next = NULL;
1470 sfs = last = cur;
1471 cur->sf = d->sf;
1472 cur->map = EncMapCopy(d->map);
1473 cur->sizes = sizes;
1474 for ( i=0; i<d->familycnt; ++i ) {
1475 if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_Family+10*i)) ) {
1476 cur = chunkalloc(sizeof(struct sflist));
1477 last->next = cur;
1478 last = cur;
1479 cur->sf = GGadgetGetUserData(GWidgetGetControl(d->gw,CID_Family+10*i));
1480 if ( oldbitmapstate!=bf_none )
1481 cur->sizes = ParseBitmapSizes(GWidgetGetControl(d->gw,CID_Family+10*i+1),_("Pixel List"),&err);
1482 if ( err ) {
1483 SfListFree(sfs);
1484 return;
1485 }
1486 cur->map = EncMapFromEncoding(cur->sf,d->map->enc);
1487 }
1488 }
1489 } else if ( !d->sf->multilayer && !d->sf->strokedfont && !d->sf->onlybitmaps ) {
1490 if ( oldformatstate == ff_ptype3 || oldformatstate == ff_none )
1491 /* No point in validating type3 fonts */;
1492 else if ( (old_validate = GGadgetIsChecked(d->validate))) {
1493 int vs = SFValidate(d->sf,layer,false);
1494 int mask = VSMaskFromFormat(d->sf,layer,oldformatstate);
1495 int blues = ValidatePrivate(d->sf)& ~pds_missingblue;
1496 if ( (vs&mask) || blues!=0 ) {
1497 const char *rsb[3];
1498 char *errs;
1499 int ret;
1500
1501 rsb[0] = _("_Review");
1502 rsb[1] = _("_Generate");
1503 rsb[2]=NULL;
1504 errs = VSErrorsFromMask(vs&mask,blues);
1505 ret = gwwv_ask(_("Errors detected"),rsb,0,0,_("The font contains errors.\n%sWould you like to review the errors or save the font anyway?"),errs);
1506 free(errs);
1507 if ( ret==0 ) {
1508 d->done = true;
1509 d->ret = false;
1510 SFValidationWindow(d->sf,layer,oldformatstate);
1511 return;
1512 }
1513 /* Ok... they want to proceed */
1514 }
1515 }
1516 }
1517
1518 switch ( d->sod_which ) {
1519 case 0: /* PostScript */
1520 flags = old_ps_flags = d->ps_flags;
1521 break;
1522 case 1: /* TrueType */
1523 flags = old_sfnt_flags = d->sfnt_flags;
1524 break;
1525 case 2: /* OpenType */
1526 flags = old_sfnt_flags = d->sfnt_flags;
1527 break;
1528 case 3: /* PostScript & OpenType bitmaps */
1529 old_ps_flags = d->ps_flags;
1530 flags = old_psotb_flags = d->psotb_flags;
1531 break;
1532 }
1533
1534 former = NULL;
1535 if ( d->family && sfs!=NULL ) {
1536 for ( sfl=sfs; sfl!=NULL; sfl=sfl->next ) {
1537 PrepareUnlinkRmOvrlp(sfl->sf,temp,layer);
1538 if ( rename_to!=NULL && !iscid )
1539 sfl->former_names = SFTemporaryRenameGlyphsToNamelist(sfl->sf,rename_to);
1540 }
1541 } else {
1542 PrepareUnlinkRmOvrlp(d->sf,temp,layer);
1543 if ( rename_to!=NULL && !iscid )
1544 former = SFTemporaryRenameGlyphsToNamelist(d->sf,rename_to);
1545 }
1546
1547 if ( d->family==gf_none ) {
1548 char *wernersfdname = NULL;
1549 char *old_fontlog_contents;
1550 int res = -1;
1551 if ( oldformatstate == ff_multiple )
1552 wernersfdname = GetWernerSFDFile(d->sf,d->map);
1553 if (( oldbitmapstate==bf_bdf || oldbitmapstate==bf_fnt ||
1554 oldbitmapstate==bf_fon ) && ask_user_for_resolution ) {
1555 ff_progress_pause_timer();
1556 res = AskResolution(oldbitmapstate,d->sf->bitmaps);
1557 ff_progress_resume_timer();
1558 }
1559 old_fontlog = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_AppendFontLog));
1560 old_fontlog_contents = NULL;
1561 if ( old_fontlog ) {
1562 char *new = GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_FontLogBit));
1563 if ( new!=NULL && *new!='\0' ) {
1564 old_fontlog_contents=d->sf->fontlog;
1565 if ( d->sf->fontlog==NULL )
1566 d->sf->fontlog = new;
1567 else {
1568 d->sf->fontlog = strconcat3(d->sf->fontlog,"\n\n",new);
1569 free(new);
1570 }
1571 d->sf->changed = true;
1572 }
1573 }
1574 if ( res!=-2 )
1575 err = _DoSave(d->sf,temp,sizes,res,d->map, wernersfdname, layer );
1576 if ( err && old_fontlog ) {
1577 free(d->sf->fontlog);
1578 d->sf->fontlog = old_fontlog_contents;
1579 } else
1580 free( old_fontlog_contents );
1581 free(wernersfdname);
1582 } else if ( d->family == gf_macfamily )
1583 err = !WriteMacFamily(temp,sfs,oldformatstate,oldbitmapstate,flags,layer);
1584 else {
1585 int ttcflags =
1586 (GGadgetIsChecked(GWidgetGetControl(d->gw,CID_MergeTables))?ttc_flag_trymerge:0) |
1587 (GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TTC_CFF))?ttc_flag_cff:0);
1588 err = !WriteTTC(temp,sfs,oldformatstate,oldbitmapstate,flags,layer,ttcflags);
1589 }
1590
1591 if ( d->family && sfs!=NULL ) {
1592 for ( sfl=sfs; sfl!=NULL; sfl=sfl->next ) {
1593 RestoreUnlinkRmOvrlp(sfl->sf,temp,layer);
1594 if ( rename_to!=NULL && !iscid )
1595 SFTemporaryRestoreGlyphNames(sfl->sf,sfl->former_names);
1596 }
1597 } else {
1598 RestoreUnlinkRmOvrlp(d->sf,temp,layer);
1599 if ( rename_to!=NULL && !iscid )
1600 SFTemporaryRestoreGlyphNames(d->sf,former);
1601 }
1602 if ( !iscid )
1603 force_names_when_saving = rename_to;
1604
1605 free(temp);
1606 d->done = !err;
1607 d->ret = !err;
1608 }
1609
GFD_doesnt(GIOControl * gio)1610 static void GFD_doesnt(GIOControl *gio) {
1611 /* The filename the user chose doesn't exist, so everything is happy */
1612 struct gfc_data *d = gio->userdata;
1613 DoSave(d,gio->path);
1614 GFileChooserReplaceIO(d->gfc,NULL);
1615 }
1616
GFD_exists(GIOControl * gio)1617 static void GFD_exists(GIOControl *gio) {
1618 /* The filename the user chose exists, ask user if s/he wants to overwrite */
1619 struct gfc_data *d = gio->userdata;
1620 char *temp;
1621 const char *rcb[3];
1622
1623 rcb[2]=NULL;
1624 rcb[0] = _("_Replace");
1625 rcb[1] = _("_Cancel");
1626
1627 if ( gwwv_ask(_("File Exists"),rcb,0,1,_("File, %s, exists. Replace it?"),
1628 temp = u2utf8_copy(u_GFileNameTail(gio->path)))==0 ) {
1629 DoSave(d,gio->path);
1630 }
1631 free(temp);
1632 GFileChooserReplaceIO(d->gfc,NULL);
1633 }
1634
_GFD_SaveOk(struct gfc_data * d)1635 static void _GFD_SaveOk(struct gfc_data *d) {
1636 GGadget *tf;
1637 unichar_t *ret;
1638 int formatstate = GGadgetGetFirstListSelectedItem(d->pstype);
1639
1640 GFileChooserGetChildren(d->gfc,NULL,NULL,&tf);
1641 if ( *_GGadgetGetTitle(tf)!='\0' ) {
1642 ret = GGadgetGetTitle(d->gfc);
1643 if ( formatstate!=ff_none ) /* are we actually generating an outline font? */
1644 GIOfileExists(GFileChooserReplaceIO(d->gfc,
1645 GIOCreate(ret,d,GFD_exists,GFD_doesnt)));
1646 else
1647 GFD_doesnt(GIOCreate(ret,d,GFD_exists,GFD_doesnt)); /* No point in bugging the user if we aren't doing anything */
1648 free(ret);
1649 }
1650 }
1651
GFD_SaveOk(GGadget * g,GEvent * e)1652 static int GFD_SaveOk(GGadget *g, GEvent *e) {
1653 if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1654 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1655 _GFD_SaveOk(d);
1656 }
1657 return( true );
1658 }
1659
GFD_Cancel(GGadget * g,GEvent * e)1660 static int GFD_Cancel(GGadget *g, GEvent *e) {
1661 if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1662 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1663 d->done = true;
1664 d->ret = false;
1665 }
1666 return( true );
1667 }
1668
GFD_FigureWhich(struct gfc_data * d)1669 static void GFD_FigureWhich(struct gfc_data *d) {
1670 int fs = GGadgetGetFirstListSelectedItem(d->pstype);
1671 int bf = GGadgetGetFirstListSelectedItem(d->bmptype);
1672 int which;
1673 if ( fs==ff_none )
1674 which = 1; /* Some bitmaps get stuffed int ttf files */
1675 else if ( fs<=ff_cffcid )
1676 which = 0; /* PostScript options */
1677 else if ( fs<=ff_ttfdfont )
1678 which = 1; /* truetype options */ /* type42 also */
1679 else
1680 which = 2; /* opentype options */
1681 if ( fs==ff_woff || fs==ff_woff2 ) {
1682 SplineFont *sf = d->sf;
1683 int layer = d->layer;
1684 if ( sf->layers[layer].order2 )
1685 which = 1; /* truetype */
1686 else
1687 which = 2; /* opentype */
1688 }
1689 if ( bf == bf_otb && which==0 )
1690 which = 3; /* postscript options with opentype bitmap options */
1691 d->sod_which = which;
1692 }
1693
GFD_Options(GGadget * g,GEvent * e)1694 static int GFD_Options(GGadget *g, GEvent *e) {
1695 if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1696 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1697 int fs = GGadgetGetFirstListSelectedItem(d->pstype);
1698 int iscid = fs==ff_cid || fs==ff_cffcid || fs==ff_otfcid ||
1699 fs==ff_otfciddfont || fs==ff_type42cid;
1700 GFD_FigureWhich(d);
1701 SaveOptionsDlg(d,d->sod_which,iscid);
1702 }
1703 return( true );
1704 }
1705
GFD_dircreated(GIOControl * gio)1706 static void GFD_dircreated(GIOControl *gio) {
1707 struct gfc_data *d = gio->userdata;
1708 unichar_t *dir = u_copy(gio->path);
1709
1710 GFileChooserReplaceIO(d->gfc,NULL);
1711 GFileChooserSetDir(d->gfc,dir);
1712 free(dir);
1713 }
1714
GFD_dircreatefailed(GIOControl * gio)1715 static void GFD_dircreatefailed(GIOControl *gio) {
1716 /* We couldn't create the directory */
1717 struct gfc_data *d = gio->userdata;
1718 char *temp;
1719
1720 ff_post_notice(_("Couldn't create directory"),_("Couldn't create directory: %s"),
1721 temp = u2utf8_copy(u_GFileNameTail(gio->path)));
1722 free(temp);
1723 GFileChooserReplaceIO(d->gfc,NULL);
1724 }
1725
GFD_NewDir(GGadget * g,GEvent * e)1726 static int GFD_NewDir(GGadget *g, GEvent *e) {
1727 if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1728 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1729 char *newdir;
1730 unichar_t *temp;
1731 newdir = gwwv_ask_string(_("Create directory..."),NULL,_("Directory name?"));
1732 if ( newdir==NULL )
1733 return( true );
1734 if ( !GFileIsAbsolute(newdir)) {
1735 char *olddir = u2utf8_copy(GFileChooserGetDir(d->gfc));
1736 char *temp = GFileAppendFile(olddir,newdir,false);
1737 free(newdir); free(olddir);
1738 newdir = temp;
1739 }
1740 temp = utf82u_copy(newdir);
1741 GIOmkDir(GFileChooserReplaceIO(d->gfc,
1742 GIOCreate(temp,d,GFD_dircreated,GFD_dircreatefailed)));
1743 free(newdir); free(temp);
1744 }
1745 return( true );
1746 }
1747
BitmapName(struct gfc_data * d)1748 static void BitmapName(struct gfc_data *d) {
1749 int bf = GGadgetGetFirstListSelectedItem(d->bmptype);
1750 int format = GGadgetGetFirstListSelectedItem(d->pstype);
1751
1752 if ( bf<0 || format<0 || format!=ff_none )
1753 return;
1754
1755 unichar_t *ret = GGadgetGetTitle(d->gfc);
1756 unichar_t *dup, *pt, *tpt;
1757
1758 dup = malloc((u_strlen(ret)+30)*sizeof(unichar_t));
1759 u_strcpy(dup,ret);
1760 free(ret);
1761 pt = u_strrchr(dup,'.');
1762 tpt = u_strrchr(dup,'/');
1763 if ( pt<tpt )
1764 pt = NULL;
1765 if ( pt==NULL ) pt = dup+u_strlen(dup);
1766 if ( uc_strcmp(pt-5, ".bmap.bin" )==0 ) pt -= 5;
1767 if ( uc_strcmp(pt-4, ".ttf.bin" )==0 ) pt -= 4;
1768 if ( uc_strcmp(pt-4, ".otf.dfont" )==0 ) pt -= 4;
1769 if ( uc_strncmp(pt-2, "%s", 2 )==0 ) pt -= 2;
1770 if ( uc_strncmp(pt-2, "-*", 2 )==0 ) pt -= 2;
1771 uc_strcpy(pt,bitmapextensions[bf]);
1772 GGadgetSetTitle(d->gfc,dup);
1773 free(dup);
1774 }
1775
GFD_Format(GGadget * g,GEvent * e)1776 static int GFD_Format(GGadget *g, GEvent *e) {
1777 if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
1778 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1779 unichar_t *pt, *dup, *tpt, *ret;
1780 int format = GGadgetGetFirstListSelectedItem(d->pstype);
1781 int32 len; int bf;
1782 static unichar_t nullstr[] = { 0 };
1783 GTextInfo **list;
1784 SplineFont *temp;
1785
1786 list = GGadgetGetList(d->bmptype,&len);
1787 temp = d->sf->cidmaster ? d->sf->cidmaster : d->sf;
1788 if ( format==ff_none ) {
1789 if ( temp->bitmaps!=NULL ) {
1790 list[bf_sfnt_dfont]->disabled = false;
1791 list[bf_sfnt_ms]->disabled = false;
1792 list[bf_otb]->disabled = false;
1793 list[bf_ttf]->disabled = true;
1794 }
1795 BitmapName(d);
1796 return( true );
1797 }
1798
1799 ret = GGadgetGetTitle(d->gfc);
1800 dup = malloc((u_strlen(ret)+30)*sizeof(unichar_t));
1801 u_strcpy(dup,ret);
1802 free(ret);
1803 pt = u_strrchr(dup,'.');
1804 tpt = u_strrchr(dup,'/');
1805 if ( pt<tpt )
1806 pt = NULL;
1807 if ( pt==NULL ) pt = dup+u_strlen(dup);
1808 if ( uc_strcmp(pt-5, ".bmap.bin" )==0 ) pt -= 5;
1809 if ( uc_strcmp(pt-4, ".ttf.bin" )==0 ) pt -= 4;
1810 if ( uc_strcmp(pt-4, ".otf.dfont" )==0 ) pt -= 4;
1811 if ( uc_strcmp(pt-4, ".cid.t42" )==0 ) pt -= 4;
1812 if ( uc_strncmp(pt-2, "%s", 2 )==0 ) pt -= 2;
1813 if ( uc_strncmp(pt-2, "-*", 2 )==0 ) pt -= 2;
1814 uc_strcpy(pt,savefont_extensions[format]);
1815 GGadgetSetTitle(d->gfc,dup);
1816 free(dup);
1817
1818 if ( d->sf->cidmaster!=NULL ) {
1819 if ( format!=ff_none && format != ff_cid && format != ff_cffcid &&
1820 format != ff_otfcid && format!=ff_otfciddfont ) {
1821 GGadgetSetTitle(d->bmpsizes,nullstr);
1822 }
1823 }
1824
1825 bf = GGadgetGetFirstListSelectedItem(d->bmptype);
1826 list[bf_sfnt_dfont]->disabled = true;
1827 if ( temp->bitmaps==NULL )
1828 /* Don't worry about what formats are possible, they're disabled */;
1829 else if ( format!=ff_ttf && format!=ff_ttfsym && format!=ff_otf &&
1830 format!=ff_ttfdfont && format!=ff_otfdfont && format!=ff_otfciddfont &&
1831 format!=ff_otfcid && format!=ff_ttfmacbin && format!=ff_none ) {
1832 /* If we're not in a ttf format then we can't output ttf bitmaps */
1833 list[bf_ttf]->disabled = true;
1834 list[bf_sfnt_dfont]->disabled = false;
1835 list[bf_sfnt_ms]->disabled = false;
1836 list[bf_otb]->disabled = false;
1837 if ( bf==bf_ttf )
1838 GGadgetSelectOneListItem(d->bmptype,bf_otb);
1839 if ( format==ff_pfbmacbin )
1840 GGadgetSelectOneListItem(d->bmptype,bf_nfntmacbin);
1841 bf = GGadgetGetFirstListSelectedItem(d->bmptype);
1842 GGadgetSetEnabled(d->bmpsizes, format!=ff_multiple && bf!=bf_none ); /* We know there are bitmaps */
1843 } else {
1844 list[bf_ttf]->disabled = false;
1845 list[bf_sfnt_dfont]->disabled = true;
1846 list[bf_sfnt_ms]->disabled = true;
1847 list[bf_otb]->disabled = true;
1848 if ( bf==bf_none )
1849 /* Do nothing, always appropriate */;
1850 else if ( format==ff_ttf || format==ff_ttfsym || format==ff_otf ||
1851 format==ff_otfcid ||
1852 bf==bf_sfnt_dfont || bf == bf_sfnt_ms || bf == bf_otb )
1853 GGadgetSelectOneListItem(d->bmptype,bf_ttf);
1854 }
1855 #if __Mac
1856 { GGadget *pulldown, *list, *tf;
1857 /* The name of the postscript file is fixed and depends solely on */
1858 /* the font name. If the user tried to change it, the font would */
1859 /* not be found */
1860 /* See MakeMacPSName for a full description */
1861 GFileChooserGetChildren(d->gfc,&pulldown,&list,&tf);
1862 GGadgetSetVisible(tf,format!=ff_pfbmacbin);
1863 }
1864 #endif
1865 GGadgetSetEnabled(d->bmptype, format!=ff_multiple );
1866 }
1867 return( true );
1868 }
1869
GFD_BitmapFormat(GGadget * g,GEvent * e)1870 static int GFD_BitmapFormat(GGadget *g, GEvent *e) {
1871 if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
1872 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1873 /*int format = GGadgetGetFirstListSelectedItem(d->pstype);*/
1874 int bf = GGadgetGetFirstListSelectedItem(d->bmptype);
1875 int i;
1876
1877 GGadgetSetEnabled(d->bmpsizes,bf!=bf_none);
1878 if ( d->family ) {
1879 for ( i=0; i<d->familycnt; ++i )
1880 GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_Family+10*i+1),
1881 bf!=bf_none);
1882 }
1883 BitmapName(d);
1884 }
1885 return( true );
1886 }
1887
GFD_TogglePrependTimestamp(GGadget * g,GEvent * e)1888 static int GFD_TogglePrependTimestamp(GGadget *g, GEvent *e) {
1889 if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
1890 will_prepend_timestamp = GGadgetIsChecked(g);
1891 }
1892 return( true );
1893 }
1894
GFD_ToggleFontLog(GGadget * g,GEvent * e)1895 static int GFD_ToggleFontLog(GGadget *g, GEvent *e) {
1896 if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
1897 struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
1898 static int cids[] = {
1899 CID_FontLogBit,
1900 0 };
1901 int i, visible = GGadgetIsChecked(g);
1902
1903 for ( i=0; cids[i]!=0; ++i )
1904 GGadgetSetVisible(GWidgetGetControl(d->gw,cids[i]),visible);
1905
1906 GWidgetToDesiredSize(d->gw);
1907 }
1908 return( true );
1909 }
1910
e_h(GWindow gw,GEvent * event)1911 static int e_h(GWindow gw, GEvent *event) {
1912 if ( event->type==et_close ) {
1913 struct gfc_data *d = GDrawGetUserData(gw);
1914 d->done = true;
1915 d->ret = false;
1916 } else if ( event->type == et_char ) {
1917 if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
1918 help("ui/dialogs/generate.html", NULL);
1919 return( true );
1920 } else if ( (event->u.chr.keysym=='s' || event->u.chr.keysym=='g' ||
1921 event->u.chr.keysym=='G' ) &&
1922 (event->u.chr.state&ksm_control) ) {
1923 _GFD_SaveOk(GDrawGetUserData(gw));
1924 return( true );
1925 }
1926 return( false );
1927 } else if ( event->type == et_mousemove ||
1928 (event->type==et_mousedown && event->u.mouse.button==3 )) {
1929 struct gfc_data *d = GDrawGetUserData(gw);
1930 if ( !GGadgetWithin(d->gfc,event->u.mouse.x,event->u.mouse.y))
1931 return( false );
1932 GFileChooserPopupCheck(d->gfc,event);
1933 } else if (( event->type==et_mouseup || event->type==et_mousedown ) &&
1934 (event->u.mouse.button>=4 && event->u.mouse.button<=7) ) {
1935 struct gfc_data *d = GDrawGetUserData(gw);
1936 return( GGadgetDispatchEvent((GGadget *) (d->gfc),event));
1937 }
1938 return( true );
1939 }
1940
BitmapList(SplineFont * sf)1941 static unichar_t *BitmapList(SplineFont *sf) {
1942 BDFFont *bdf;
1943 int i;
1944 char *cret, *pt;
1945 unichar_t *uret;
1946
1947 for ( bdf=sf->bitmaps, i=0; bdf!=NULL; bdf=bdf->next, ++i );
1948 pt = cret = malloc((i+1)*20);
1949 for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
1950 if ( pt!=cret ) *pt++ = ',';
1951 if ( bdf->clut==NULL )
1952 sprintf( pt, "%d", bdf->pixelsize );
1953 else
1954 sprintf( pt, "%d@%d", bdf->pixelsize, BDFDepth(bdf) );
1955 pt += strlen(pt);
1956 }
1957 *pt = '\0';
1958 uret = uc_copy(cret);
1959 free(cret);
1960 return( uret );
1961 }
1962
styleName(SplineFont * sf)1963 static const char *styleName(SplineFont *sf) {
1964 int stylecode = MacStyleCode(sf,NULL);
1965
1966 if ( stylecode&sf_bold )
1967 return " Bold";
1968 if ( stylecode&sf_italic )
1969 return " Italic";
1970 if ( stylecode&sf_outline )
1971 return " Outline";
1972 if ( stylecode&sf_shadow )
1973 return " Shadow";
1974 if ( stylecode&sf_condense )
1975 return " Condensed";
1976 if ( stylecode&sf_extend )
1977 return " Extended";
1978 return " Plain";
1979 }
1980
SFUsableLayerNames(SplineFont * sf,int def_layer)1981 static GTextInfo *SFUsableLayerNames(SplineFont *sf,int def_layer) {
1982 int gid, layer, cnt = 1, k, known;
1983 SplineFont *_sf;
1984 SplineChar *sc;
1985 GTextInfo *ti;
1986
1987 for ( layer=0; layer<sf->layer_cnt; ++layer )
1988 sf->layers[layer].ticked = false;
1989 sf->layers[ly_fore].ticked = true;
1990 for ( layer=0; layer<sf->layer_cnt; ++layer ) if ( !sf->layers[layer].background ) {
1991 known = -1;
1992 k = 0;
1993 do {
1994 _sf = sf->subfontcnt==0 ? sf : sf->subfonts[k];
1995 for ( gid = 0; gid<_sf->glyphcnt; ++gid ) if ( (sc=_sf->glyphs[gid])!=NULL ) {
1996 if ( sc->layers[layer].images!=NULL ) {
1997 known = 0;
1998 break;
1999 }
2000 if ( sc->layers[layer].splines!=NULL )
2001 known = 1;
2002 }
2003 ++k;
2004 } while ( known!=0 && k<sf->subfontcnt );
2005 if ( known == 1 ) {
2006 sf->layers[layer].ticked = true;
2007 ++cnt;
2008 } else if ( layer==def_layer )
2009 def_layer = ly_fore;
2010 }
2011
2012 ti = calloc(cnt+1,sizeof(GTextInfo));
2013 cnt=0;
2014 for ( layer=0; layer<sf->layer_cnt; ++layer ) if ( sf->layers[layer].ticked ) {
2015 ti[cnt].text = (unichar_t *) sf->layers[layer].name;
2016 ti[cnt].text_is_1byte = true;
2017 ti[cnt].selected = layer==def_layer;
2018 ti[cnt++].userdata = (void *) (intpt) layer;
2019 }
2020 return( ti );
2021 }
2022
2023 typedef SplineFont *SFArray[48];
2024
SFGenerateFont(SplineFont * sf,int layer,int family,EncMap * map)2025 int SFGenerateFont(SplineFont *sf,int layer,int family,EncMap *map) {
2026 GRect pos;
2027 GWindow gw;
2028 GWindowAttrs wattrs;
2029 GGadgetCreateData gcd[20+2*48+5+1], *varray[13], *hvarray[33], *famarray[3*52+1],
2030 *harray[10], boxes[7];
2031 GTextInfo label[20+2*48+4+1];
2032 struct gfc_data d;
2033 GGadget *pulldown, *files, *tf;
2034 int hvi, i, j, k, f, old, ofs, y, fc, dupfc, dupstyle, rk, vk;
2035 int bs = GIntGetResource(_NUM_Buttonsize), bsbigger, totwid, spacing;
2036 SplineFont *temp;
2037 int familycnt=0;
2038 int fondcnt = 0, fondmax = 10;
2039 SFArray *familysfs=NULL;
2040 uint16 psstyle;
2041 static int done=false;
2042 extern NameList *force_names_when_saving;
2043 char **nlnames;
2044 int cnt, any;
2045 GTextInfo *namelistnames, *lynames=NULL;
2046
2047 memset(&d,'\0',sizeof(d));
2048 d.sf = sf;
2049 d.layer = layer;
2050
2051 if ( !done ) {
2052 done = true;
2053 for ( i=0; formattypes[i].text; ++i )
2054 formattypes[i].text = (unichar_t *) _((char *) formattypes[i].text);
2055 for ( i=0; bitmaptypes[i].text; ++i )
2056 bitmaptypes[i].text = (unichar_t *) _((char *) bitmaptypes[i].text);
2057 }
2058
2059 if ( family==gf_macfamily ) {
2060 old_sfnt_flags |= ttf_flag_applemode;
2061 old_sfnt_flags &= ~ttf_flag_otmode;
2062 }
2063
2064 if ( family ) {
2065 /* I could just disable the menu item, but I think it's a bit confusing*/
2066 /* and I want people to know why they can't generate a family */
2067 FontView *fv;
2068 SplineFont *dup=NULL/*, *badenc=NULL*/;
2069 familysfs = malloc((fondmax=10)*sizeof(SFArray));
2070 memset(familysfs[0],0,sizeof(familysfs[0]));
2071 familysfs[0][0] = sf;
2072 fondcnt = 1;
2073 for ( fv=fv_list; fv!=NULL; fv=(FontView *) (fv->b.next) ) {
2074 if ( fv->b.sf==sf )
2075 continue;
2076 if ( family==gf_ttc ) {
2077 fc = fondcnt;
2078 psstyle = 0;
2079 } else if ( family==gf_macfamily && sf->familyname && fv->b.sf->familyname && strcmp(fv->b.sf->familyname,sf->familyname)==0 ) {
2080 MacStyleCode(fv->b.sf,&psstyle);
2081 if ( fv->b.sf->fondname==NULL ) {
2082 fc = 0;
2083 if ( familysfs[0][0]->fondname==NULL &&
2084 (familysfs[0][psstyle]==NULL || familysfs[0][psstyle]==fv->b.sf))
2085 familysfs[0][psstyle] = fv->b.sf;
2086 else {
2087 for ( fc=0; fc<fondcnt; ++fc ) {
2088 for ( i=0; i<48; ++i )
2089 if ( familysfs[fc][i]!=NULL )
2090 break;
2091 if ( i<48 && familysfs[fc][i]->fondname==NULL &&
2092 familysfs[fc][psstyle]==fv->b.sf )
2093 break;
2094 }
2095 }
2096 } else {
2097 for ( fc=0; fc<fondcnt; ++fc ) {
2098 for ( i=0; i<48; ++i )
2099 if ( familysfs[fc][i]!=NULL )
2100 break;
2101 if ( i<48 && familysfs[fc][i]->fondname!=NULL &&
2102 strcmp(familysfs[fc][i]->fondname,fv->b.sf->fondname)==0 ) {
2103 if ( familysfs[fc][psstyle]==fv->b.sf )
2104 /* several windows may point to same font */;
2105 else if ( familysfs[fc][psstyle]!=NULL ) {
2106 dup = fv->b.sf;
2107 dupstyle = psstyle;
2108 dupfc = fc;
2109 } else
2110 familysfs[fc][psstyle] = fv->b.sf;
2111 break;
2112 }
2113 }
2114 }
2115 }
2116 if ( fc==fondcnt ) {
2117 /* Create a new fond containing just this font */
2118 if ( fondcnt>=fondmax )
2119 familysfs = realloc(familysfs,(fondmax+=10)*sizeof(SFArray));
2120 memset(familysfs[fondcnt],0,sizeof(SFArray));
2121 familysfs[fondcnt++][psstyle] = fv->b.sf;
2122 }
2123 }
2124 if ( family==gf_macfamily ) {
2125 for ( fc=0; fc<fondcnt; ++fc ) for ( i=0; i<48; ++i ) {
2126 if ( familysfs[fc][i]!=NULL ) {
2127 ++familycnt;
2128 }
2129 }
2130 if ( MacStyleCode(sf,NULL)!=0 || familycnt<=1 || sf->multilayer ) {
2131 ff_post_error(_("Bad Mac Family"),_("To generate a Mac family file, the current font must have plain (Normal, Regular, etc.) style, and there must be other open fonts with the same family name."));
2132 return( 0 );
2133 } else if ( dup ) {
2134 MacStyleCode(dup,&psstyle);
2135 ff_post_error(_("Bad Mac Family"),_("There are two open fonts with the current family name and the same style. %.30s and %.30s"),
2136 dup->fontname, familysfs[dupfc][dupstyle]->fontname);
2137 return( 0 );
2138 }
2139 } else {
2140 familycnt = fondcnt;
2141 }
2142 }
2143
2144 memset(&wattrs,0,sizeof(wattrs));
2145 wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
2146 wattrs.event_masks = ~(1<<et_charup);
2147 wattrs.is_dlg = true;
2148 wattrs.restrict_input_to_me = 1;
2149 wattrs.undercursor = 1;
2150 wattrs.cursor = ct_pointer;
2151 {
2152 const char *label = _("Generate Fonts");
2153 switch (family) {
2154 case gf_ttc:
2155 label = _("Generate TTC");
2156 break;
2157 case gf_macfamily:
2158 label = _("Generate Mac Family");
2159 break;
2160 }
2161 wattrs.utf8_window_title = label;
2162 }
2163 pos.x = pos.y = 0;
2164 totwid = GGadgetScale(295);
2165 bsbigger = 4*bs+4*14>totwid; totwid = bsbigger?4*bs+4*12:totwid;
2166 spacing = (totwid-4*bs-2*12)/3;
2167 pos.width = GDrawPointsToPixels(NULL,totwid);
2168 if ( family )
2169 pos.height = GDrawPointsToPixels(NULL,310+13+26*(familycnt-1));
2170 else
2171 pos.height = GDrawPointsToPixels(NULL,310);
2172 gw = GDrawCreateTopWindow(NULL,&pos,e_h,&d,&wattrs);
2173
2174 memset(&label,0,sizeof(label));
2175 memset(&gcd,0,sizeof(gcd));
2176 memset(&boxes,0,sizeof(boxes));
2177 gcd[0].gd.pos.x = 12; gcd[0].gd.pos.y = 6; gcd[0].gd.pos.width = 100*totwid/GIntGetResource(_NUM_ScaleFactor)-24; gcd[0].gd.pos.height = 182;
2178 gcd[0].gd.flags = gg_visible | gg_enabled;
2179 gcd[0].creator = GFileChooserCreate;
2180 varray[0] = &gcd[0]; varray[1] = NULL;
2181
2182 y = 276;
2183 if ( family )
2184 y += 13 + 26*(familycnt-1);
2185
2186 gcd[1].gd.pos.x = 12; gcd[1].gd.pos.y = y-3;
2187 gcd[1].gd.pos.width = -1;
2188 gcd[1].gd.flags = gg_visible | gg_enabled | gg_but_default;
2189 label[1].text = (unichar_t *) _("_Generate");
2190 label[1].text_is_1byte = true;
2191 label[1].text_in_resource = true;
2192 gcd[1].gd.mnemonic = 'S';
2193 gcd[1].gd.label = &label[1];
2194 gcd[1].gd.handle_controlevent = GFD_SaveOk;
2195 gcd[1].creator = GButtonCreate;
2196 harray[0] = GCD_Glue; harray[1] = &gcd[1];
2197
2198 gcd[2].gd.pos.x = -(spacing+bs)*100/GIntGetResource(_NUM_ScaleFactor)-12; gcd[2].gd.pos.y = y;
2199 gcd[2].gd.pos.width = -1;
2200 gcd[2].gd.flags = gg_visible | gg_enabled;
2201 label[2].text = (unichar_t *) _("_Filter");
2202 label[2].text_is_1byte = true;
2203 label[2].text_in_resource = true;
2204 gcd[2].gd.mnemonic = 'F';
2205 gcd[2].gd.label = &label[2];
2206 gcd[2].gd.handle_controlevent = GFileChooserFilterEh;
2207 gcd[2].creator = GButtonCreate;
2208 harray[2] = GCD_Glue; harray[3] = &gcd[2];
2209
2210 gcd[3].gd.pos.x = -12; gcd[3].gd.pos.y = y; gcd[3].gd.pos.width = -1; gcd[3].gd.pos.height = 0;
2211 gcd[3].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
2212 label[3].text = (unichar_t *) _("_Cancel");
2213 label[3].text_is_1byte = true;
2214 label[3].text_in_resource = true;
2215 gcd[3].gd.label = &label[3];
2216 gcd[3].gd.mnemonic = 'C';
2217 gcd[3].gd.handle_controlevent = GFD_Cancel;
2218 gcd[3].creator = GButtonCreate;
2219 harray[6] = GCD_Glue; harray[7] = &gcd[3]; harray[8] = GCD_Glue; harray[9] = NULL;
2220
2221 gcd[4].gd.pos.x = (spacing+bs)*100/GIntGetResource(_NUM_ScaleFactor)+12; gcd[4].gd.pos.y = y; gcd[4].gd.pos.width = -1; gcd[4].gd.pos.height = 0;
2222 gcd[4].gd.flags = gg_visible | gg_enabled;
2223 label[4].text = (unichar_t *) S_("Directory|_New");
2224 label[4].text_is_1byte = true;
2225 label[4].text_in_resource = true;
2226 label[4].image = &_GIcon_dir;
2227 label[4].image_precedes = false;
2228 gcd[4].gd.mnemonic = 'N';
2229 gcd[4].gd.label = &label[4];
2230 gcd[4].gd.handle_controlevent = GFD_NewDir;
2231 gcd[4].creator = GButtonCreate;
2232 harray[4] = GCD_Glue; harray[5] = &gcd[4];
2233
2234 boxes[2].gd.flags = gg_enabled|gg_visible;
2235 boxes[2].gd.u.boxelements = harray;
2236 boxes[2].creator = GHBoxCreate;
2237
2238 gcd[5].gd.pos.x = 12; gcd[5].gd.pos.y = 218; gcd[5].gd.pos.width = 0; gcd[5].gd.pos.height = 0;
2239 gcd[5].gd.flags = gg_visible | gg_enabled;
2240 label[5].text = (unichar_t *) _("Options");
2241 label[5].text_is_1byte = true;
2242 gcd[5].gd.popup_msg = _("Allows you to select optional behavior when generating the font");
2243 gcd[5].gd.label = &label[5];
2244 gcd[5].gd.handle_controlevent = GFD_Options;
2245 gcd[5].creator = GButtonCreate;
2246 hvarray[4] = &gcd[5]; hvarray[5] = GCD_Glue;
2247
2248 gcd[6].gd.pos.x = 12; gcd[6].gd.pos.y = 190; gcd[6].gd.pos.width = 0; gcd[6].gd.pos.height = 0;
2249 gcd[6].gd.flags = gg_visible | gg_enabled ;
2250 gcd[6].gd.u.list = formattypes;
2251 gcd[6].creator = GListButtonCreate;
2252 hvarray[0] = &gcd[6]; hvarray[1] = GCD_ColSpan;
2253
2254 any = false;
2255 for ( i=0; i<sf->glyphcnt; ++i ) if ( SCWorthOutputting(sf->glyphs[i])) {
2256 any = true;
2257 break;
2258 }
2259 for ( i=0; i<sizeof(formattypes)/sizeof(formattypes[0])-1; ++i )
2260 formattypes[i].disabled = !any;
2261 formattypes[ff_ptype0].disabled = sf->onlybitmaps || map->enc->only_1byte;
2262 formattypes[ff_mma].disabled = formattypes[ff_mmb].disabled =
2263 sf->mm==NULL || sf->mm->apple || !MMValid(sf->mm,false);
2264 formattypes[ff_cffcid].disabled = sf->cidmaster==NULL;
2265 formattypes[ff_cid].disabled = sf->cidmaster==NULL;
2266 formattypes[ff_otfcid].disabled = sf->cidmaster==NULL;
2267 formattypes[ff_otfciddfont].disabled = sf->cidmaster==NULL;
2268 if ( map->enc->is_unicodefull )
2269 formattypes[ff_type42cid].disabled = true; /* Identity CMap only handles BMP */
2270 ofs = oldformatstate;
2271 if (( ofs==ff_ptype0 && formattypes[ff_ptype0].disabled ) ||
2272 ((ofs==ff_mma || ofs==ff_mmb) && sf->mm==NULL) ||
2273 ((ofs==ff_cid || ofs==ff_cffcid || ofs==ff_otfcid || ofs==ff_otfciddfont) && formattypes[ff_cid].disabled))
2274 ofs = ff_pfb;
2275 else if ( (ofs!=ff_cid && ofs!=ff_cffcid && ofs!=ff_otfcid && ofs!=ff_otfciddfont) && sf->cidmaster!=NULL )
2276 ofs = ff_otfcid;
2277 else if ( !formattypes[ff_mmb].disabled && ofs!=ff_mma )
2278 ofs = ff_mmb;
2279 if ( ofs==ff_ttc )
2280 ofs = ff_ttf;
2281 if ( sf->onlybitmaps )
2282 ofs = ff_none;
2283 if ( sf->multilayer ) {
2284 formattypes[ff_pfa].disabled = true;
2285 formattypes[ff_pfb].disabled = true;
2286 formattypes[ff_pfbmacbin].disabled = true;
2287 formattypes[ff_mma].disabled = true;
2288 formattypes[ff_mmb].disabled = true;
2289 formattypes[ff_multiple].disabled = true;
2290 formattypes[ff_ptype0].disabled = true;
2291 formattypes[ff_cff].disabled = true;
2292 formattypes[ff_cffcid].disabled = true;
2293 formattypes[ff_cid].disabled = true;
2294 formattypes[ff_ttf].disabled = true;
2295 formattypes[ff_type42].disabled = true;
2296 formattypes[ff_type42cid].disabled = true;
2297 formattypes[ff_ttfsym].disabled = true;
2298 formattypes[ff_ttfmacbin].disabled = true;
2299 formattypes[ff_ttfdfont].disabled = true;
2300 formattypes[ff_otfdfont].disabled = true;
2301 formattypes[ff_otf].disabled = true;
2302 formattypes[ff_otfcid].disabled = true;
2303 formattypes[ff_cffcid].disabled = true;
2304 formattypes[ff_ufo].disabled = true;
2305 formattypes[ff_ufo2].disabled = true;
2306 formattypes[ff_ufo3].disabled = true;
2307 if ( ofs!=ff_svg )
2308 ofs = ff_ptype3;
2309 } else if ( sf->strokedfont ) {
2310 formattypes[ff_ttf].disabled = true;
2311 formattypes[ff_ttfsym].disabled = true;
2312 formattypes[ff_ttfmacbin].disabled = true;
2313 formattypes[ff_ttfdfont].disabled = true;
2314 formattypes[ff_ufo].disabled = true;
2315 formattypes[ff_ufo2].disabled = true;
2316 formattypes[ff_ufo3].disabled = true;
2317 if ( ofs==ff_ttf || ofs==ff_ttfsym || ofs==ff_ttfmacbin || ofs==ff_ttfdfont )
2318 ofs = ff_otf;
2319 }
2320 formattypes[ff_ttc].disabled = true;
2321 if ( family == gf_macfamily ) {
2322 if ( ofs==ff_pfa || ofs==ff_pfb || ofs==ff_multiple || ofs==ff_ptype3 ||
2323 ofs==ff_ptype0 || ofs==ff_mma || ofs==ff_mmb )
2324 ofs = ff_pfbmacbin;
2325 else if ( ofs==ff_cid || ofs==ff_otfcid || ofs==ff_cffcid )
2326 ofs = ff_otfciddfont;
2327 else if ( ofs==ff_ttf || ofs==ff_ttfsym )
2328 ofs = ff_ttfmacbin;
2329 else if ( ofs==ff_otf || ofs==ff_cff )
2330 ofs = ff_otfdfont;
2331 else if ( ofs==ff_ufo || ofs==ff_ufo2 || ofs==ff_ufo3 || ofs==ff_ttc )
2332 ofs = ff_ttfdfont;
2333 formattypes[ff_pfa].disabled = true;
2334 formattypes[ff_pfb].disabled = true;
2335 formattypes[ff_mma].disabled = true;
2336 formattypes[ff_mmb].disabled = true;
2337 formattypes[ff_multiple].disabled = true;
2338 formattypes[ff_ptype3].disabled = true;
2339 formattypes[ff_ptype0].disabled = true;
2340 formattypes[ff_type42].disabled = true;
2341 formattypes[ff_type42cid].disabled = true;
2342 formattypes[ff_ttf].disabled = true;
2343 formattypes[ff_ttfsym].disabled = true;
2344 formattypes[ff_otf].disabled = true;
2345 formattypes[ff_otfcid].disabled = true;
2346 formattypes[ff_cff].disabled = true;
2347 formattypes[ff_cffcid].disabled = true;
2348 formattypes[ff_svg].disabled = true;
2349 formattypes[ff_ufo].disabled = true;
2350 formattypes[ff_ufo2].disabled = true;
2351 formattypes[ff_ufo3].disabled = true;
2352 } else if ( family == gf_ttc ) {
2353 for ( i=0; i<=ff_none; ++i )
2354 formattypes[i].disabled = true;
2355 formattypes[ff_ttc].disabled = false;
2356 ofs = ff_ttc;
2357 }
2358 #ifndef FONTFORGE_CAN_USE_WOFF2
2359 formattypes[ff_woff2].disabled = true;
2360 #endif
2361
2362 for ( i=0; i<sizeof(formattypes)/sizeof(formattypes[0]); ++i )
2363 formattypes[i].selected = false;
2364 formattypes[ofs].selected = true;
2365 gcd[6].gd.handle_controlevent = GFD_Format;
2366 gcd[6].gd.label = &formattypes[ofs];
2367
2368 gcd[7].gd.pos.x = 2; gcd[7].gd.pos.y = 2;
2369 gcd[7].gd.pos.width = pos.width-4; gcd[7].gd.pos.height = pos.height-4;
2370 gcd[7].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
2371 gcd[7].creator = GGroupCreate;
2372
2373 gcd[8].gd.pos.x = 155; gcd[8].gd.pos.y = 190; gcd[8].gd.pos.width = 126;
2374 gcd[8].gd.flags = gg_visible | gg_enabled;
2375 gcd[8].gd.u.list = bitmaptypes;
2376 gcd[8].creator = GListButtonCreate;
2377 for ( i=0; i<sizeof(bitmaptypes)/sizeof(bitmaptypes[0]); ++i ) {
2378 bitmaptypes[i].selected = false;
2379 bitmaptypes[i].disabled = false;
2380 }
2381 hvarray[2] = &gcd[8]; hvarray[3] = NULL;
2382 old = oldbitmapstate;
2383 if ( family==gf_macfamily ) {
2384 if ( old==bf_bdf || old==bf_fon || old==bf_fnt || old==bf_sfnt_ms ||
2385 old==bf_otb || old==bf_palm || old==bf_ptype3 ) {
2386 if ( ofs==ff_otfdfont || ofs==ff_otfciddfont || ofs==ff_ttfdfont )
2387 old = bf_ttf;
2388 else
2389 old = bf_sfnt_dfont;
2390 } else if ( old==bf_nfntmacbin &&
2391 ( ofs==ff_otfdfont || ofs==ff_otfciddfont || ofs==ff_ttfdfont ))
2392 old = bf_ttf;
2393 bitmaptypes[bf_bdf].disabled = true;
2394 bitmaptypes[bf_fon].disabled = true;
2395 bitmaptypes[bf_fnt].disabled = true;
2396 } else if ( family==gf_ttc ) {
2397 for ( i=0; i<bf_none; ++i )
2398 bitmaptypes[i].disabled = true;
2399 bitmaptypes[bf_ttf].disabled = false;
2400 if ( old!=bf_none )
2401 old = bf_ttf;
2402 }
2403 temp = sf->cidmaster ? sf->cidmaster : sf;
2404 if ( temp->bitmaps==NULL ) {
2405 old = bf_none;
2406 bitmaptypes[bf_bdf].disabled = true;
2407 bitmaptypes[bf_ttf].disabled = true;
2408 bitmaptypes[bf_sfnt_dfont].disabled = true;
2409 bitmaptypes[bf_sfnt_ms].disabled = true;
2410 bitmaptypes[bf_otb].disabled = true;
2411 bitmaptypes[bf_nfntmacbin].disabled = true;
2412 bitmaptypes[bf_fon].disabled = true;
2413 bitmaptypes[bf_fnt].disabled = true;
2414 bitmaptypes[bf_palm].disabled = true;
2415 bitmaptypes[bf_ptype3].disabled = true;
2416 } else if ( ofs==ff_ttf || ofs==ff_ttfsym || ofs==ff_ttfmacbin ||
2417 ofs==ff_ttfdfont || ofs==ff_otf || ofs==ff_otfdfont || ofs==ff_otfcid ||
2418 ofs==ff_otfciddfont ) {
2419 bitmaptypes[bf_ttf].disabled = false;
2420 bitmaptypes[bf_sfnt_dfont].disabled = true;
2421 bitmaptypes[bf_sfnt_ms].disabled = true;
2422 bitmaptypes[bf_otb].disabled = true;
2423 } else {
2424 bitmaptypes[bf_ttf].disabled = true;
2425 bitmaptypes[bf_sfnt_dfont].disabled = false;
2426 bitmaptypes[bf_sfnt_ms].disabled = false;
2427 bitmaptypes[bf_otb].disabled = false;
2428 }
2429 bitmaptypes[old].selected = true;
2430 gcd[8].gd.label = &bitmaptypes[old];
2431 gcd[8].gd.handle_controlevent = GFD_BitmapFormat;
2432
2433 gcd[9].gd.pos.x = gcd[8].gd.pos.x; gcd[9].gd.pos.y = 219; gcd[9].gd.pos.width = gcd[8].gd.pos.width;
2434 gcd[9].gd.flags = gg_visible | gg_enabled;
2435 if ( old==bf_none )
2436 gcd[9].gd.flags &= ~gg_enabled;
2437 gcd[9].creator = GTextFieldCreate;
2438 label[9].text = BitmapList(temp);
2439 gcd[9].gd.label = &label[9];
2440 hvarray[6] = &gcd[9]; hvarray[7] = NULL;
2441
2442 k = 10;
2443 label[k].text = (unichar_t *) _("Force glyph names to:");
2444 label[k].text_is_1byte = true;
2445 gcd[k].gd.label = &label[k];
2446 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24+6;
2447 gcd[k].gd.flags = gg_enabled | gg_visible;
2448 gcd[k].gd.popup_msg = _("In the saved font, force all glyph names to match those in the specified namelist");
2449 gcd[k++].creator = GLabelCreate;
2450 hvarray[8] = &gcd[k-1]; hvarray[9] = GCD_ColSpan;
2451
2452 rk = k;
2453 gcd[k].gd.pos.x = gcd[k-2].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
2454 gcd[k].gd.pos.width = gcd[k-2].gd.pos.width;
2455 gcd[k].gd.flags = gg_visible | gg_enabled;
2456 gcd[k].gd.popup_msg = _("In the saved font, force all glyph names to match those in the specified namelist");
2457 gcd[k].creator = GListButtonCreate;
2458 nlnames = AllNamelistNames();
2459 for ( cnt=0; nlnames[cnt]!=NULL; ++cnt);
2460 namelistnames = calloc(cnt+3,sizeof(GTextInfo));
2461 namelistnames[0].text = (unichar_t *) _("No Rename");
2462 namelistnames[0].text_is_1byte = true;
2463 if ( force_names_when_saving==NULL ) {
2464 namelistnames[0].selected = true;
2465 gcd[k].gd.label = &namelistnames[0];
2466 }
2467 namelistnames[1].line = true;
2468 for ( cnt=0; nlnames[cnt]!=NULL; ++cnt) {
2469 namelistnames[cnt+2].text = (unichar_t *) nlnames[cnt];
2470 namelistnames[cnt+2].text_is_1byte = true;
2471 if ( force_names_when_saving!=NULL &&
2472 strcmp(_(force_names_when_saving->title),nlnames[cnt])==0 ) {
2473 namelistnames[cnt+2].selected = true;
2474 gcd[k].gd.label = &namelistnames[cnt+2];
2475 }
2476 }
2477 gcd[k++].gd.u.list = namelistnames;
2478 free(nlnames);
2479 hvarray[10] = &gcd[k-1]; hvarray[11] = NULL;
2480
2481 if ( !family ) {
2482 /* Too annoying to check if all fonts in a family have the same set of*/
2483 /* useful layers. So only do this if not family */
2484 label[k].text = (unichar_t *) _("Layer:");
2485 label[k].text_is_1byte = true;
2486 gcd[k].gd.label = &label[k];
2487 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24+6;
2488 gcd[k].gd.flags = gg_enabled | gg_visible;
2489 gcd[k].gd.popup_msg = _("In the saved font, force all glyph names to match those in the specified namelist");
2490 gcd[k++].creator = GLabelCreate;
2491
2492 gcd[k].gd.pos.x = gcd[k-2].gd.pos.x; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
2493 gcd[k].gd.pos.width = gcd[k-2].gd.pos.width;
2494 gcd[k].gd.flags = gg_visible | gg_enabled;
2495 gcd[k].gd.popup_msg = _("Save a font based on the specified layer");
2496 gcd[k].creator = GListButtonCreate;
2497 gcd[k].gd.cid = CID_Layers;
2498 gcd[k++].gd.u.list = lynames = SFUsableLayerNames(sf,layer);
2499 if ( lynames[1].text==NULL ) {
2500 gcd[k-2].gd.flags &= ~gg_visible;
2501 gcd[k-1].gd.flags &= ~gg_visible;
2502 }
2503 hvi=12;
2504 hvarray[hvi++] = &gcd[k-2]; hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = &gcd[k-1];
2505 hvarray[hvi++] = NULL;
2506
2507 /* Too time consuming to validate lots of fonts, and what UI would I use? */
2508 /* so only do this if not family */
2509 vk = k;
2510 label[k].text = (unichar_t *) _("Validate Before Saving");
2511 label[k].text_is_1byte = true;
2512 gcd[k].gd.label = &label[k];
2513 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24+6;
2514 if ( sf->multilayer || sf->strokedfont || sf->onlybitmaps )
2515 gcd[k].gd.flags = gg_visible;
2516 else if ( old_validate )
2517 gcd[k].gd.flags = (gg_enabled | gg_visible | gg_cb_on);
2518 else
2519 gcd[k].gd.flags = (gg_enabled | gg_visible);
2520 gcd[k].gd.popup_msg = _("Check the glyph outlines for standard errors before saving\nThis can be slow.");
2521 gcd[k++].creator = GCheckBoxCreate;
2522 hvarray[hvi++] = &gcd[k-1]; hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = GCD_ColSpan;
2523 hvarray[hvi++] = NULL;
2524
2525 label[k].text = (unichar_t *) _("Append a FONTLOG entry");
2526 label[k].text_is_1byte = true;
2527 gcd[k].gd.label = &label[k];
2528 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24+6;
2529 gcd[k].gd.flags = (gg_enabled | gg_visible);
2530 if ( old_fontlog )
2531 gcd[k].gd.flags |= gg_cb_on;
2532 gcd[k].gd.popup_msg = _("The FONTLOG allows you to keep a log of changes made to your font.");
2533 gcd[k].gd.cid = CID_AppendFontLog;
2534 gcd[k].gd.handle_controlevent = GFD_ToggleFontLog;
2535 gcd[k++].creator = GCheckBoxCreate;
2536 hvarray[hvi++] = &gcd[k-1]; hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = GCD_ColSpan;
2537 hvarray[hvi++] = NULL;
2538
2539 gcd[k].gd.flags = old_fontlog ? (gg_visible | gg_enabled | gg_textarea_wrap) : (gg_enabled|gg_textarea_wrap);
2540 gcd[k].gd.cid = CID_FontLogBit;
2541 gcd[k++].creator = GTextAreaCreate;
2542 hvarray[hvi++] = &gcd[k-1];
2543 hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = NULL;
2544
2545 label[k].text = (unichar_t *) _("Prepend timestamp");
2546 label[k].text_is_1byte = true;
2547 gcd[k].gd.label = &label[k];
2548 gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24+6;
2549 gcd[k].gd.flags = (gg_enabled | gg_visible);
2550 gcd[k].gd.popup_msg = _("This option prepends a timestamp in the format YYMMDDHHMM to the filename and font-family name metadata.");
2551 gcd[k].gd.cid = CID_PrependTimestamp;
2552 gcd[k].gd.handle_controlevent = GFD_TogglePrependTimestamp;
2553 gcd[k++].creator = GCheckBoxCreate; //???
2554 hvarray[hvi++] = &gcd[k-1]; hvarray[hvi++] = GCD_ColSpan; hvarray[hvi++] = GCD_ColSpan;
2555 hvarray[hvi++] = NULL; hvarray[hvi++] = NULL;
2556 } else {
2557 hvarray[12] = NULL;
2558 }
2559
2560 boxes[3].gd.flags = gg_enabled|gg_visible;
2561 boxes[3].gd.u.boxelements = hvarray;
2562 boxes[3].creator = GHVBoxCreate;
2563 varray[2] = GCD_Glue; varray[3] = NULL;
2564 varray[4] = &boxes[3]; varray[5] = NULL;
2565 varray[6] = GCD_Glue; varray[7] = NULL;
2566 varray[8] = GCD_Glue; varray[9] = NULL;
2567 varray[10] = &boxes[2]; varray[11] = NULL;
2568 varray[12] = NULL;
2569
2570 if ( family ) {
2571 y = 276;
2572
2573 f = 0;
2574 gcd[k].gd.pos.x = 5; gcd[k].gd.pos.y = y;
2575 gcd[k].gd.pos.width = totwid-5-5;
2576 gcd[k].gd.flags = gg_visible | gg_enabled ;
2577 gcd[k++].creator = GLineCreate;
2578 famarray[f++] = &gcd[k-1]; famarray[f++] = GCD_ColSpan; famarray[f++] = NULL;
2579 y += 7;
2580
2581 for ( i=0, fc=0, j=1; i<familycnt && j<48 ; ++i ) {
2582 while ( fc<fondcnt ) {
2583 while ( j<48 && familysfs[fc][j]==NULL ) ++j;
2584 if ( j!=48 )
2585 break;
2586 ++fc;
2587 j=0;
2588 }
2589 if ( fc==fondcnt )
2590 break;
2591 gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = y;
2592 gcd[k].gd.pos.width = gcd[8].gd.pos.x-gcd[k].gd.pos.x-5;
2593 gcd[k].gd.flags = gg_visible | gg_enabled | gg_cb_on ;
2594 label[k].text = (unichar_t *) (familysfs[fc][j]->fontname);
2595 label[k].text_is_1byte = true;
2596 gcd[k].gd.label = &label[k];
2597 gcd[k].gd.cid = CID_Family+i*10;
2598 gcd[k].data = familysfs[fc][j];
2599 gcd[k].gd.popup_msg = styleName(familysfs[fc][j]);
2600 gcd[k++].creator = GCheckBoxCreate;
2601 famarray[f++] = &gcd[k-1];
2602
2603 gcd[k].gd.pos.x = gcd[8].gd.pos.x; gcd[k].gd.pos.y = y; gcd[k].gd.pos.width = gcd[8].gd.pos.width;
2604 gcd[k].gd.flags = gg_visible | gg_enabled;
2605 if ( old==bf_none )
2606 gcd[k].gd.flags &= ~gg_enabled;
2607 temp = familysfs[fc][j]->cidmaster ? familysfs[fc][j]->cidmaster : familysfs[fc][j];
2608 label[k].text = BitmapList(temp);
2609 gcd[k].gd.label = &label[k];
2610 gcd[k].gd.cid = CID_Family+i*10+1;
2611 gcd[k].data = familysfs[fc][j];
2612 gcd[k++].creator = GTextFieldCreate;
2613 famarray[f++] = &gcd[k-1]; famarray[f++] = NULL;
2614 y+=26;
2615 ++j;
2616 }
2617
2618 gcd[k].gd.pos.x = 5; gcd[k].gd.pos.y = y;
2619 gcd[k].gd.pos.width = totwid-5-5;
2620 gcd[k].gd.flags = gg_visible | gg_enabled ;
2621 gcd[k++].creator = GLineCreate;
2622 famarray[f++] = &gcd[k-1]; famarray[f++] = GCD_ColSpan; famarray[f++] = NULL;
2623 if ( family == gf_ttc ) {
2624 gcd[k].gd.flags = gg_visible | gg_enabled | gg_cb_on;
2625 label[k].text = (unichar_t *) _("Merge tables across fonts");
2626 label[k].text_is_1byte = true;
2627 gcd[k].gd.label = &label[k];
2628 gcd[k].gd.cid = CID_MergeTables;
2629 gcd[k].gd.popup_msg = _(
2630 "FontForge can generate two styles of ttc file.\n"
2631 "In the first each font is a separate entity\n"
2632 "with no connection to other fonts. In the second\n"
2633 "FontForge will attempt to use the same glyph table\n"
2634 "for all fonts, merging duplicate glyphs. It will\n"
2635 "also attempt to use the same space for tables in\n"
2636 "different fonts which are bit by bit the same.\n\n"
2637 "FontForge isn't always able to perform a merge, in\n"
2638 "which case it falls back on generating independent\n"
2639 "fonts within the ttc.\n"
2640 " FontForge cannot merge if:\n"
2641 " * The fonts have different em-sizes\n"
2642 " * Bitmaps are involved\n"
2643 " * The merged glyf table has more than 65534 glyphs\n\n"
2644 "(Merging will take longer)" );
2645 gcd[k++].creator = GCheckBoxCreate;
2646 famarray[f++] = &gcd[k-1]; famarray[f++] = GCD_ColSpan; famarray[f++] = NULL;
2647
2648 gcd[k].gd.flags = gg_visible | gg_enabled;
2649 label[k].text = (unichar_t *) _("As CFF fonts");
2650 label[k].text_is_1byte = true;
2651 gcd[k].gd.label = &label[k];
2652 gcd[k].gd.cid = CID_TTC_CFF;
2653 gcd[k].gd.popup_msg = _(
2654 "Put CFF fonts into the ttc rather than TTF.\n These seem to work on the mac and linux\n but are documented not to work on Windows." );
2655 gcd[k++].creator = GCheckBoxCreate;
2656 famarray[f++] = &gcd[k-1]; famarray[f++] = GCD_ColSpan; famarray[f++] = NULL;
2657 }
2658 famarray[f++] = NULL;
2659
2660 free(familysfs);
2661
2662 boxes[4].gd.flags = gg_enabled|gg_visible;
2663 boxes[4].gd.u.boxelements = famarray;
2664 boxes[4].creator = GHVBoxCreate;
2665 varray[6] = &boxes[4];
2666 }
2667
2668 boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
2669 boxes[0].gd.flags = gg_enabled|gg_visible;
2670 boxes[0].gd.u.boxelements = varray;
2671 boxes[0].creator = GHVGroupCreate;
2672
2673 GGadgetsCreate(gw,boxes);
2674 GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
2675 GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
2676 GHVBoxFitWindow(boxes[0].ret);
2677
2678 GGadgetSetUserData(gcd[2].ret,gcd[0].ret);
2679 free(namelistnames);
2680 free(lynames);
2681 free(label[9].text);
2682 GFileChooserConnectButtons(gcd[0].ret,gcd[1].ret,gcd[2].ret);
2683 {
2684 SplineFont *master = sf->cidmaster ? sf->cidmaster : sf;
2685 char *fn = master->defbasefilename!=NULL ? master->defbasefilename :
2686 master->fontname;
2687 unichar_t *temp = malloc(sizeof(unichar_t)*(strlen(fn)+30));
2688 uc_strcpy(temp,fn);
2689 if ( ofs==ff_none )
2690 uc_strcat(temp,bitmapextensions[old]);
2691 else
2692 uc_strcat(temp,savefont_extensions[ofs]);
2693 GGadgetSetTitle(gcd[0].ret,temp);
2694 free(temp);
2695 }
2696 GFileChooserGetChildren(gcd[0].ret,&pulldown,&files,&tf);
2697 GWidgetIndicateFocusGadget(tf);
2698 #if __Mac
2699 /* The name of the postscript file is fixed and depends solely on */
2700 /* the font name. If the user tried to change it, the font would */
2701 /* not be found */
2702 GGadgetSetVisible(tf,ofs!=ff_pfbmacbin);
2703 #endif
2704
2705 d.sf = sf;
2706 d.map = map;
2707 d.family = family;
2708 d.familycnt = familycnt-1; /* Don't include the "normal" instance */
2709 d.gfc = gcd[0].ret;
2710 d.pstype = gcd[6].ret;
2711 d.bmptype = gcd[8].ret;
2712 d.bmpsizes = gcd[9].ret;
2713 d.rename = gcd[rk].ret;
2714 d.validate = family ? NULL : gcd[vk].ret;
2715 d.gw = gw;
2716
2717 d.ps_flags = old_ps_flags;
2718 d.sfnt_flags = old_sfnt_flags;
2719 d.psotb_flags = old_ps_flags | (old_psotb_flags&~ps_flag_mask);
2720
2721 GFD_FigureWhich(&d);
2722
2723 GWidgetHidePalettes();
2724 GDrawSetVisible(gw,true);
2725 while ( !d.done )
2726 GDrawProcessOneEvent(NULL);
2727 GDrawDestroyWindow(gw);
2728 return(d.ret);
2729 }
2730