Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "autohint.h"
28 : #include "cvexport.h"
29 : #include "cvundoes.h"
30 : #include "fontforgeui.h"
31 : #include <math.h>
32 : #include <locale.h>
33 : #include <string.h>
34 : #include "gfile.h"
35 : #include <time.h>
36 : #include "ustring.h"
37 : #include "gio.h"
38 : #include "gicons.h"
39 : #include <utype.h>
40 :
41 : static char *last = NULL;
42 : static char *last_bits = NULL;
43 :
44 : struct sizebits {
45 : GWindow gw;
46 : int *pixels, *bits;
47 : unsigned int done: 1;
48 : unsigned int good: 1;
49 : };
50 :
51 : #define CID_Size 1000
52 : #define CID_Bits 1001
53 :
54 0 : static int SB_OK(GGadget *g, GEvent *e) {
55 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
56 0 : struct sizebits *d = GDrawGetUserData(GGadgetGetWindow(g));
57 0 : int err=0;
58 0 : *d->pixels = GetInt8(d->gw,CID_Size,_("Pixel size:"),&err);
59 0 : *d->bits = GetInt8(d->gw,CID_Bits,_("Bits/Pixel:"),&err);
60 0 : if ( err )
61 0 : return( true );
62 0 : if ( *d->bits!=1 && *d->bits!=2 && *d->bits!=4 && *d->bits!=8 ) {
63 0 : ff_post_error(_("The only valid values for bits/pixel are 1, 2, 4 or 8"),_("The only valid values for bits/pixel are 1, 2, 4 or 8"));
64 0 : return( true );
65 : }
66 0 : free( last ); free( last_bits );
67 0 : last = GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Size));
68 0 : last_bits = GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Bits));
69 0 : d->done = true;
70 0 : d->good = true;
71 : }
72 0 : return( true );
73 : }
74 :
75 0 : static int SB_Cancel(GGadget *g, GEvent *e) {
76 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
77 0 : struct sizebits *d = GDrawGetUserData(GGadgetGetWindow(g));
78 0 : d->done = true;
79 : }
80 0 : return( true );
81 : }
82 :
83 0 : static int sb_e_h(GWindow gw, GEvent *event) {
84 0 : if ( event->type==et_close ) {
85 0 : struct sizebits *d = GDrawGetUserData(gw);
86 0 : d->done = true;
87 : }
88 0 : return( event->type!=et_char );
89 : }
90 :
91 0 : static int AskSizeBits(int *pixelsize,int *bitsperpixel) {
92 : GRect pos;
93 : GWindow gw;
94 : GWindowAttrs wattrs;
95 : GGadgetCreateData gcd[8], boxes[5], *hvarray[7][4], *barray[10];
96 : GTextInfo label[8];
97 : struct sizebits sb;
98 :
99 0 : memset(&sb,'\0',sizeof(sb));
100 0 : sb.pixels = pixelsize; sb.bits = bitsperpixel;
101 :
102 0 : memset(&wattrs,0,sizeof(wattrs));
103 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
104 0 : wattrs.event_masks = ~(1<<et_charup);
105 0 : wattrs.restrict_input_to_me = 1;
106 0 : wattrs.undercursor = 1;
107 0 : wattrs.cursor = ct_pointer;
108 0 : wattrs.utf8_window_title = _("Pixel size?");
109 0 : wattrs.is_dlg = true;
110 0 : pos.x = pos.y = 0;
111 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,140));
112 0 : pos.height = GDrawPointsToPixels(NULL,100);
113 0 : sb.gw = gw = GDrawCreateTopWindow(NULL,&pos,sb_e_h,&sb,&wattrs);
114 :
115 0 : memset(&label,0,sizeof(label));
116 0 : memset(&gcd,0,sizeof(gcd));
117 0 : memset(&boxes,0,sizeof(boxes));
118 :
119 0 : label[0].text = (unichar_t *) _("Pixel size:");
120 0 : label[0].text_is_1byte = true;
121 0 : gcd[0].gd.label = &label[0];
122 0 : gcd[0].gd.pos.x = 8; gcd[0].gd.pos.y = 8+6;
123 0 : gcd[0].gd.flags = gg_enabled|gg_visible;
124 0 : gcd[0].creator = GLabelCreate;
125 0 : hvarray[0][0] = &gcd[0];
126 :
127 0 : gcd[1].gd.pos.x = 70; gcd[1].gd.pos.y = 8; gcd[1].gd.pos.width = 65;
128 0 : label[1].text = (unichar_t *) (last==NULL ? "100" : last);
129 0 : label[1].text_is_1byte = true;
130 0 : gcd[1].gd.label = &label[1];
131 0 : gcd[1].gd.flags = gg_enabled|gg_visible;
132 0 : gcd[1].gd.cid = CID_Size;
133 0 : gcd[1].creator = GNumericFieldCreate;
134 0 : hvarray[0][1] = &gcd[1]; hvarray[0][2] = GCD_Glue; hvarray[0][3] = NULL;
135 :
136 0 : label[2].text = (unichar_t *) _("Bits/Pixel:");
137 0 : label[2].text_is_1byte = true;
138 0 : gcd[2].gd.label = &label[2];
139 0 : gcd[2].gd.pos.x = 8; gcd[2].gd.pos.y = 38+6;
140 0 : gcd[2].gd.flags = gg_enabled|gg_visible;
141 0 : gcd[2].creator = GLabelCreate;
142 0 : hvarray[1][0] = &gcd[2];
143 :
144 0 : gcd[3].gd.pos.x = 70; gcd[3].gd.pos.y = 38; gcd[3].gd.pos.width = 65;
145 0 : label[3].text = (unichar_t *) (last_bits==NULL? "1" : last_bits);
146 0 : label[3].text_is_1byte = true;
147 0 : gcd[3].gd.label = &label[3];
148 0 : gcd[3].gd.flags = gg_enabled|gg_visible;
149 0 : gcd[3].gd.cid = CID_Bits;
150 0 : gcd[3].creator = GNumericFieldCreate;
151 0 : hvarray[1][1] = &gcd[3]; hvarray[1][2] = GCD_Glue; hvarray[1][3] = NULL;
152 0 : hvarray[2][0] = hvarray[2][1] = hvarray[2][2] = GCD_Glue; hvarray[2][3] = NULL;
153 :
154 0 : gcd[4].gd.pos.x = 10-3; gcd[4].gd.pos.y = 38+30-3;
155 0 : gcd[4].gd.pos.width = -1; gcd[4].gd.pos.height = 0;
156 0 : gcd[4].gd.flags = gg_visible | gg_enabled | gg_but_default;
157 0 : label[4].text = (unichar_t *) _("_OK");
158 0 : label[4].text_is_1byte = true;
159 0 : label[4].text_in_resource = true;
160 0 : gcd[4].gd.mnemonic = 'O';
161 0 : gcd[4].gd.label = &label[4];
162 0 : gcd[4].gd.handle_controlevent = SB_OK;
163 0 : gcd[4].creator = GButtonCreate;
164 0 : barray[0] = GCD_Glue; barray[1] = &gcd[4]; barray[2] = barray[3] = barray[4] = barray[5] = GCD_Glue;
165 :
166 0 : gcd[5].gd.pos.x = -10; gcd[5].gd.pos.y = 38+30;
167 0 : gcd[5].gd.pos.width = -1; gcd[5].gd.pos.height = 0;
168 0 : gcd[5].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
169 0 : label[5].text = (unichar_t *) _("_Cancel");
170 0 : label[5].text_is_1byte = true;
171 0 : label[5].text_in_resource = true;
172 0 : gcd[5].gd.label = &label[5];
173 0 : gcd[5].gd.mnemonic = 'C';
174 0 : gcd[5].gd.handle_controlevent = SB_Cancel;
175 0 : gcd[5].creator = GButtonCreate;
176 0 : barray[5] = &gcd[5]; barray[6] = GCD_Glue; barray[7] = NULL;
177 :
178 0 : boxes[2].gd.flags = gg_enabled | gg_visible;
179 0 : boxes[2].gd.u.boxelements = barray;
180 0 : boxes[2].creator = GHBoxCreate;
181 0 : hvarray[3][0] = &boxes[2]; hvarray[3][1] = GCD_ColSpan; hvarray[3][2] = GCD_Glue; hvarray[3][3] = NULL;
182 0 : hvarray[4][0] = NULL;
183 :
184 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
185 0 : boxes[0].gd.flags = gg_enabled | gg_visible;
186 0 : boxes[0].gd.u.boxelements = hvarray[0];
187 0 : boxes[0].creator = GHVGroupCreate;
188 :
189 0 : GGadgetsCreate(gw,boxes);
190 0 : GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
191 0 : GHVBoxSetExpandableCol(boxes[0].ret,gb_expandglue);
192 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
193 0 : GHVBoxFitWindow(boxes[0].ret);
194 0 : GWidgetIndicateFocusGadget(GWidgetGetControl(gw,CID_Size));
195 0 : GTextFieldSelect(GWidgetGetControl(gw,CID_Size),0,-1);
196 :
197 0 : GWidgetHidePalettes();
198 0 : GDrawSetVisible(gw,true);
199 0 : while ( !sb.done )
200 0 : GDrawProcessOneEvent(NULL);
201 0 : GDrawDestroyWindow(gw);
202 0 : return( sb.good );
203 : }
204 :
205 0 : static int ExportXBM(char *filename,SplineChar *sc, int layer, int format) {
206 : char *ans;
207 : int pixelsize, bitsperpixel;
208 :
209 0 : if ( format==0 ) {
210 0 : ans = gwwv_ask_string(_("Pixel size?"),"100",_("Pixel size?"));
211 0 : if ( ans==NULL )
212 0 : return( 0 );
213 0 : if ( (pixelsize=strtol(ans,NULL,10))<=0 )
214 0 : return( 0 );
215 0 : free(last);
216 0 : last = ans;
217 0 : bitsperpixel=1;
218 : } else {
219 0 : if ( !AskSizeBits(&pixelsize,&bitsperpixel) )
220 0 : return( 0 );
221 : }
222 0 : if ( autohint_before_generate && sc->changedsincelasthinted && !sc->manualhints )
223 0 : SplineCharAutoHint(sc,layer,NULL);
224 0 : return( ExportImage(filename,sc, layer, format, pixelsize, bitsperpixel));
225 : }
226 : struct gfc_data {
227 : int done;
228 : int ret;
229 : GGadget *gfc;
230 : GGadget *format;
231 : SplineChar *sc;
232 : BDFChar *bc;
233 : int layer;
234 : };
235 :
236 :
237 : static GTextInfo bcformats[] = {
238 : /* 0=*.xbm, 1=*.bmp, 2=*.png, 3=*.xpm, 4=*.c(fontforge-internal) */
239 : { (unichar_t *) N_("X Bitmap"), NULL, 0, 0, (void *) 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
240 : { (unichar_t *) N_("BMP"), NULL, 0, 0, (void *) 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
241 : #ifndef _NO_LIBPNG
242 : { (unichar_t *) N_("png"), NULL, 0, 0, (void *) 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
243 : #endif
244 : { (unichar_t *) N_("X Pixmap"), NULL, 0, 0, (void *) 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
245 : { (unichar_t *) N_("C FontForge"), NULL, 0, 0, (void *) 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
246 : GTEXTINFO_EMPTY
247 : };
248 :
249 : static GTextInfo formats[] = {
250 : { (unichar_t *) N_("EPS"), NULL, 0, 0, (void *) 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0' },
251 : { (unichar_t *) N_("XFig"), NULL, 0, 0, (void *) 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
252 : { (unichar_t *) N_("SVG"), NULL, 0, 0, (void *) 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
253 : { (unichar_t *) N_("Glif"), NULL, 0, 0, (void *) 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
254 : { (unichar_t *) N_("PDF"), NULL, 0, 0, (void *) 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
255 : { (unichar_t *) N_("Raph's plate"), NULL, 0, 0, (void *) 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
256 : #define BITMAP_FORMAT_START 6
257 : /* 0=*.xbm, 1=*.bmp, 2=*.png, 3=*.xpm, 4=*.c(fontforge-internal) */
258 : { (unichar_t *) N_("X Bitmap"), NULL, 0, 0, (void *) BITMAP_FORMAT_START, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
259 : { (unichar_t *) N_("BMP"), NULL, 0, 0, (void *) (BITMAP_FORMAT_START+1), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
260 : #ifndef _NO_LIBPNG
261 : { (unichar_t *) N_("png"), NULL, 0, 0, (void *) (BITMAP_FORMAT_START+2), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
262 : #endif
263 : { (unichar_t *) N_("X Pixmap"), NULL, 0, 0, (void *) (BITMAP_FORMAT_START+3), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
264 : { (unichar_t *) N_("C FontForge"), NULL, 0, 0, (void *) (BITMAP_FORMAT_START+4), 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0' },
265 : GTEXTINFO_EMPTY
266 : };
267 : static int last_format = 0;
268 :
269 0 : static void DoExport(struct gfc_data *d,unichar_t *path) {
270 : char *temp;
271 0 : int format, good = 0;
272 :
273 0 : temp = cu_copy(path);
274 0 : last_format = format = (intpt) (GGadgetGetListItemSelected(d->format)->userdata);
275 0 : if ( d->bc )
276 0 : last_format += BITMAP_FORMAT_START;
277 0 : if ( d->bc!=NULL )
278 0 : good = BCExportXBM(temp,d->bc,format);
279 0 : else if ( format==0 )
280 0 : good = ExportEPS(temp,d->sc,d->layer);
281 0 : else if ( format==1 )
282 0 : good = ExportFig(temp,d->sc,d->layer);
283 0 : else if ( format==2 )
284 0 : good = ExportSVG(temp,d->sc,d->layer);
285 0 : else if ( format==3 )
286 0 : good = ExportGlif(temp,d->sc,d->layer);
287 0 : else if ( format==4 )
288 0 : good = ExportPDF(temp,d->sc,d->layer);
289 0 : else if ( format==5 )
290 0 : good = ExportPlate(temp,d->sc,d->layer);
291 0 : else if ( format<fv_pythonbase )
292 0 : good = ExportXBM(temp,d->sc,d->layer,format-BITMAP_FORMAT_START);
293 : #ifndef _NO_PYTHON
294 0 : else if ( format>=fv_pythonbase )
295 0 : PyFF_SCExport(d->sc,format-fv_pythonbase,temp,d->layer);
296 : #endif
297 0 : if ( !good )
298 0 : ff_post_error(_("Save Failed"),_("Save Failed"));
299 0 : free(temp);
300 0 : d->done = good;
301 0 : d->ret = good;
302 0 : }
303 :
304 0 : static void GFD_doesnt(GIOControl *gio) {
305 : /* The filename the user chose doesn't exist, so everything is happy */
306 0 : struct gfc_data *d = gio->userdata;
307 0 : DoExport(d,gio->path);
308 0 : GFileChooserReplaceIO(d->gfc,NULL);
309 0 : }
310 :
311 0 : static void GFD_exists(GIOControl *gio) {
312 : /* The filename the user chose exists, ask user if s/he wants to overwrite */
313 0 : struct gfc_data *d = gio->userdata;
314 : char *rcb[3], *temp;
315 :
316 0 : rcb[2]=NULL;
317 0 : rcb[0] = _("_Replace");
318 0 : rcb[1] = _("_Cancel");
319 :
320 0 : if ( gwwv_ask(_("File Exists"),(const char **) rcb,0,1,_("File, %s, exists. Replace it?"),
321 0 : temp = u2utf8_copy(u_GFileNameTail(gio->path)))==0 ) {
322 0 : DoExport(d,gio->path);
323 : }
324 0 : free(temp);
325 0 : GFileChooserReplaceIO(d->gfc,NULL);
326 0 : }
327 :
328 0 : static int GFD_SaveOk(GGadget *g, GEvent *e) {
329 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
330 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
331 : GGadget *tf;
332 0 : GFileChooserGetChildren(d->gfc,NULL,NULL,&tf);
333 0 : if ( *_GGadgetGetTitle(tf)!='\0' ) {
334 0 : unichar_t *ret = GGadgetGetTitle(d->gfc);
335 :
336 0 : GIOfileExists(GFileChooserReplaceIO(d->gfc,
337 0 : GIOCreate(ret,d,GFD_exists,GFD_doesnt)));
338 0 : free(ret);
339 : }
340 : }
341 0 : return( true );
342 : }
343 :
344 0 : static int GFD_Cancel(GGadget *g, GEvent *e) {
345 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
346 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
347 0 : d->done = true;
348 0 : d->ret = false;
349 : }
350 0 : return( true );
351 : }
352 :
353 0 : static int GFD_Format(GGadget *g, GEvent *e) {
354 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
355 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
356 : unichar_t *pt, *file, *f2;
357 0 : int format = (intpt) (GGadgetGetListItemSelected(d->format)->userdata);
358 0 : file = GGadgetGetTitle(d->gfc);
359 0 : f2 = malloc(sizeof(unichar_t) * (u_strlen(file)+6));
360 0 : u_strcpy(f2,file);
361 0 : free(file);
362 0 : pt = u_strrchr(f2,'.');
363 0 : if ( pt==NULL )
364 0 : pt = f2+u_strlen(f2);
365 0 : if ( d->bc!=NULL )
366 0 : uc_strcpy(pt,format==0?".xbm":
367 : format==1?".bmp":
368 : //format==2?".png":
369 : format==3?".xpm":
370 : format==4?".c":
371 : ".png");
372 : #ifndef _NO_PYTHON
373 0 : else if ( format>=fv_pythonbase )
374 0 : uc_strcpy(pt+1,py_ie[format-fv_pythonbase].extension);
375 : #endif
376 : else
377 0 : uc_strcpy(pt,format==0?".eps":
378 : format==1?".fig":
379 : format==2?".svg":
380 : format==3?".glif":
381 : format==4?".pdf":
382 : format==5?".plate":
383 : format==6?".xbm":
384 : format==7?".bmp":
385 : //format==8?".png":
386 : format==9?".xpm":
387 : format==10?".c":
388 : ".png");
389 0 : GGadgetSetTitle(d->gfc,f2);
390 0 : free(f2);
391 : }
392 0 : return( true );
393 : }
394 :
395 0 : static void GFD_dircreated(GIOControl *gio) {
396 0 : struct gfc_data *d = gio->userdata;
397 0 : unichar_t *dir = u_copy(gio->path);
398 :
399 0 : GFileChooserReplaceIO(d->gfc,NULL);
400 0 : GFileChooserSetDir(d->gfc,dir);
401 0 : free(dir);
402 0 : }
403 :
404 0 : static void GFD_dircreatefailed(GIOControl *gio) {
405 : /* We couldn't create the directory */
406 0 : struct gfc_data *d = gio->userdata;
407 : char *temp;
408 :
409 0 : ff_post_notice(_("Couldn't create directory"),_("Couldn't create directory: %s"),
410 0 : temp = u2utf8_copy(u_GFileNameTail(gio->path)));
411 0 : free(temp);
412 0 : GFileChooserReplaceIO(d->gfc,NULL);
413 0 : GFileChooserReplaceIO(d->gfc,NULL);
414 0 : }
415 :
416 0 : static int GFD_NewDir(GGadget *g, GEvent *e) {
417 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
418 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
419 : char *newdir;
420 : unichar_t *utemp;
421 :
422 0 : newdir = gwwv_ask_string(_("Create directory"),NULL,_("Directory name?"));
423 0 : if ( newdir==NULL )
424 0 : return( true );
425 0 : if ( !GFileIsAbsolute(newdir)) {
426 0 : unichar_t *tmp_dir = GFileChooserGetDir(d->gfc);
427 0 : char *basedir = u2utf8_copy(tmp_dir);
428 0 : char *temp = GFileAppendFile(basedir,newdir,false);
429 0 : free(newdir); free(basedir); free(tmp_dir);
430 0 : newdir = temp;
431 : }
432 0 : utemp = utf82u_copy(newdir); free(newdir);
433 0 : GIOmkDir(GFileChooserReplaceIO(d->gfc,
434 0 : GIOCreate(utemp,d,GFD_dircreated,GFD_dircreatefailed)));
435 0 : free(utemp);
436 : }
437 0 : return true;
438 : }
439 :
440 0 : static int e_h(GWindow gw, GEvent *event) {
441 0 : if ( event->type==et_close ) {
442 0 : struct gfc_data *d = GDrawGetUserData(gw);
443 0 : d->done = true;
444 0 : d->ret = false;
445 0 : } else if ( event->type == et_char ) {
446 0 : return( false );
447 0 : } else if ( event->type==et_map ) {
448 0 : GDrawRaise(gw);
449 0 : } else if ( event->type == et_mousemove ||
450 0 : (event->type==et_mousedown && event->u.mouse.button==3 )) {
451 0 : struct gfc_data *d = GDrawGetUserData(gw);
452 0 : GFileChooserPopupCheck(d->gfc,event);
453 0 : } else if (( event->type==et_mouseup || event->type==et_mousedown ) &&
454 0 : (event->u.mouse.button>=4 && event->u.mouse.button<=7) ) {
455 0 : struct gfc_data *d = GDrawGetUserData(gw);
456 0 : return( GGadgetDispatchEvent((GGadget *) (d->gfc),event));
457 : }
458 0 : return( true );
459 : }
460 :
461 0 : static int CanBeAPlateFile(SplineChar *sc) {
462 : int open_cnt;
463 : SplineSet *ss;
464 :
465 0 : if ( sc->parent->multilayer )
466 0 : return( false );
467 : /* Plate files can't handle refs */
468 0 : if ( sc->layers[ly_fore].refs!=NULL )
469 0 : return( false );
470 :
471 : /* Plate files can only handle 1 open contour */
472 0 : open_cnt = 0;
473 0 : for ( ss= sc->layers[ly_fore].splines; ss!=NULL; ss=ss->next ) {
474 0 : if ( ss->first->prev==NULL ) {
475 0 : if ( ss->first->next!=NULL )
476 0 : ++open_cnt;
477 : }
478 : }
479 0 : return( open_cnt<=1 );
480 : }
481 :
482 0 : static int _Export(SplineChar *sc,BDFChar *bc,int layer) {
483 : GRect pos;
484 : GWindow gw;
485 : GWindowAttrs wattrs;
486 : GGadgetCreateData gcd[8], boxes[4], *hvarray[8], *harray[5], *barray[10];
487 : GTextInfo label[7];
488 : struct gfc_data d;
489 : GGadget *pulldown, *files, *tf;
490 : char buffer[100]; unichar_t ubuf[100];
491 : char *ext;
492 : int _format, i;
493 : int /*bs = GIntGetResource(_NUM_Buttonsize), bsbigger,*/ totwid;
494 : static int done = false;
495 : GTextInfo *cur_formats;
496 :
497 0 : if ( !done ) {
498 0 : for ( i=0; formats[i].text!=NULL; ++i )
499 0 : formats[i].text= (unichar_t *) _((char *) formats[i].text);
500 0 : for ( i=0; bcformats[i].text!=NULL; ++i )
501 0 : bcformats[i].text= (unichar_t *) _((char *) bcformats[i].text);
502 0 : done = true;
503 : }
504 0 : if ( bc==NULL )
505 0 : formats[5].disabled = !CanBeAPlateFile(sc);
506 0 : cur_formats = bc==NULL ? formats : bcformats;
507 : #ifndef _NO_PYTHON
508 0 : if ( bc==NULL && py_ie!=NULL ) {
509 : int cnt, extras;
510 0 : for ( cnt=0; formats[cnt].text!=NULL; ++cnt );
511 0 : for ( i=extras=0; py_ie[i].name!=NULL; ++i )
512 0 : if ( py_ie[i].export!=NULL )
513 0 : ++extras;
514 0 : if ( extras!=0 ) {
515 0 : cur_formats = calloc(extras+cnt+1,sizeof(GTextInfo));
516 0 : for ( cnt=0; formats[cnt].text!=NULL; ++cnt ) {
517 0 : cur_formats[cnt] = formats[cnt];
518 0 : cur_formats[cnt].text = (unichar_t *) copy( (char *) formats[cnt].text );
519 : }
520 0 : for ( i=extras=0; py_ie[i].name!=NULL; ++i ) {
521 0 : if ( py_ie[i].export!=NULL ) {
522 0 : cur_formats[cnt+extras].text = (unichar_t *) copy(py_ie[i].name);
523 0 : cur_formats[cnt+extras].text_is_1byte = true;
524 0 : cur_formats[cnt+extras].userdata = (void *) (intpt) (fv_pythonbase+i);
525 0 : ++extras;
526 : }
527 : }
528 : }
529 : }
530 : #endif
531 :
532 0 : memset(&wattrs,0,sizeof(wattrs));
533 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
534 0 : wattrs.event_masks = ~(1<<et_charup);
535 0 : wattrs.restrict_input_to_me = 1;
536 0 : wattrs.is_dlg = 1;
537 0 : wattrs.undercursor = 1;
538 0 : wattrs.cursor = ct_pointer;
539 0 : wattrs.utf8_window_title = _("Export");
540 0 : pos.x = pos.y = 0;
541 0 : totwid = GGadgetScale(300);
542 0 : pos.width = GDrawPointsToPixels(NULL,200);
543 0 : pos.height = GDrawPointsToPixels(NULL,255);
544 0 : gw = GDrawCreateTopWindow(NULL,&pos,e_h,&d,&wattrs);
545 :
546 0 : memset(&label,0,sizeof(label));
547 0 : memset(&gcd,0,sizeof(gcd));
548 0 : memset(&boxes,0,sizeof(boxes));
549 :
550 0 : gcd[0].gd.flags = gg_visible | gg_enabled;
551 0 : gcd[0].creator = GFileChooserCreate;
552 0 : hvarray[0] = &gcd[0]; hvarray[1] = NULL;
553 :
554 0 : gcd[1].gd.flags = gg_visible | gg_enabled | gg_but_default;
555 0 : label[1].text = (unichar_t *) _("_Save");
556 0 : label[1].text_is_1byte = true;
557 0 : label[1].text_in_resource = true;
558 0 : gcd[1].gd.label = &label[1];
559 0 : gcd[1].gd.handle_controlevent = GFD_SaveOk;
560 0 : gcd[1].creator = GButtonCreate;
561 0 : barray[0] = GCD_Glue; barray[1] = &gcd[1]; barray[2] = GCD_Glue;
562 :
563 0 : gcd[2].gd.flags = gg_visible | gg_enabled;
564 0 : label[2].text = (unichar_t *) _("_Filter");
565 0 : label[2].text_is_1byte = true;
566 0 : label[2].text_in_resource = true;
567 0 : gcd[2].gd.label = &label[2];
568 0 : gcd[2].gd.handle_controlevent = GFileChooserFilterEh;
569 0 : gcd[2].creator = GButtonCreate;
570 0 : barray[3] = GCD_Glue; barray[4] = &gcd[2]; barray[5] = GCD_Glue;
571 :
572 0 : gcd[3].gd.pos.x = -gcd[1].gd.pos.x; gcd[3].gd.pos.y = 224; gcd[3].gd.pos.width = -1; gcd[3].gd.pos.height = 0;
573 0 : gcd[3].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
574 0 : label[3].text = (unichar_t *) _("_Cancel");
575 0 : label[3].text_is_1byte = true;
576 0 : label[3].text_in_resource = true;
577 0 : gcd[3].gd.label = &label[3];
578 0 : gcd[3].gd.handle_controlevent = GFD_Cancel;
579 0 : gcd[3].creator = GButtonCreate;
580 0 : barray[6] = GCD_Glue; barray[7] = &gcd[3]; barray[8] = GCD_Glue;
581 0 : barray[9] = NULL;
582 :
583 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
584 0 : boxes[2].gd.u.boxelements = barray;
585 0 : boxes[2].creator = GHBoxCreate;
586 0 : hvarray[4] = &boxes[2]; hvarray[5] = NULL;
587 :
588 0 : gcd[4].gd.pos.x = gcd[3].gd.pos.x; gcd[4].gd.pos.y = 194; gcd[4].gd.pos.width = -1; gcd[4].gd.pos.height = 0;
589 0 : gcd[4].gd.flags = gg_visible | gg_enabled;
590 0 : label[4].text = (unichar_t *) S_("Directory|_New");
591 0 : label[4].text_is_1byte = true;
592 0 : label[4].text_in_resource = true;
593 0 : label[4].image = &_GIcon_dir;
594 0 : label[4].image_precedes = false;
595 0 : gcd[4].gd.label = &label[4];
596 0 : gcd[4].gd.handle_controlevent = GFD_NewDir;
597 0 : gcd[4].creator = GButtonCreate;
598 :
599 0 : gcd[5].gd.pos.x = 12; gcd[5].gd.pos.y = 200; gcd[5].gd.pos.width = 0; gcd[5].gd.pos.height = 0;
600 0 : gcd[5].gd.flags = gg_visible | gg_enabled;
601 0 : label[5].text = (unichar_t *) _("Format:");
602 0 : label[5].text_is_1byte = true;
603 0 : gcd[5].gd.label = &label[5];
604 0 : gcd[5].creator = GLabelCreate;
605 0 : harray[0] = &gcd[5];
606 :
607 0 : _format = last_format;
608 0 : if ( bc!=NULL ) {
609 0 : _format-=2;
610 0 : if ( _format<0 || _format>2 ) _format = 0;
611 : }
612 0 : gcd[6].gd.pos.x = 55; gcd[6].gd.pos.y = 194;
613 0 : gcd[6].gd.flags = gg_visible | gg_enabled ;
614 0 : gcd[6].gd.u.list = cur_formats;
615 0 : if ( bc!=NULL ) {
616 0 : bcformats[0].disabled = bc->byte_data;
617 0 : if ( _format==0 ) _format=1;
618 : }
619 0 : gcd[6].gd.label = &cur_formats[_format];
620 0 : gcd[6].gd.u.list[0].selected = true;
621 0 : gcd[6].gd.handle_controlevent = GFD_Format;
622 0 : gcd[6].creator = GListButtonCreate;
623 0 : for ( i=0; cur_formats[i].text!=NULL; ++i )
624 0 : cur_formats[i].selected =false;
625 0 : cur_formats[_format].selected = true;
626 0 : harray[1] = &gcd[6];
627 0 : harray[2] = GCD_Glue;
628 0 : harray[3] = &gcd[4];
629 0 : harray[4] = NULL;
630 :
631 0 : boxes[3].gd.flags = gg_enabled|gg_visible;
632 0 : boxes[3].gd.u.boxelements = harray;
633 0 : boxes[3].creator = GHBoxCreate;
634 0 : hvarray[2] = &boxes[3]; hvarray[3] = NULL;
635 0 : hvarray[6] = NULL;
636 :
637 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
638 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
639 0 : boxes[0].gd.u.boxelements = hvarray;
640 0 : boxes[0].creator = GHVGroupCreate;
641 :
642 0 : GGadgetsCreate(gw,boxes);
643 0 : GGadgetSetUserData(gcd[2].ret,gcd[0].ret);
644 :
645 0 : GHVBoxSetExpandableRow(boxes[0].ret,0);
646 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
647 0 : GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
648 :
649 0 : GFileChooserConnectButtons(gcd[0].ret,gcd[1].ret,gcd[2].ret);
650 0 : if ( bc!=NULL )
651 0 : ext = _format==0 ? "xbm" : _format==1 ? "bmp" : "png";
652 : #ifndef _NO_PYTHON
653 0 : else if ( _format>=fv_pythonbase )
654 0 : ext = py_ie[_format-fv_pythonbase].extension;
655 : #endif
656 : else
657 0 : ext = _format==0?"eps":_format==1?"fig":_format==2?"svg":
658 0 : _format==3?"glif":
659 0 : _format==4?"pdf":_format==5?"plate":
660 0 : _format==6?"xbm":_format==7?"bmp":"png";
661 : #if defined( __CygWin ) || defined(__Mac)
662 : /* Windows file systems are not case conscious */
663 : { char *pt, *bpt, *end;
664 : bpt = buffer; end = buffer+40;
665 : for ( pt=sc->name; *pt!='\0' && bpt<end; ) {
666 : if ( isupper( *pt ))
667 : *bpt++ = '$';
668 : *bpt++ = *pt++;
669 : }
670 : sprintf( bpt, "_%.40s.%s", sc->parent->fontname, ext);
671 : }
672 : #else
673 0 : sprintf( buffer, "%.40s_%.40s.%s", sc->name, sc->parent->fontname, ext);
674 : #endif
675 0 : uc_strcpy(ubuf,buffer);
676 0 : GGadgetSetTitle(gcd[0].ret,ubuf);
677 0 : GFileChooserGetChildren(gcd[0].ret,&pulldown,&files,&tf);
678 0 : GWidgetIndicateFocusGadget(tf);
679 :
680 0 : if ( cur_formats!=formats && cur_formats!=bcformats )
681 0 : GTextInfoListFree(cur_formats);
682 :
683 0 : memset(&d,'\0',sizeof(d));
684 0 : d.sc = sc;
685 0 : d.bc = bc;
686 0 : d.layer = layer;
687 0 : d.gfc = gcd[0].ret;
688 0 : d.format = gcd[6].ret;
689 :
690 0 : GHVBoxFitWindow(boxes[0].ret);
691 :
692 0 : GWidgetHidePalettes();
693 0 : GDrawSetVisible(gw,true);
694 0 : while ( !d.done )
695 0 : GDrawProcessOneEvent(NULL);
696 0 : GDrawDestroyWindow(gw);
697 0 : return(d.ret);
698 : }
699 :
700 0 : int CVExport(CharView *cv) {
701 0 : return( _Export(cv->b.sc,NULL,CVLayer((CharViewBase *)cv)));
702 : }
703 :
704 0 : int BVExport(BitmapView *bv) {
705 0 : return( _Export(bv->bc->sc,bv->bc,ly_fore));
706 : }
|