1 /* Copyright (C) 2002-2012 by George Williams */
2 /*
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are met:
5 
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer.
8 
9  * Redistributions in binary form must reproduce the above copyright notice,
10  * this list of conditions and the following disclaimer in the documentation
11  * and/or other materials provided with the distribution.
12 
13  * The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15 
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <fontforge-config.h>
29 
30 #include "fontforgeui.h"
31 #include "ustring.h"
32 
33 #define CID_Extrema	1000
34 #define CID_Slopes	1001
35 #define CID_Error	1002
36 #define CID_Smooth	1003
37 #define CID_SmoothTan	1004
38 #define CID_SmoothHV	1005
39 #define CID_FlattenBumps	1006
40 #define CID_FlattenBound	1007
41 #define CID_LineLenMax		1008
42 #define CID_Start		1009
43 #define CID_SetAsDefault	1010
44 
45 static double olderr_rat = 1/1000., oldsmooth_tan=.2,
46 	oldlinefixup_rat = 10./1000., oldlinelenmax_rat = 1/100.;
47 static int set_as_default = true;
48 
49 static int oldextrema = false;
50 static int oldslopes = false;
51 static int oldsmooth = true;
52 static int oldsmoothhv = true;
53 static int oldlinefix = false;
54 static int oldstart = false;
55 
56 typedef struct simplifydlg {
57     int flags;
58     double err;
59     double tan_bounds;
60     double linefixup;
61     double linelenmax;
62     int done;
63     int cancelled;
64     int em_size;
65     int set_as_default;
66 } Simple;
67 
Sim_OK(GGadget * g,GEvent * e)68 static int Sim_OK(GGadget *g, GEvent *e) {
69     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
70 	Simple *sim = GDrawGetUserData(GGadgetGetWindow(g));
71 	int badparse=false;
72 	sim->flags = 0;
73 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_Extrema)) )
74 	    sim->flags = sf_ignoreextremum;
75 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_Slopes)) )
76 	    sim->flags |= sf_ignoreslopes;
77 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_Smooth)) )
78 	    sim->flags |= sf_smoothcurves;
79 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_SmoothHV)) )
80 	    sim->flags |= sf_choosehv;
81 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_FlattenBumps)) )
82 	    sim->flags |= sf_forcelines;
83 	if ( GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_Start)) )
84 	    sim->flags |= sf_setstart2extremum;
85 	sim->err = GetReal8(GGadgetGetWindow(g),CID_Error,_("_Error Limit:"),&badparse);
86 	if ( sim->flags&sf_smoothcurves )
87 	    sim->tan_bounds= GetReal8(GGadgetGetWindow(g),CID_SmoothTan,_("_Tangent"),&badparse);
88 	if ( sim->flags&sf_forcelines )
89 	    sim->linefixup= GetReal8(GGadgetGetWindow(g),CID_FlattenBound,_("Bump Size"),&badparse);
90 	sim->linelenmax = GetReal8(GGadgetGetWindow(g),CID_LineLenMax,_("Line length max"),&badparse);
91 	if ( badparse )
92 return( true );
93 	olderr_rat = sim->err/sim->em_size;
94 	oldextrema = (sim->flags&sf_ignoreextremum);
95 	oldslopes = (sim->flags&sf_ignoreslopes);
96 	oldsmooth = (sim->flags&sf_smoothcurves);
97 	oldlinefix = (sim->flags&sf_forcelines);
98 	oldstart = (sim->flags&sf_setstart2extremum);
99 	if ( oldsmooth ) {
100 	    oldsmooth_tan = sim->tan_bounds;
101 	    oldsmoothhv = (sim->flags&sf_choosehv);
102 	}
103 	if ( oldlinefix )
104 	    oldlinefixup_rat = sim->linefixup/sim->em_size;
105 	oldlinelenmax_rat = sim->linelenmax/sim->em_size;
106 	sim->set_as_default = GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_SetAsDefault) );
107 
108 	sim->done = true;
109     }
110 return( true );
111 }
112 
Sim_Cancel(GGadget * g,GEvent * e)113 static int Sim_Cancel(GGadget *g, GEvent *e) {
114     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
115 	Simple *sim = GDrawGetUserData(GGadgetGetWindow(g));
116 	sim->done = sim->cancelled = true;
117     }
118 return( true );
119 }
120 
sim_e_h(GWindow gw,GEvent * event)121 static int sim_e_h(GWindow gw, GEvent *event) {
122     if ( event->type==et_close ) {
123 	Simple *sim = GDrawGetUserData(gw);
124 	sim->done = sim->cancelled = true;
125     } else if ( event->type == et_char ) {
126 return( false );
127     } else if ( event->type == et_map ) {
128 	/* Above palettes */
129 	GDrawRaise(gw);
130     }
131 return( true );
132 }
133 
SimplifyDlg(SplineFont * sf,struct simplifyinfo * smpl)134 int SimplifyDlg(SplineFont *sf, struct simplifyinfo *smpl) {
135     GRect pos;
136     GWindow gw;
137     GWindowAttrs wattrs;
138     GGadgetCreateData gcd[24], boxes[7], *harray1[6], *harray2[6], *harray3[6],
139 	    *harray4[4][6], *barray[9], *varray[18][2];
140     GTextInfo label[24];
141     Simple sim;
142     char buffer[12], buffer2[12], buffer3[12], buffer4[12];
143     int k,l;
144 
145     memset(&sim,0,sizeof(sim));
146     sim.em_size = sf->ascent+sf->descent;
147 
148     memset(&wattrs,0,sizeof(wattrs));
149     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
150     wattrs.event_masks = ~(1<<et_charup);
151     wattrs.restrict_input_to_me = 1;
152     wattrs.undercursor = 1;
153     wattrs.cursor = ct_pointer;
154     wattrs.utf8_window_title = _("Simplify");
155     wattrs.is_dlg = true;
156     pos.x = pos.y = 0;
157     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,180));
158     pos.height = GDrawPointsToPixels(NULL,275);
159     gw = GDrawCreateTopWindow(NULL,&pos,sim_e_h,&sim,&wattrs);
160 
161     memset(&label,0,sizeof(label));
162     memset(&gcd,0,sizeof(gcd));
163     memset(&boxes,0,sizeof(boxes));
164 
165     k=l=0;
166     label[k].text = (unichar_t *) _("_Error Limit:");
167     label[k].text_is_1byte = true;
168     label[k].text_in_resource = true;
169     gcd[k].gd.label = &label[k];
170     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = 12;
171     gcd[k].gd.flags = gg_enabled|gg_visible;
172     gcd[k++].creator = GLabelCreate;
173     harray1[0] = &gcd[k-1];
174 
175     sprintf( buffer, "%.3g", olderr_rat*sim.em_size );
176     label[k].text = (unichar_t *) buffer;
177     label[k].text_is_1byte = true;
178     gcd[k].gd.label = &label[k];
179     gcd[k].gd.pos.x = 70; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
180     gcd[k].gd.pos.width = 40;
181     gcd[k].gd.flags = gg_enabled|gg_visible;
182     gcd[k].gd.cid = CID_Error;
183     gcd[k++].creator = GTextFieldCreate;
184     harray1[1] = &gcd[k-1];
185 
186     gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+gcd[k-1].gd.pos.width+3;
187     gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
188     gcd[k].gd.flags = gg_visible | gg_enabled ;
189     label[k].text = (unichar_t *) _("em-units");
190     label[k].text_is_1byte = true;
191     gcd[k].gd.label = &label[k];
192     gcd[k++].creator = GLabelCreate;
193     harray1[2] = &gcd[k-1]; harray1[3] = GCD_Glue; harray1[4] = NULL;
194 
195     boxes[2].gd.flags = gg_enabled|gg_visible;
196     boxes[2].gd.u.boxelements = harray1;
197     boxes[2].creator = GHBoxCreate;
198     varray[l][0] = &boxes[2]; varray[l++][1] = NULL;
199 
200     label[k].text = (unichar_t *) _("Allow _removal of extrema");
201     label[k].text_is_1byte = true;
202     label[k].text_in_resource = true;
203     gcd[k].gd.label = &label[k];
204     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y+24;
205     gcd[k].gd.flags = gg_enabled|gg_visible;
206     if ( oldextrema )
207 	gcd[k].gd.flags |= gg_cb_on;
208     gcd[k].gd.popup_msg = _("Normally simplify will not remove points at the extrema of curves\n(both PostScript and TrueType suggest you retain these points)");
209     gcd[k].gd.cid = CID_Extrema;
210     gcd[k++].creator = GCheckBoxCreate;
211     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
212 
213     label[k].text = (unichar_t *) _("Allow _slopes to change");
214     label[k].text_is_1byte = true;
215     label[k].text_in_resource = true;
216     gcd[k].gd.label = &label[k];
217     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
218     gcd[k].gd.flags = gg_enabled|gg_visible;
219     if ( oldslopes )
220 	gcd[k].gd.flags |= gg_cb_on;
221     gcd[k].gd.cid = CID_Slopes;
222     gcd[k].gd.popup_msg = _("Normally simplify will not change the slope of the contour at the points.");
223     gcd[k++].creator = GCheckBoxCreate;
224     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
225 
226     label[k].text = (unichar_t *) _("Start contours at e_xtrema");
227     label[k].text_is_1byte = true;
228     label[k].text_in_resource = true;
229     gcd[k].gd.label = &label[k];
230     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
231     gcd[k].gd.flags = gg_enabled|gg_visible;
232     if ( oldstart )
233 	gcd[k].gd.flags |= gg_cb_on;
234     gcd[k].gd.cid = CID_Start;
235     gcd[k].gd.popup_msg = _("If the start point of a contour is not an extremum, find a new start point (on the contour) which is.");
236     gcd[k++].creator = GCheckBoxCreate;
237     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
238 
239     gcd[k].gd.pos.x = 15; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y + 20;
240     gcd[k].gd.pos.width = 150;
241     gcd[k].gd.flags = gg_enabled|gg_visible;
242     gcd[k++].creator = GLineCreate;
243     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
244 
245     label[k].text = (unichar_t *) _("Allow _curve smoothing");
246     label[k].text_is_1byte = true;
247     label[k].text_in_resource = true;
248     gcd[k].gd.label = &label[k];
249     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+4;
250     if ( sf->layers[ly_fore].order2 )
251 	gcd[k].gd.flags = gg_visible;
252     else {
253 	gcd[k].gd.flags = gg_enabled|gg_visible;
254 	if ( oldsmooth )
255 	    gcd[k].gd.flags |= gg_cb_on;
256     }
257     gcd[k].gd.popup_msg = _("Simplify will examine corner points whose control points are almost\ncolinear and smooth them into curve points");
258     gcd[k].gd.cid = CID_Smooth;
259     gcd[k++].creator = GCheckBoxCreate;
260     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
261 
262 /* GT: here "tan" means trigonometric tangent */
263     label[k].text = (unichar_t *) _("if tan less than");
264     label[k].text_is_1byte = true;
265     gcd[k].gd.label = &label[k];
266     gcd[k].gd.pos.x = 20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24;
267     gcd[k].gd.flags = gg_enabled|gg_visible;
268     if ( sf->layers[ly_fore].order2 ) gcd[k].gd.flags = gg_visible;
269     gcd[k++].creator = GLabelCreate;
270     harray2[0] = GCD_HPad10; harray2[1] = &gcd[k-1];
271 
272     sprintf( buffer2, "%.3g", oldsmooth_tan );
273     label[k].text = (unichar_t *) buffer2;
274     label[k].text_is_1byte = true;
275     gcd[k].gd.label = &label[k];
276     gcd[k].gd.pos.x = 94; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
277     gcd[k].gd.pos.width = 40;
278     gcd[k].gd.flags = gg_enabled|gg_visible;
279     if ( sf->layers[ly_fore].order2 ) gcd[k].gd.flags = gg_visible;
280     gcd[k].gd.cid = CID_SmoothTan;
281     gcd[k++].creator = GTextFieldCreate;
282     harray2[2] = &gcd[k-1]; harray2[3] = GCD_Glue; harray2[4] = NULL;
283 
284     boxes[3].gd.flags = gg_enabled|gg_visible;
285     boxes[3].gd.u.boxelements = harray2;
286     boxes[3].creator = GHBoxCreate;
287     varray[l][0] = &boxes[3]; varray[l++][1] = NULL;
288 
289     label[k].text = (unichar_t *) _("S_nap to horizontal/vertical");
290     label[k].text_is_1byte = true;
291     label[k].text_in_resource = true;
292     gcd[k].gd.label = &label[k];
293     gcd[k].gd.pos.x = 17; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24;
294     if ( sf->layers[ly_fore].order2 )
295 	gcd[k].gd.flags = gg_visible;
296     else {
297 	gcd[k].gd.flags = gg_enabled|gg_visible;
298 	if ( oldsmoothhv )
299 	    gcd[k].gd.flags |= gg_cb_on;
300     }
301     gcd[k].gd.popup_msg = _("If the slope of an adjusted point is near horizontal or vertical\nsnap to that");
302     gcd[k].gd.cid = CID_SmoothHV;
303     gcd[k++].creator = GCheckBoxCreate;
304     harray3[0] = GCD_HPad10; harray3[1] = &gcd[k-1]; harray3[2] = GCD_Glue; harray3[3] = NULL;
305 
306     boxes[4].gd.flags = gg_enabled|gg_visible;
307     boxes[4].gd.u.boxelements = harray3;
308     boxes[4].creator = GHBoxCreate;
309     varray[l][0] = &boxes[4]; varray[l++][1] = NULL;
310 
311     label[k].text = (unichar_t *) _("_Flatten bumps on lines");
312     label[k].text_is_1byte = true;
313     label[k].text_in_resource = true;
314     gcd[k].gd.label = &label[k];
315     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
316     if ( sf->layers[ly_fore].order2 )
317 	gcd[k].gd.flags = gg_visible;
318     else {
319 	gcd[k].gd.flags = gg_enabled|gg_visible;
320 	if ( oldlinefix )
321 	    gcd[k].gd.flags |= gg_cb_on;
322     }
323     gcd[k].gd.popup_msg = _("If a line has a bump on it then flatten out that bump");
324     gcd[k].gd.cid = CID_FlattenBumps;
325     gcd[k++].creator = GCheckBoxCreate;
326     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
327 
328     label[k].text = (unichar_t *) _("if smaller than");
329     label[k].text_is_1byte = true;
330     gcd[k].gd.label = &label[k];
331     gcd[k].gd.pos.x = 20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24;
332     gcd[k].gd.flags = gg_enabled|gg_visible;
333     if ( sf->layers[ly_fore].order2 ) gcd[k].gd.flags = gg_visible;
334     gcd[k++].creator = GLabelCreate;
335     harray4[0][0] = GCD_HPad10; harray4[0][1] = &gcd[k-1];
336 
337     sprintf( buffer3, "%.3g", oldlinefixup_rat*sim.em_size );
338     label[k].text = (unichar_t *) buffer3;
339     label[k].text_is_1byte = true;
340     gcd[k].gd.label = &label[k];
341     gcd[k].gd.pos.x = 90; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
342     gcd[k].gd.pos.width = 40;
343     gcd[k].gd.flags = gg_enabled|gg_visible;
344     if ( sf->layers[ly_fore].order2 ) gcd[k].gd.flags = gg_visible;
345     gcd[k].gd.cid = CID_FlattenBound;
346     gcd[k++].creator = GTextFieldCreate;
347     harray4[0][2] = &gcd[k-1];
348 
349     gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+gcd[k-1].gd.pos.width+3;
350     gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
351     gcd[k].gd.flags = gg_visible | gg_enabled ;
352     if ( sf->layers[ly_fore].order2 ) gcd[k].gd.flags = gg_visible;
353     label[k].text = (unichar_t *) _("em-units");
354     label[k].text_is_1byte = true;
355     gcd[k].gd.label = &label[k];
356     gcd[k++].creator = GLabelCreate;
357     harray4[0][3] = &gcd[k-1]; harray4[0][4] = GCD_Glue; harray4[0][5] = NULL;
358 
359 
360     label[k].text = (unichar_t *) _("Don't smooth lines");
361     label[k].text_is_1byte = true;
362     gcd[k].gd.label = &label[k];
363     gcd[k].gd.pos.x = 8; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+14;
364     gcd[k].gd.flags = gg_enabled|gg_visible;
365     gcd[k++].creator = GLabelCreate;
366     harray4[1][0] = &gcd[k-1]; harray4[1][1] = harray4[1][2] = harray4[1][3] = GCD_ColSpan;
367     harray4[1][4] = GCD_Glue; harray4[1][5] = NULL;
368 
369     label[k].text = (unichar_t *) _("longer than");
370     label[k].text_is_1byte = true;
371     gcd[k].gd.label = &label[k];
372     gcd[k].gd.pos.x = 20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+24;
373     gcd[k].gd.flags = gg_enabled|gg_visible;
374     gcd[k++].creator = GLabelCreate;
375     harray4[2][0] = GCD_HPad10; harray4[2][1] = &gcd[k-1];
376 
377     sprintf( buffer4, "%.3g", oldlinelenmax_rat*sim.em_size );
378     label[k].text = (unichar_t *) buffer4;
379     label[k].text_is_1byte = true;
380     gcd[k].gd.label = &label[k];
381     gcd[k].gd.pos.x = 90; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y-6;
382     gcd[k].gd.pos.width = 40;
383     gcd[k].gd.flags = gg_enabled|gg_visible;
384     gcd[k].gd.cid = CID_LineLenMax;
385     gcd[k++].creator = GTextFieldCreate;
386     harray4[2][2] = &gcd[k-1];
387 
388     gcd[k].gd.pos.x = gcd[k-1].gd.pos.x+gcd[k-1].gd.pos.width+3;
389     gcd[k].gd.pos.y = gcd[k-2].gd.pos.y;
390     gcd[k].gd.flags = gg_visible | gg_enabled ;
391     label[k].text = (unichar_t *) _("em-units");
392     label[k].text_is_1byte = true;
393     gcd[k].gd.label = &label[k];
394     gcd[k++].creator = GLabelCreate;
395     harray4[2][3] = &gcd[k-1]; harray4[2][4] = GCD_Glue; harray4[2][5] = NULL;
396     harray4[3][0] = NULL;
397 
398     boxes[5].gd.flags = gg_enabled|gg_visible;
399     boxes[5].gd.u.boxelements = harray4[0];
400     boxes[5].creator = GHVBoxCreate;
401     varray[l][0] = &boxes[5]; varray[l++][1] = NULL;
402 
403     gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+20;
404     gcd[k].gd.flags = gg_visible | gg_enabled | (set_as_default ? gg_cb_on : 0);
405     label[k].text = (unichar_t *) _("Set as Default");
406     label[k].text_is_1byte = true;
407     gcd[k].gd.label = &label[k];
408     gcd[k].gd.cid = CID_SetAsDefault;
409     gcd[k++].creator = GCheckBoxCreate;
410     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
411 
412     gcd[k].gd.pos.x = 15; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y + 20;
413     gcd[k].gd.pos.width = 150;
414     gcd[k].gd.flags = gg_enabled|gg_visible;
415     gcd[k++].creator = GLineCreate;
416     varray[l][0] = &gcd[k-1]; varray[l++][1] = NULL;
417 
418     gcd[k].gd.pos.x = 20-3; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+30;
419     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
420     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
421     label[k].text = (unichar_t *) _("_OK");
422     label[k].text_is_1byte = true;
423     label[k].text_in_resource = true;
424     gcd[k].gd.mnemonic = 'O';
425     gcd[k].gd.label = &label[k];
426     gcd[k].gd.handle_controlevent = Sim_OK;
427     gcd[k++].creator = GButtonCreate;
428     barray[0] = GCD_Glue; barray[1] = &gcd[k-1]; barray[2] = GCD_Glue;
429 
430     gcd[k].gd.pos.x = -20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
431     gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
432     gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
433     label[k].text = (unichar_t *) _("_Cancel");
434     label[k].text_is_1byte = true;
435     label[k].text_in_resource = true;
436     gcd[k].gd.label = &label[k];
437     gcd[k].gd.mnemonic = 'C';
438     gcd[k].gd.handle_controlevent = Sim_Cancel;
439     gcd[k++].creator = GButtonCreate;
440     barray[3] = GCD_Glue; barray[4] = &gcd[k-1]; barray[5] = GCD_Glue; barray[6] = NULL;
441 
442     boxes[6].gd.flags = gg_enabled|gg_visible;
443     boxes[6].gd.u.boxelements = barray;
444     boxes[6].creator = GHBoxCreate;
445     varray[l][0] = &boxes[6]; varray[l++][1] = NULL;
446     varray[l][0] = NULL;
447 
448     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
449     boxes[0].gd.flags = gg_enabled|gg_visible;
450     boxes[0].gd.u.boxelements = varray[0];
451     boxes[0].creator = GHVGroupCreate;
452 
453     GGadgetsCreate(gw,boxes);
454     GWidgetIndicateFocusGadget(GWidgetGetControl(gw,CID_Error));
455     GTextFieldSelect(GWidgetGetControl(gw,CID_Error),0,-1);
456     GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
457     GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
458     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
459     GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
460     GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
461     GHVBoxFitWindow(boxes[0].ret);
462 
463     GWidgetHidePalettes();
464     GDrawSetVisible(gw,true);
465     while ( !sim.done )
466 	GDrawProcessOneEvent(NULL);
467     GDrawDestroyWindow(gw);
468     if ( sim.cancelled )
469 return( false );
470 
471     smpl->flags = sim.flags;
472     smpl->err = sim.err;
473     smpl->tan_bounds = sim.tan_bounds;
474     smpl->linefixup = sim.linefixup;
475     smpl->linelenmax = sim.linelenmax;
476     smpl->set_as_default = sim.set_as_default;
477     set_as_default = sim.set_as_default;
478 return( true );
479 }
480