Line data Source code
1 : /* Copyright (C) 2003-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 "dumppfa.h"
28 : #include "encoding.h"
29 : #include "fontforgeui.h"
30 : #include "fvfonts.h"
31 : #include "macenc.h"
32 : #include "mm.h"
33 : #include "mem.h"
34 : #include "parsettf.h"
35 : #include "psread.h"
36 : #include "sfd.h"
37 : #include "splinefill.h"
38 : #include "splineutil.h"
39 : #include "splineutil2.h"
40 : #include "tottfvar.h"
41 : #include <ustring.h>
42 : #include <math.h>
43 : #include <gkeysym.h>
44 : #include <locale.h>
45 : #include <utype.h>
46 : #include "ttf.h"
47 : #include "mm.h"
48 :
49 : /* As far as I can tell, the CDV in AdobeSansMM is half gibberish */
50 : /* This is disturbing */
51 : /* But at least the CDV in Type1_supp.pdf for Myriad appears correct */
52 : static char *standard_cdvs[5] = {
53 : /* 0 axes? Impossible */
54 : "{}",
55 : /* 1 axis */
56 : "{\n"
57 : " 1 1 index sub 2 1 roll\n"
58 : " 0 index 2 1 roll\n"
59 : " pop\n"
60 : "}",
61 : /* 2 axes */
62 : "{\n"
63 : " 1 2 index sub 1 2 index sub mul 3 1 roll\n"
64 : " 1 index 1 2 index sub mul 3 1 roll\n"
65 : " 1 2 index sub 1 index mul 3 1 roll\n"
66 : " 1 index 1 index mul 3 1 roll\n"
67 : " pop pop\n"
68 : "}",
69 : /* 3 axes */
70 : "{\n"
71 : " 1 3 index sub 1 3 index sub mul 1 2 index sub mul 4 1 roll\n"
72 : " 2 index 1 3 index sub mul 1 2 index sub mul 4 1 roll\n"
73 : " 1 3 index sub 2 index mul 1 2 index sub mul 4 1 roll\n"
74 : " 2 index 2 index mul 1 2 index sub mul 4 1 roll\n"
75 : " 1 3 index sub 1 3 index sub mul 1 index mul 4 1 roll\n"
76 : " 2 index 1 3 index sub mul 1 index mul 4 1 roll\n"
77 : " 1 3 index sub 2 index mul 1 index mul 4 1 roll\n"
78 : " 2 index 2 index mul 1 index mul 4 1 roll\n"
79 : " pop pop pop\n"
80 : "}",
81 : /* 4 axes */
82 : /* This requires too big a string. We must build it at runtime */
83 : NULL
84 : };
85 : static char *cdv_4axis[3] = {
86 : "{\n"
87 : " 1 4 index sub 1 4 index sub mul 1 3 index sub mul 1 2 index sub mul 5 1 roll\n"
88 : " 3 index 1 4 index sub mul 1 3 index sub mul 1 2 index sub mul 5 1 roll\n"
89 : " 1 4 index sub 3 index mul 1 3 index sub mul 1 2 index sub mul 5 1 roll\n"
90 : " 3 index 3 index mul 1 3 index sub mul 1 2 index sub mul 5 1 roll\n"
91 : " 1 4 index sub 1 4 index sub mul 2 index mul 1 2 index sub mul 5 1 roll\n"
92 : " 3 index 1 4 index sub mul 2 index mul 1 2 index sub mul 5 1 roll\n",
93 : " 1 4 index sub 3 index mul 2 index mul 1 2 index sub mul 5 1 roll\n"
94 : " 3 index 3 index mul 2 index mul 1 2 index sub mul 5 1 roll\n"
95 : " 1 4 index sub 1 4 index sub mul 1 3 index sub mul 1 index mul 5 1 roll\n"
96 : " 3 index 1 4 index sub mul 1 3 index sub mul 1 index mul 5 1 roll\n"
97 : " 1 4 index sub 3 index mul 1 3 index sub mul 1 index mul 5 1 roll\n",
98 : " 3 index 3 index mul 1 3 index sub mul 1 index mul 5 1 roll\n"
99 : " 1 4 index sub 1 4 index sub mul 2 index mul 1 index mul 5 1 roll\n"
100 : " 3 index 1 4 index sub mul 2 index mul 1 index mul 5 1 roll\n"
101 : " 1 4 index sub 3 index mul 2 index mul 1 index mul 5 1 roll\n"
102 : " 3 index 3 index mul 2 index mul 1 index mul 5 1 roll\n"
103 : " pop pop pop pop\n"
104 : "}"
105 : };
106 :
107 : static char *axistablab[] = { N_("Axis 1"), N_("Axis 2"), N_("Axis 3"), N_("Axis 4") };
108 :
109 0 : static int ExecConvertDesignVector(real *designs, int dcnt, char *ndv, char *cdv,
110 : real *stack) {
111 : char *temp, dv[101];
112 : int j, len, cnt;
113 :
114 : /* PostScript parses things in "C" locale too */
115 : locale_t tmplocale; locale_t oldlocale; // Declare temporary locale storage.
116 0 : switch_to_c_locale(&tmplocale, &oldlocale); // Switch to the C locale temporarily and cache the old locale.
117 0 : len = 0;
118 0 : for ( j=0; j<dcnt; ++j ) {
119 0 : sprintf(dv+len, "%g ", (double) designs[j]);
120 0 : len += strlen(dv+len);
121 : }
122 0 : switch_to_old_locale(&tmplocale, &oldlocale); // Switch to the cached locale.
123 :
124 0 : temp = malloc(len+strlen(ndv)+strlen(cdv)+20);
125 0 : strcpy(temp,dv);
126 : /*strcpy(temp+len++," ");*/ /* dv always will end in a space */
127 :
128 0 : while ( isspace(*ndv)) ++ndv;
129 0 : if ( *ndv=='{' )
130 0 : ++ndv;
131 0 : strcpy(temp+len,ndv);
132 0 : len += strlen(temp+len);
133 0 : while ( len>0 && (temp[len-1]==' '||temp[len-1]=='\n') ) --len;
134 0 : if ( len>0 && temp[len-1]=='}' ) --len;
135 :
136 0 : while ( isspace(*cdv)) ++cdv;
137 0 : if ( *cdv=='{' )
138 0 : ++cdv;
139 0 : strcpy(temp+len,cdv);
140 0 : len += strlen(temp+len);
141 0 : while ( len>0 && (temp[len-1]==' '||temp[len-1]=='\n') ) --len;
142 0 : if ( len>0 && temp[len-1]=='}' ) --len;
143 :
144 0 : cnt = EvaluatePS(temp,stack,MmMax);
145 0 : free(temp);
146 0 : return( cnt );
147 : }
148 :
149 0 : static int StandardPositions(MMSet *mm,int instance_count, int axis_count,int isapple) {
150 : int i,j,factor,v;
151 :
152 0 : if ( !isapple ) {
153 0 : for ( i=0; i<instance_count; ++i ) {
154 0 : for ( j=0; j<axis_count; ++j )
155 0 : if ( mm->positions[i*mm->axis_count+j]!= ( (i&(1<<j)) ? 1 : 0 ))
156 0 : return( false );
157 : }
158 : } else {
159 0 : for ( i=0; i<instance_count; ++i ) {
160 0 : factor = 1;
161 0 : for ( j=0; j<axis_count; ++j ) {
162 0 : v = (i/factor)%3 -1;
163 0 : if ( mm->positions[i*mm->axis_count+j]!= v )
164 0 : return( false );
165 0 : factor *= 3;
166 : }
167 : }
168 : }
169 0 : return( true );
170 : }
171 :
172 0 : static int OrderedPositions(MMSet *mm,int instance_count, int isapple) {
173 : /* For a 1 axis system, check that the positions are ordered */
174 : int i;
175 :
176 0 : if ( mm->positions[0]!=isapple?-1:0 ) /* must start at 0 */
177 0 : return( false );
178 0 : if ( mm->positions[(instance_count-1)*4]!=1 ) /* and end at 1 */
179 0 : return( false );
180 0 : for ( i=1; i<mm->instance_count; ++i )
181 0 : if ( mm->positions[i*mm->axis_count]<=mm->positions[(i-1)*mm->axis_count] )
182 0 : return( false );
183 :
184 0 : return( true );
185 : }
186 :
187 0 : static unichar_t *MMDesignCoords(MMSet *mm) {
188 : char buffer[80], *pt;
189 : int i;
190 : real axiscoords[4];
191 :
192 0 : if ( mm->instance_count!=(1<<mm->axis_count) ||
193 0 : !StandardPositions(mm,mm->instance_count,mm->axis_count,false))
194 0 : return( uc_copy(""));
195 0 : MMWeightsUnMap(mm->defweights,axiscoords,mm->axis_count);
196 0 : pt = buffer;
197 0 : for ( i=0; i<mm->axis_count; ++i ) {
198 0 : sprintf( pt,"%g ", (double) MMAxisUnmap(mm,i,axiscoords[i]));
199 0 : pt += strlen(pt);
200 : }
201 0 : pt[-1] = ' ';
202 0 : return( uc_copy( buffer ));
203 : }
204 :
205 0 : static real DoDelta(int16 **deltas,int pt,int is_y,real *blends,int instance_count) {
206 0 : real diff = 0;
207 : int j;
208 :
209 0 : for ( j=0; j<instance_count; ++j ) {
210 0 : if ( blends[j]!=0 && deltas[2*j+is_y]!=NULL )
211 0 : diff += blends[j]*deltas[2*j+is_y][pt];
212 : }
213 0 : return( diff );
214 : }
215 :
216 0 : static void DistortChar(SplineFont *sf,MMSet *mm,int gid,real *blends) {
217 : int i,j,ptcnt;
218 : int16 **deltas;
219 : SplineSet *ss;
220 : SplinePoint *sp;
221 : RefChar *ref;
222 0 : SplineChar *sc = sf->glyphs[gid];
223 : Spline *s, *first;
224 :
225 0 : if ( sc==NULL )
226 0 : return;
227 0 : deltas = SCFindDeltas(mm,gid,&ptcnt);
228 0 : if ( deltas==NULL )
229 0 : return;
230 : /* I never delta the left side bearing or top */
231 0 : sc->width += DoDelta(deltas,ptcnt-3,0,blends,mm->instance_count);
232 0 : sc->vwidth += DoDelta(deltas,ptcnt-1,1,blends,mm->instance_count);
233 0 : if ( sc->layers[ly_fore].refs!=NULL ) {
234 0 : for ( i=0,ref = sc->layers[ly_fore].refs; ref!=NULL; ref=ref->next, ++i ) {
235 0 : ref->transform[4] += DoDelta(deltas,i,0,blends,mm->instance_count);
236 0 : ref->transform[5] += DoDelta(deltas,i,1,blends,mm->instance_count);
237 : }
238 : } else {
239 0 : for ( ss=sc->layers[ly_fore].splines; ss!=NULL; ss=ss->next ) {
240 0 : for ( sp=ss->first;; ) {
241 0 : if ( sp->ttfindex!=0xffff ) {
242 0 : sp->me.x += DoDelta(deltas,sp->ttfindex,0,blends,mm->instance_count);
243 0 : sp->me.y += DoDelta(deltas,sp->ttfindex,1,blends,mm->instance_count);
244 : }
245 0 : if ( sp->nextcpindex!=0xffff ) {
246 0 : sp->nextcp.x += DoDelta(deltas,sp->nextcpindex,0,blends,mm->instance_count);
247 0 : sp->nextcp.y += DoDelta(deltas,sp->nextcpindex,1,blends,mm->instance_count);
248 : } else
249 0 : sp->nextcp = sp->me;
250 0 : if ( sp->next!=NULL )
251 0 : sp->next->to->prevcp = sp->nextcp;
252 0 : if ( sp->next==NULL )
253 0 : break;
254 0 : sp = sp->next->to;
255 0 : if ( sp==ss->first )
256 0 : break;
257 0 : }
258 0 : for ( sp=ss->first;; ) {
259 0 : if ( sp->ttfindex==0xffff ) {
260 0 : sp->me.x = (sp->prevcp.x+sp->nextcp.x)/2;
261 0 : sp->me.y = (sp->prevcp.y+sp->nextcp.y)/2;
262 : }
263 0 : if ( sp->next==NULL )
264 0 : break;
265 0 : sp = sp->next->to;
266 0 : if ( sp==ss->first )
267 0 : break;
268 0 : }
269 0 : first = NULL;
270 0 : for ( s=ss->first->next; s!=NULL && s!=first; s=s->to->next ) {
271 0 : SplineRefigure(s);
272 0 : if ( first==NULL ) first = s;
273 : }
274 : }
275 : }
276 0 : for ( j=0; j<2*mm->instance_count; ++j )
277 0 : free( deltas[j]);
278 0 : free(deltas);
279 : }
280 :
281 0 : static void DistortCvt(struct ttf_table *cvt,MMSet *mm,real *blends) {
282 : int i,j,ptcnt;
283 : real diff;
284 : int16 **deltas;
285 :
286 0 : deltas = CvtFindDeltas(mm,&ptcnt);
287 0 : if ( deltas==NULL )
288 0 : return;
289 0 : for ( i=0; i<ptcnt; ++i ) {
290 0 : diff = 0;
291 0 : for ( j=0; j<mm->instance_count; ++j ) {
292 0 : if ( blends[j]!=0 && deltas[j]!=NULL )
293 0 : diff += blends[j]*deltas[j][i];
294 : }
295 0 : memputshort(cvt->data,2*i,memushort(cvt->data,cvt->len,2*i)+rint(diff));
296 : }
297 0 : for ( j=0; j<mm->instance_count; ++j )
298 0 : free( deltas[j]);
299 0 : free(deltas);
300 : }
301 :
302 0 : static void MakeAppleBlend(FontView *fv,MMSet *mm,real *blends,real *normalized) {
303 0 : SplineFont *base = mm->normal;
304 0 : SplineFont *sf = _MMNewFont(mm,-2,base->familyname,normalized);
305 : int i;
306 0 : struct ttf_table *tab, *cvt=NULL, *last=NULL, *cur;
307 : RefChar *ref;
308 :
309 0 : sf->mm = NULL;
310 0 : for ( i=0; i<base->glyphcnt && i<sf->glyphcnt; ++i ) if ( base->glyphs[i]!=NULL ) {
311 0 : sf->glyphs[i] = SplineCharCopy(base->glyphs[i],base,NULL);
312 0 : for ( ref=sf->glyphs[i]->layers[ly_fore].refs; ref!=NULL; ref=ref->next )
313 0 : ref->sc = NULL;
314 0 : sf->glyphs[i]->orig_pos = i;
315 0 : DistortChar(sf,mm,i,blends);
316 : }
317 0 : for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL )
318 0 : ttfFixupRef(sf->glyphs,i);
319 0 : for ( tab=base->ttf_tables; tab!=NULL; tab=tab->next ) {
320 0 : cur = chunkalloc(sizeof(struct ttf_table));
321 0 : cur->tag = tab->tag;
322 0 : cur->len = tab->len;
323 0 : cur->data = malloc(tab->len);
324 0 : memcpy(cur->data,tab->data,tab->len);
325 0 : if ( cur->tag==CHR('c','v','t',' '))
326 0 : cvt = cur;
327 0 : if ( last==NULL )
328 0 : sf->ttf_tables = cur;
329 : else
330 0 : last->next = cur;
331 0 : last = cur;
332 : }
333 0 : if ( cvt!=NULL )
334 0 : DistortCvt(cvt,mm,blends);
335 : /* I don't know how to blend kerns */
336 : /* Apple's Skia has 5 kerning classes (one for the base font and one for */
337 : /* some of the instances) and the classes have different glyph classes */
338 : /* I can't make a kern class out of them. I suppose I could generate a bunch */
339 : /* of kern pairs, but ug. */
340 : /* Nor is it clear whether the kerning info is a delta or not */
341 :
342 0 : sf->changed = true;
343 0 : EncMapFree(sf->map);
344 0 : sf->map = EncMapFromEncoding(sf,fv->b.map->enc);
345 0 : FontViewCreate(sf,false);
346 0 : }
347 :
348 : struct mmcb {
349 : int done;
350 : GWindow gw;
351 : MMSet *mm;
352 : FontView *fv;
353 : int tonew;
354 : };
355 :
356 : #define CID_Explicit 6001
357 : #define CID_ByDesign 6002
358 : #define CID_NewBlends 6003
359 : #define CID_NewDesign 6004
360 : #define CID_Knowns 6005
361 :
362 0 : static GTextInfo *MMCB_KnownValues(MMSet *mm) {
363 0 : GTextInfo *ti = calloc(mm->named_instance_count+2,sizeof(GTextInfo));
364 : int i;
365 :
366 0 : ti[0].text = uc_copy(" --- ");
367 0 : ti[0].bg = ti[0].fg = COLOR_DEFAULT;
368 0 : for ( i=0; i<mm->named_instance_count; ++i ) {
369 0 : ti[i+1].text = (unichar_t *) PickNameFromMacName(mm->named_instances[i].names);
370 0 : ti[i+1].text_is_1byte = true;
371 0 : ti[i+1].bg = ti[i+1].fg = COLOR_DEFAULT;
372 : }
373 0 : return( ti );
374 : }
375 :
376 0 : static int MMCB_PickedKnown(GGadget *g, GEvent *e) {
377 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
378 0 : struct mmcb *mmcb = GDrawGetUserData(GGadgetGetWindow(g));
379 0 : int which = GGadgetGetFirstListSelectedItem(g);
380 : char buffer[24];
381 : int i;
382 : unichar_t *temp;
383 :
384 0 : --which;
385 0 : if ( which<0 )
386 0 : return( true );
387 0 : for ( i=0; i<mmcb->mm->axis_count; ++i ) {
388 0 : sprintf( buffer, "%.4g", (double) mmcb->mm->named_instances[which].coords[i]);
389 0 : temp = uc_copy(buffer);
390 0 : GGadgetSetTitle(GWidgetGetControl(mmcb->gw,1000+i),temp);
391 0 : free(temp);
392 : }
393 : }
394 0 : return( true );
395 : }
396 :
397 0 : static int MMCB_Changed(GGadget *g, GEvent *e) {
398 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
399 0 : GWindow gw = GGadgetGetWindow(g);
400 0 : int explicitblends = GGadgetIsChecked(GWidgetGetControl(gw,CID_Explicit));
401 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NewBlends),explicitblends);
402 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NewDesign),!explicitblends);
403 : }
404 0 : return( true );
405 : }
406 :
407 0 : static int GetWeights(GWindow gw, real blends[MmMax], MMSet *mm,
408 : int instance_count, int axis_count) {
409 0 : int explicitblends = GGadgetIsChecked(GWidgetGetControl(gw,CID_Explicit));
410 0 : const unichar_t *ret = _GGadgetGetTitle(GWidgetGetControl(gw,
411 : explicitblends?CID_NewBlends:CID_NewDesign)), *upt;
412 : unichar_t *uend;
413 : int i;
414 : real sum;
415 :
416 0 : sum = 0;
417 0 : for ( i=0, upt = ret; i<instance_count && *upt; ++i ) {
418 0 : blends[i] = u_strtod(upt,&uend);
419 0 : sum += blends[i];
420 0 : if ( upt==uend )
421 0 : break;
422 0 : upt = uend;
423 0 : while ( *upt==',' || *upt==' ' ) ++upt;
424 : }
425 0 : if ( (explicitblends && i!=instance_count ) ||
426 0 : (!explicitblends && i!=axis_count ) ||
427 0 : *upt!='\0' ) {
428 0 : ff_post_error(_("Bad MM Weights"),_("Incorrect number of instances weights, or illegal numbers"));
429 0 : return(false);
430 : }
431 0 : if ( explicitblends ) {
432 0 : if ( sum<.99 || sum>1.01 ) {
433 0 : ff_post_error(_("Bad MM Weights"),_("The weights for the default version of the font must sum to 1.0"));
434 0 : return(false);
435 : }
436 : } else {
437 0 : i = ExecConvertDesignVector(blends, i, mm->ndv, mm->cdv,
438 : blends);
439 0 : if ( i!=instance_count ) {
440 0 : ff_post_error(_("Bad MM Weights"),_("The results produced by applying the NormalizeDesignVector and ConvertDesignVector functions were not the results expected. You may need to change these functions"));
441 0 : return(false);
442 : }
443 : }
444 0 : return( true );
445 : }
446 :
447 0 : static int MMCB_OKApple(GGadget *g, GEvent *e) {
448 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
449 0 : struct mmcb *mmcb = GDrawGetUserData(GGadgetGetWindow(g));
450 : real newcoords[4];
451 0 : int i, j, k, err=false;
452 : real blends[AppleMmMax];
453 0 : MMSet *mm = mmcb->mm;
454 :
455 0 : for ( i=0; i<mm->axis_count; ++i )
456 0 : newcoords[i] = rint(GetReal8(mmcb->gw,1000+i,_(axistablab[i]),&err)*8096)/8096;
457 0 : if ( err )
458 0 : return( true );
459 : /* Now normalize each */
460 0 : for ( i=0; i<mm->axis_count; ++i ) {
461 0 : for ( j=1; j<mm->axismaps[i].points; ++j ) {
462 0 : if ( newcoords[i]<=mm->axismaps[i].designs[j] || j==mm->axismaps[i].points-1 ) {
463 0 : if ( mm->axismaps[i].designs[j]==mm->axismaps[i].designs[j-1] )
464 0 : newcoords[i] = mm->axismaps[i].blends[j];
465 : else
466 0 : newcoords[i] = mm->axismaps[i].blends[j-1] +
467 0 : (newcoords[i]-mm->axismaps[i].designs[j-1])/
468 0 : (mm->axismaps[i].designs[j]-mm->axismaps[i].designs[j-1]) *
469 0 : (mm->axismaps[i].blends[j]-mm->axismaps[i].blends[j-1]);
470 0 : newcoords[i] = rint(8096*newcoords[i])/8096; /* Apple's fixed numbers have a fair amount of rounding error */
471 0 : break;
472 : }
473 : }
474 : }
475 : /* Now figure out the contribution of each design */
476 0 : for ( k=0; k<mm->instance_count; ++k ) {
477 0 : real factor = 1.0;
478 0 : for ( i=0; i<mm->axis_count; ++i ) {
479 0 : if ( (newcoords[i]<=0 && mm->positions[k*mm->axis_count+i]>0) ||
480 0 : (newcoords[i]>=0 && mm->positions[k*mm->axis_count+i]<0)) {
481 0 : factor = 0;
482 0 : break;
483 : }
484 0 : if ( newcoords[i]==0 )
485 0 : continue;
486 0 : if ( newcoords[i]<0 )
487 0 : factor *= -newcoords[i];
488 : else
489 0 : factor *= newcoords[i];
490 : }
491 0 : blends[k] = factor;
492 : }
493 0 : MakeAppleBlend(mmcb->fv,mm,blends,newcoords);
494 0 : mmcb->done = true;
495 : }
496 0 : return( true );
497 : }
498 :
499 0 : static int MMCB_OK(GGadget *g, GEvent *e) {
500 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
501 0 : struct mmcb *mmcb = GDrawGetUserData(GGadgetGetWindow(g));
502 : real blends[MmMax];
503 :
504 0 : if ( !GetWeights(mmcb->gw, blends, mmcb->mm, mmcb->mm->instance_count, mmcb->mm->axis_count))
505 0 : return( true );
506 0 : MMCreateBlendedFont(mmcb->mm,(FontViewBase *) mmcb->fv,blends,mmcb->tonew );
507 : }
508 0 : return( true );
509 : }
510 :
511 0 : static int MMCB_Cancel(GGadget *g, GEvent *e) {
512 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
513 0 : struct mmcb *mmcb = GDrawGetUserData(GGadgetGetWindow(g));
514 0 : mmcb->done = true;
515 : }
516 0 : return( true );
517 : }
518 :
519 0 : static int mmcb_e_h(GWindow gw, GEvent *event) {
520 0 : if ( event->type==et_close ) {
521 0 : struct mmcb *mmcb = GDrawGetUserData(gw);
522 0 : mmcb->done = true;
523 0 : } else if ( event->type==et_char ) {
524 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
525 0 : help("mmmenu.html");
526 0 : return( true );
527 : }
528 0 : return( false );
529 : }
530 0 : return( true );
531 : }
532 :
533 0 : static int GCDFillupMacWeights(GGadgetCreateData *gcd, GTextInfo *label, int k,
534 : char *axisnames[4], char axisval[4][24],
535 : real *defcoords,int axis_count,MMSet *mm) {
536 : int i;
537 : char *an;
538 : char axisrange[80];
539 :
540 0 : for ( i=0; i<axis_count; ++i ) {
541 0 : sprintf( axisrange, " [%.4g %.4g %.4g]", (double) mm->axismaps[i].min,
542 0 : (double) mm->axismaps[i].def, (double) mm->axismaps[i].max );
543 0 : an = PickNameFromMacName(mm->axismaps[i].axisnames);
544 0 : if ( an==NULL )
545 0 : an = copy(mm->axes[i]);
546 0 : axisnames[i] = malloc(strlen(axisrange)+3+strlen(an));
547 0 : strcpy(axisnames[i],an);
548 0 : strcat(axisnames[i],axisrange);
549 0 : sprintf(axisval[i],"%.4g", (double) defcoords[i]);
550 0 : free(an);
551 : }
552 0 : for ( ; i<4; ++i ) {
553 0 : axisnames[i] = _(axistablab[i]);
554 0 : axisval[i][0] = '\0';
555 : }
556 :
557 0 : for ( i=0; i<4; ++i ) {
558 0 : label[k].text = (unichar_t *) axisnames[i];
559 0 : label[k].text_is_1byte = true;
560 0 : gcd[k].gd.label = &label[k];
561 0 : gcd[k].gd.pos.x = 5; gcd[k].gd.pos.y = k==0 ? 4 : gcd[k-1].gd.pos.y+28;
562 0 : gcd[k].gd.flags = i<axis_count ? (gg_visible | gg_enabled) : gg_visible;
563 0 : gcd[k++].creator = GLabelCreate;
564 :
565 0 : label[k].text = (unichar_t *) axisval[i];
566 0 : label[k].text_is_1byte = true;
567 0 : gcd[k].gd.label = &label[k];
568 0 : gcd[k].gd.pos.x = 15; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+12;
569 0 : gcd[k].gd.flags = gcd[k-1].gd.flags;
570 0 : gcd[k].gd.cid = 1000+i;
571 0 : gcd[k++].creator = GTextFieldCreate;
572 : }
573 0 : return( k );
574 : }
575 :
576 0 : void MMChangeBlend(MMSet *mm,FontView *fv,int tonew) {
577 : char buffer[MmMax*20], *pt;
578 : unichar_t ubuf[MmMax*20];
579 : int i, k, j, def_name;
580 : struct mmcb mmcb;
581 : GRect pos;
582 : GWindow gw;
583 : GWindowAttrs wattrs;
584 : GGadgetCreateData gcd[14];
585 : GTextInfo label[14];
586 : unichar_t *utemp;
587 : char axisval[4][24];
588 : char *axisnames[4];
589 : real defcoords[4];
590 :
591 0 : if ( mm==NULL )
592 0 : return;
593 :
594 0 : memset(&mmcb,0,sizeof(mmcb));
595 0 : mmcb.mm = mm;
596 0 : mmcb.fv = fv;
597 0 : mmcb.tonew = tonew;
598 :
599 0 : memset(&wattrs,0,sizeof(wattrs));
600 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
601 0 : wattrs.event_masks = ~(1<<et_charup);
602 0 : wattrs.is_dlg = true;
603 0 : wattrs.restrict_input_to_me = true;
604 0 : wattrs.undercursor = 1;
605 0 : wattrs.cursor = ct_pointer;
606 0 : wattrs.utf8_window_title = tonew ? _("Blend to New Font"):_("MM Change Def Weights");
607 0 : pos.x = pos.y = 0;
608 :
609 0 : if ( !mm->apple ) {
610 0 : pt = buffer;
611 0 : for ( i=0; i<mm->instance_count; ++i ) {
612 0 : sprintf( pt, "%g ", (double) mm->defweights[i]);
613 0 : pt += strlen(pt);
614 : }
615 0 : if ( pt>buffer )
616 0 : pt[-2] = '\0';
617 0 : uc_strcpy(ubuf,buffer);
618 :
619 0 : pos.width =GDrawPointsToPixels(NULL,GGadgetScale(270));
620 0 : pos.height = GDrawPointsToPixels(NULL,200);
621 0 : mmcb.gw = gw = GDrawCreateTopWindow(NULL,&pos,mmcb_e_h,&mmcb,&wattrs);
622 :
623 0 : memset(&gcd,0,sizeof(gcd));
624 0 : memset(&label,0,sizeof(label));
625 :
626 0 : k=0;
627 : /* GT: The following strings should be concatenated together, the result */
628 : /* GT: translated, and then broken into lines by hand. I'm sure it would */
629 : /* GT: be better to specify this all as one string, but my widgets won't support */
630 : /* GT: that */
631 0 : label[k].text = (unichar_t *) (tonew ? _("You may specify the new instance of this font") : _("You may change the default instance of this font"));
632 0 : label[k].text_is_1byte = true;
633 0 : gcd[k].gd.label = &label[k];
634 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = 10;
635 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
636 0 : gcd[k++].creator = GLabelCreate;
637 :
638 0 : label[k].text = (unichar_t *) _("either by explicitly entering the contribution");
639 0 : label[k].text_is_1byte = true;
640 0 : gcd[k].gd.label = &label[k];
641 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+13;
642 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
643 0 : gcd[k++].creator = GLabelCreate;
644 :
645 0 : label[k].text = (unichar_t *) _("of each master design, or by entering the design");
646 0 : label[k].text_is_1byte = true;
647 0 : gcd[k].gd.label = &label[k];
648 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+13;
649 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
650 0 : gcd[k++].creator = GLabelCreate;
651 :
652 0 : label[k].text = (unichar_t *) _("values for each axis");
653 0 : label[k].text_is_1byte = true;
654 0 : gcd[k].gd.label = &label[k];
655 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+13;
656 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
657 0 : gcd[k++].creator = GLabelCreate;
658 :
659 0 : label[k].text = (unichar_t *) _("Contribution of each master design");
660 0 : label[k].text_is_1byte = true;
661 0 : gcd[k].gd.label = &label[k];
662 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+16;
663 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_cb_on;
664 0 : gcd[k].gd.cid = CID_Explicit;
665 0 : gcd[k].gd.handle_controlevent = MMCB_Changed;
666 0 : gcd[k++].creator = GRadioCreate;
667 :
668 0 : label[k].text = (unichar_t *) _("Design Axis Values");
669 0 : label[k].text_is_1byte = true;
670 0 : gcd[k].gd.label = &label[k];
671 0 : gcd[k].gd.pos.x = 10; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+45;
672 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
673 0 : gcd[k].gd.cid = CID_ByDesign;
674 0 : gcd[k].gd.handle_controlevent = MMCB_Changed;
675 0 : gcd[k++].creator = GRadioCreate;
676 :
677 0 : label[k].text = ubuf;
678 0 : gcd[k].gd.label = &label[k];
679 0 : gcd[k].gd.pos.x = 15; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y+18;
680 0 : gcd[k].gd.pos.width = 240;
681 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
682 0 : gcd[k].gd.cid = CID_NewBlends;
683 0 : gcd[k++].creator = GTextFieldCreate;
684 :
685 0 : label[k].text = utemp = MMDesignCoords(mm);
686 0 : gcd[k].gd.label = &label[k];
687 0 : gcd[k].gd.pos.x = 15; gcd[k].gd.pos.y = gcd[k-2].gd.pos.y+18;
688 0 : gcd[k].gd.pos.width = 240;
689 0 : gcd[k].gd.flags = gg_visible;
690 0 : gcd[k].gd.cid = CID_NewDesign;
691 0 : gcd[k++].creator = GTextFieldCreate;
692 :
693 0 : gcd[k].gd.pos.x = 30-3; gcd[k].gd.pos.y = GDrawPixelsToPoints(NULL,pos.height)-35-3;
694 0 : gcd[k].gd.pos.width = -1;
695 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
696 0 : label[k].text = (unichar_t *) _("_OK");
697 0 : label[k].text_is_1byte = true;
698 0 : label[k].text_in_resource = true;
699 0 : gcd[k].gd.label = &label[k];
700 0 : gcd[k].gd.handle_controlevent = MMCB_OK;
701 0 : gcd[k++].creator = GButtonCreate;
702 :
703 0 : gcd[k].gd.pos.x = -30; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
704 0 : gcd[k].gd.pos.width = -1;
705 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
706 0 : label[k].text = (unichar_t *) _("_Cancel");
707 0 : label[k].text_is_1byte = true;
708 0 : label[k].text_in_resource = true;
709 0 : gcd[k].gd.label = &label[k];
710 0 : gcd[k].gd.handle_controlevent = MMCB_Cancel;
711 0 : gcd[k++].creator = GButtonCreate;
712 :
713 0 : gcd[k].gd.pos.x = 2; gcd[k].gd.pos.y = 2;
714 0 : gcd[k].gd.pos.width = pos.width-4; gcd[k].gd.pos.height = pos.height-4;
715 0 : gcd[k].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
716 0 : gcd[k].creator = GGroupCreate;
717 :
718 0 : GGadgetsCreate(gw,gcd);
719 0 : free(utemp);
720 : } else {
721 0 : pos.width =GDrawPointsToPixels(NULL,GGadgetScale(270));
722 0 : pos.height = GDrawPointsToPixels(NULL,200);
723 0 : mmcb.gw = gw = GDrawCreateTopWindow(NULL,&pos,mmcb_e_h,&mmcb,&wattrs);
724 :
725 0 : memset(&gcd,0,sizeof(gcd));
726 0 : memset(&label,0,sizeof(label));
727 :
728 0 : memset(defcoords,0,sizeof(defcoords));
729 0 : for ( i=0; i<mm->axis_count; ++i )
730 0 : defcoords[i] = mm->axismaps[i].def;
731 0 : def_name = -1;
732 0 : for ( i=0; i<mm->named_instance_count; ++i ) {
733 0 : for ( j=0; j<mm->axis_count; ++j )
734 0 : if ( !RealNear(mm->named_instances[i].coords[j],defcoords[j]))
735 0 : break;
736 0 : if ( j==mm->axis_count ) {
737 0 : def_name = i;
738 0 : break;
739 : }
740 : }
741 :
742 0 : k=0;
743 0 : k = GCDFillupMacWeights(gcd,label,k,axisnames,axisval,defcoords,
744 : mm->axis_count,mm);
745 :
746 0 : gcd[k].gd.pos.x = 130; gcd[k].gd.pos.y = gcd[k-4].gd.pos.y-12;
747 0 : gcd[k].gd.flags = gg_visible | gg_enabled;
748 0 : if ( mm->named_instance_count==0 )
749 0 : gcd[k].gd.flags = 0;
750 0 : gcd[k].gd.u.list = MMCB_KnownValues(mm);
751 0 : if ( def_name!=-1 )
752 0 : gcd[k].gd.u.list[def_name+1].selected = true;
753 0 : gcd[k].gd.cid = CID_Knowns;
754 0 : gcd[k].gd.handle_controlevent = MMCB_PickedKnown;
755 0 : gcd[k++].creator = GListButtonCreate;
756 :
757 0 : gcd[k].gd.pos.x = 30-3; gcd[k].gd.pos.y = GDrawPixelsToPoints(NULL,pos.height)-35-3;
758 0 : gcd[k].gd.pos.width = -1;
759 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
760 0 : label[k].text = (unichar_t *) _("_OK");
761 0 : label[k].text_is_1byte = true;
762 0 : label[k].text_in_resource = true;
763 0 : gcd[k].gd.label = &label[k];
764 0 : gcd[k].gd.handle_controlevent = MMCB_OKApple;
765 0 : gcd[k++].creator = GButtonCreate;
766 :
767 0 : gcd[k].gd.pos.x = -30; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
768 0 : gcd[k].gd.pos.width = -1;
769 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
770 0 : label[k].text = (unichar_t *) _("_Cancel");
771 0 : label[k].text_is_1byte = true;
772 0 : label[k].text_in_resource = true;
773 0 : gcd[k].gd.label = &label[k];
774 0 : gcd[k].gd.handle_controlevent = MMCB_Cancel;
775 0 : gcd[k++].creator = GButtonCreate;
776 :
777 0 : gcd[k].gd.pos.x = 2; gcd[k].gd.pos.y = 2;
778 0 : gcd[k].gd.pos.width = pos.width-4; gcd[k].gd.pos.height = pos.height-4;
779 0 : gcd[k].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
780 0 : gcd[k++].creator = GGroupCreate;
781 :
782 0 : GGadgetsCreate(gw,gcd);
783 0 : for ( i=0; i<mm->axis_count; ++i )
784 0 : free(axisnames[i]);
785 0 : GTextInfoListFree(gcd[k-4].gd.u.list);
786 0 : GWidgetIndicateFocusGadget(gcd[1].ret);
787 : }
788 :
789 0 : GDrawSetVisible(gw,true);
790 :
791 0 : while ( !mmcb.done )
792 0 : GDrawProcessOneEvent(NULL);
793 0 : GDrawDestroyWindow(gw);
794 : }
795 :
796 : GTextInfo axiscounts[] = {
797 : { (unichar_t *) "1", NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
798 : { (unichar_t *) "2", NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
799 : { (unichar_t *) "3", NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
800 : { (unichar_t *) "4", NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
801 : GTEXTINFO_EMPTY
802 : };
803 :
804 : /* These names are fixed by Adobe & Apple and are not subject to translation */
805 : GTextInfo axistypes[] = {
806 : { (unichar_t *) "Weight", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
807 : { (unichar_t *) "Width", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
808 : { (unichar_t *) "OpticalSize", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
809 : { (unichar_t *) "Slant", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
810 : GTEXTINFO_EMPTY
811 : };
812 :
813 : GTextInfo mastercounts[] = {
814 : { (unichar_t *) "1", NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
815 : { (unichar_t *) "2", NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
816 : { (unichar_t *) "3", NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
817 : { (unichar_t *) "4", NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
818 : { (unichar_t *) "5", NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
819 : { (unichar_t *) "6", NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
820 : { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
821 : { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
822 : { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
823 : { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
824 : { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
825 : { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
826 : { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
827 : { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
828 : { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
829 : { (unichar_t *) "16", NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
830 : { (unichar_t *) "17", NULL, 0, 0, (void *) 17, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
831 : { (unichar_t *) "18", NULL, 0, 0, (void *) 18, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
832 : { (unichar_t *) "19", NULL, 0, 0, (void *) 19, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
833 : { (unichar_t *) "20", NULL, 0, 0, (void *) 20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
834 : { (unichar_t *) "21", NULL, 0, 0, (void *) 21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
835 : { (unichar_t *) "22", NULL, 0, 0, (void *) 22, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
836 : { (unichar_t *) "23", NULL, 0, 0, (void *) 23, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
837 : { (unichar_t *) "24", NULL, 0, 0, (void *) 24, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
838 : { (unichar_t *) "25", NULL, 0, 0, (void *) 25, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
839 : { (unichar_t *) "26", NULL, 0, 0, (void *) 26, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
840 : { (unichar_t *) "27", NULL, 0, 0, (void *) 27, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
841 : #if AppleMmMax!=26
842 : #error "The mastercounts array needs to be expanded to match AppleMmMax"
843 : /* Actually it should be one bigger than AppleMmMax */
844 : #endif
845 : GTEXTINFO_EMPTY
846 : };
847 :
848 : enum mmw_state { mmw_counts, mmw_axes, mmw_designs, mmw_named, mmw_funcs,
849 : mmw_others };
850 :
851 : typedef struct mmw {
852 : GWindow gw;
853 : enum mmw_state state;
854 : GWindow subwins[mmw_others+1];
855 : MMSet *mm, *old;
856 : int isnew;
857 : int done;
858 : int old_axis_count, old_adobe;
859 : int axis_count, instance_count; /* The data in mm are set to the max for each */
860 : int last_instance_count, last_axis_count, lastw_instance_count;
861 : struct axismap last_axismaps[4];
862 : int canceldrop, subheightdiff;
863 : int lcnt, lmax;
864 : SplineFont **loaded;
865 : } MMW;
866 :
867 : #define MMW_Width 340
868 : #define MMW_Height 300
869 : #define ESD_Width 262
870 : #define ESD_Height 316
871 :
872 : #define CID_OK 1001
873 : #define CID_Prev 1002
874 : #define CID_Next 1003
875 : #define CID_Cancel 1004
876 : #define CID_Group 1005
877 :
878 : #define CID_AxisCount 2001
879 : #define CID_MasterCount 2002
880 : #define CID_Adobe 2003
881 : #define CID_Apple 2004
882 :
883 : #define CID_WhichAxis 3000
884 : #define CID_AxisType 3001 /* +[0,3]*100 */
885 : #define CID_AxisBegin 3002 /* +[0,3]*100 */
886 : #define CID_AxisDefault 3003 /* +[0,3]*100 */
887 : #define CID_AxisDefaultLabel 3004 /* +[0,3]*100 */
888 : #define CID_AxisEnd 3005 /* +[0,3]*100 */
889 : #define CID_IntermediateDesign 3006 /* +[0,3]*100 */
890 : #define CID_IntermediateNormalized 3007 /* +[0,3]*100 */
891 :
892 : #define DesignScaleFactor 20
893 :
894 : #define CID_WhichDesign 4000
895 : #define CID_DesignFonts 4001 /* +[0,26]*DesignScaleFactor */
896 : #define CID_AxisWeights 4002 /* +[0,26]*DesignScaleFactor */
897 :
898 : #define CID_NDV 5002
899 : #define CID_CDV 5003
900 :
901 : /* CID_Explicit-CID_NewDesign already defined */
902 : #define CID_ForceBoldThreshold 6005
903 : #define CID_FamilyName 6006
904 :
905 : #define CID_NamedDesigns 7001
906 : #define CID_NamedNew 7002
907 : #define CID_NamedEdit 7003
908 : #define CID_NamedDelete 7004
909 :
910 : struct esd {
911 : GWindow gw;
912 : MMW *mmw;
913 : GGadget *list;
914 : int index;
915 : int done;
916 : };
917 :
918 0 : static void ESD_Close(struct esd *esd) {
919 0 : MacNameListFree(NameGadgetsGetNames(esd->gw));
920 0 : esd->done = true;
921 0 : }
922 :
923 0 : static int ESD_Cancel(GGadget *g, GEvent *e) {
924 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
925 0 : struct esd *esd = GDrawGetUserData(GGadgetGetWindow(g));
926 0 : ESD_Close(esd);
927 : }
928 0 : return( true );
929 : }
930 :
931 0 : static int ESD_OK(GGadget *g, GEvent *e) {
932 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
933 0 : struct esd *esd = GDrawGetUserData(GGadgetGetWindow(g));
934 : int i,axis_count;
935 0 : int err = false;
936 : real coords[4];
937 : struct macname *mn;
938 : char buffer[120], *pt;
939 : unichar_t *name; char *style;
940 :
941 0 : for ( i=0; i<esd->mmw->axis_count && i<4; ++i )
942 0 : coords[i] = rint(GetReal8(esd->gw,1000+i,_(axistablab[i]),&err)*8096)/8096;
943 0 : if ( err )
944 0 : return( true );
945 0 : axis_count = i;
946 0 : mn = NameGadgetsGetNames(esd->gw);
947 0 : if ( mn==NULL ) {
948 0 : ff_post_error(_("Bad Multiple Master Font"),_("You must provide at least one name here"));
949 0 : return( true );
950 : }
951 0 : pt = buffer; *pt++ = ' '; *pt++ = '[';
952 0 : for ( i=0; i<axis_count; ++i ) {
953 0 : sprintf(pt, "%g ", (double) coords[i]);
954 0 : pt += strlen(pt);
955 : }
956 0 : pt[-1] = ']';
957 0 : *pt = '\0';
958 0 : style = PickNameFromMacName(mn);
959 0 : name = malloc(((pt-buffer) + strlen(style) + 1)*sizeof(unichar_t));
960 0 : utf82u_strcpy(name,style);
961 0 : uc_strcat(name,buffer);
962 0 : free(style);
963 0 : if ( esd->index==-1 )
964 0 : GListAppendLine(esd->list,name,false)->userdata = mn;
965 : else {
966 0 : GTextInfo *ti = GGadgetGetListItem(esd->list,esd->index);
967 0 : MacNameListFree(ti->userdata);
968 0 : GListChangeLine(esd->list,esd->index,name)->userdata = mn;
969 : }
970 0 : esd->done = true;
971 0 : free(name);
972 : }
973 0 : return( true );
974 : }
975 :
976 0 : static int esd_eh(GWindow gw, GEvent *event) {
977 0 : if ( event->type==et_close ) {
978 0 : struct esd *esd = GDrawGetUserData(gw);
979 0 : ESD_Close(esd);
980 0 : } else if ( event->type==et_char ) {
981 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
982 0 : help("multiplemaster.html#NamedStyles");
983 0 : return( true );
984 0 : } else if ( GMenuIsCommand(event,H_("Quit|Ctl+Q") )) {
985 0 : MenuExit(NULL,NULL,NULL);
986 0 : return( true );
987 0 : } else if ( GMenuIsCommand(event,H_("Close|Ctl+Shft+Q") )) {
988 0 : ESD_Close(GDrawGetUserData(gw));
989 0 : return( true );
990 : }
991 0 : return( false );
992 : }
993 0 : return( true );
994 : }
995 :
996 0 : static void EditStyleName(MMW *mmw,int index) {
997 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_named],CID_NamedDesigns);
998 0 : GTextInfo *ti = NULL;
999 : int i,k;
1000 0 : unichar_t *pt = NULL, *end;
1001 : real axes[4];
1002 0 : struct macname *mn = NULL;
1003 : char axisval[4][24];
1004 : char *axisnames[4];
1005 : GGadgetCreateData gcd[17];
1006 : GTextInfo label[17];
1007 : GRect pos;
1008 : GWindow gw;
1009 : GWindowAttrs wattrs;
1010 : struct esd esd;
1011 :
1012 0 : for ( i=0; i<mmw->axis_count; ++i )
1013 0 : axes[i] = mmw->mm->axismaps[i].def;
1014 0 : if ( index != -1 ) {
1015 0 : ti = GGadgetGetListItem(list,index);
1016 0 : if ( ti!=NULL ) {
1017 0 : pt = u_strchr(ti->text,'[');
1018 0 : mn = ti->userdata;
1019 : }
1020 0 : if ( pt!=NULL ) {
1021 0 : for ( i=0, ++pt; i<4 && (*pt!=']' && *pt!='\0'); ++i ) {
1022 0 : axes[i] = u_strtod(pt,&end);
1023 0 : pt = end;
1024 : }
1025 : }
1026 : }
1027 :
1028 0 : memset(&esd,0,sizeof(esd));
1029 0 : esd.mmw = mmw;
1030 0 : esd.index = index;
1031 0 : esd.list = list;
1032 :
1033 0 : memset(&wattrs,0,sizeof(wattrs));
1034 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
1035 0 : wattrs.event_masks = ~(1<<et_charup);
1036 0 : wattrs.is_dlg = true;
1037 0 : wattrs.restrict_input_to_me = true;
1038 0 : wattrs.undercursor = 1;
1039 0 : wattrs.cursor = ct_pointer;
1040 0 : wattrs.utf8_window_title = _("Named Styles");
1041 0 : pos.x = pos.y = 0;
1042 0 : pos.width =GDrawPointsToPixels(NULL,GGadgetScale(ESD_Width));
1043 0 : pos.height = GDrawPointsToPixels(NULL,ESD_Height);
1044 0 : esd.gw = gw = GDrawCreateTopWindow(NULL,&pos,esd_eh,&esd,&wattrs);
1045 :
1046 0 : memset(gcd,0,sizeof(gcd));
1047 0 : memset(label,0,sizeof(label));
1048 0 : k = 0;
1049 :
1050 0 : k = GCDFillupMacWeights(gcd,label,k,axisnames,axisval,axes,
1051 : mmw->axis_count,mmw->mm);
1052 0 : k = GCDBuildNames(gcd,label,k,mn);
1053 :
1054 0 : gcd[k].gd.pos.x = 20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+33-3;
1055 0 : gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
1056 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
1057 0 : label[k].text = (unichar_t *) _("_OK");
1058 0 : label[k].text_is_1byte = true;
1059 0 : label[k].text_in_resource = true;
1060 0 : gcd[k].gd.label = &label[k];
1061 0 : gcd[k].gd.handle_controlevent = ESD_OK;
1062 0 : gcd[k++].creator = GButtonCreate;
1063 :
1064 0 : gcd[k].gd.pos.x = -20; gcd[k].gd.pos.y = gcd[k-1].gd.pos.y+3;
1065 0 : gcd[k].gd.pos.width = -1; gcd[k].gd.pos.height = 0;
1066 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
1067 0 : label[k].text = (unichar_t *) _("_Cancel");
1068 0 : label[k].text_is_1byte = true;
1069 0 : label[k].text_in_resource = true;
1070 0 : gcd[k].gd.label = &label[k];
1071 0 : gcd[k].gd.handle_controlevent = ESD_Cancel;
1072 0 : gcd[k++].creator = GButtonCreate;
1073 :
1074 0 : gcd[k].gd.pos.x = 2; gcd[k].gd.pos.y = 2;
1075 0 : gcd[k].gd.pos.width = pos.width-4; gcd[k].gd.pos.height = pos.height-4;
1076 0 : gcd[k].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
1077 0 : gcd[k].creator = GGroupCreate;
1078 :
1079 0 : GGadgetsCreate(gw,gcd);
1080 :
1081 0 : for ( i=0; i<mmw->axis_count; ++i )
1082 0 : free( axisnames[i]);
1083 :
1084 0 : GDrawSetVisible(gw,true);
1085 :
1086 0 : while ( !esd.done )
1087 0 : GDrawProcessOneEvent(NULL);
1088 :
1089 0 : GDrawDestroyWindow(gw);
1090 0 : }
1091 :
1092 0 : static void SetMasterToAxis(MMW *mmw, int initial) {
1093 : int i, cnt, def, isadobe;
1094 :
1095 0 : cnt = GGadgetGetFirstListSelectedItem(GWidgetGetControl(mmw->subwins[mmw_counts],CID_AxisCount))
1096 : +1;
1097 0 : isadobe = GGadgetIsChecked(GWidgetGetControl(mmw->subwins[mmw_counts],CID_Adobe));
1098 0 : if ( cnt!=mmw->old_axis_count || isadobe!=mmw->old_adobe ) {
1099 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_counts],CID_MasterCount);
1100 : int32 len;
1101 0 : GTextInfo **ti = GGadgetGetList(list,&len);
1102 0 : if ( isadobe ) {
1103 0 : for ( i=0; i<MmMax; ++i )
1104 0 : ti[i]->disabled = (i+1) < (1<<cnt);
1105 0 : for ( ; i<AppleMmMax+1 ; ++i )
1106 0 : ti[i]->disabled = true;
1107 0 : def = (1<<cnt);
1108 : } else {
1109 0 : for ( i=0; i<AppleMmMax+1; ++i )
1110 0 : ti[i]->disabled = (i+1) < cnt;
1111 0 : def = 1;
1112 0 : for ( i=0; i<cnt; ++i )
1113 0 : def *= 3;
1114 0 : if ( def>AppleMmMax+1 )
1115 0 : def = AppleMmMax+1;
1116 : }
1117 0 : if ( !initial )
1118 0 : GGadgetSelectOneListItem(list,def-1);
1119 0 : mmw->old_axis_count = cnt;
1120 0 : mmw->old_adobe = isadobe;
1121 : }
1122 0 : }
1123 :
1124 0 : static int MMW_AxisCntChanged(GGadget *g, GEvent *e) {
1125 :
1126 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
1127 0 : SetMasterToAxis(GDrawGetUserData(GGadgetGetWindow(g)),false);
1128 : }
1129 0 : return( true );
1130 : }
1131 :
1132 0 : static int MMW_TypeChanged(GGadget *g, GEvent *e) {
1133 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
1134 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
1135 0 : int isapple = GGadgetIsChecked(GWidgetGetControl(mmw->subwins[mmw_counts],CID_Apple));
1136 : int i;
1137 0 : SetMasterToAxis(mmw,false);
1138 0 : for ( i=0; i<4; ++i ) {
1139 0 : GGadgetSetEnabled(GWidgetGetControl(mmw->subwins[mmw_axes],CID_AxisDefault+i*100),isapple);
1140 0 : GGadgetSetEnabled(GWidgetGetControl(mmw->subwins[mmw_axes],CID_AxisDefaultLabel+i*100),isapple);
1141 0 : NameGadgetsSetEnabled(GTabSetGetSubwindow(
1142 0 : GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),i),isapple);
1143 : }
1144 : }
1145 0 : return( true );
1146 : }
1147 :
1148 0 : static void MMUsurpNew(SplineFont *sf) {
1149 : /* This is a font that wasn't in the original MMSet */
1150 : /* We ARE going to use it in the final result */
1151 : /* So if it is attached to a fontview, we must close that window and */
1152 : /* claim the splinefont for ourselves */
1153 : FontView *fv, *nextfv;
1154 :
1155 0 : if ( sf->fv!=NULL ) {
1156 0 : if ( sf->kcld!=NULL )
1157 0 : KCLD_End(sf->kcld);
1158 0 : if ( sf->vkcld!=NULL )
1159 0 : KCLD_End(sf->vkcld);
1160 0 : sf->kcld = sf->vkcld = NULL;
1161 :
1162 0 : for ( fv=(FontView *) sf->fv; fv!=NULL; fv=nextfv ) {
1163 0 : nextfv = (FontView *) (fv->b.nextsame);
1164 0 : fv->b.nextsame = NULL;
1165 0 : _FVCloseWindows(fv);
1166 0 : fv->b.sf = NULL;
1167 0 : GDrawDestroyWindow(fv->gw);
1168 : }
1169 0 : sf->fv = NULL;
1170 0 : SFClearAutoSave(sf);
1171 : }
1172 0 : }
1173 :
1174 0 : static void MMDetachNew(SplineFont *sf) {
1175 : /* This is a font that wasn't in the original MMSet */
1176 : /* We aren't going to use it in the final result */
1177 : /* If it is attached to a fontview, then the fontview retains control */
1178 : /* If not, then free it */
1179 0 : if ( sf->fv==NULL )
1180 0 : SplineFontFree(sf);
1181 0 : }
1182 :
1183 0 : static void MMDetachOld(SplineFont *sf) {
1184 : /* This is a font that was in the original MMSet */
1185 : /* We aren't going to use it in the final result */
1186 : /* So then free it */
1187 0 : sf->mm = NULL;
1188 0 : SplineFontFree(sf);
1189 0 : }
1190 :
1191 0 : static void MMW_Close(MMW *mmw) {
1192 : int i;
1193 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_named],CID_NamedDesigns);
1194 : int32 len;
1195 0 : GTextInfo **ti = GGadgetGetList(list,&len);
1196 :
1197 0 : for ( i=0; i<len; ++i )
1198 0 : if ( ti[i]->userdata!=NULL )
1199 0 : MacNameListFree(ti[i]->userdata);
1200 0 : for ( i=0; i<4; ++i )
1201 0 : MacNameListFree(NameGadgetsGetNames(GTabSetGetSubwindow(
1202 0 : GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),i)));
1203 0 : for ( i=0; i<mmw->lcnt; ++i )
1204 0 : MMDetachNew(mmw->loaded[i]);
1205 0 : free(mmw->loaded);
1206 0 : for ( i=0; i<4; ++i )
1207 0 : mmw->mm->axismaps[i].axisnames = NULL;
1208 0 : MMSetFreeContents(mmw->mm);
1209 0 : chunkfree(mmw->mm,sizeof(MMSet));
1210 0 : mmw->done = true;
1211 0 : }
1212 :
1213 0 : static int MMW_Cancel(GGadget *g, GEvent *e) {
1214 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1215 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
1216 0 : MMW_Close(mmw);
1217 : }
1218 0 : return( true );
1219 : }
1220 :
1221 0 : static void MMW_SetState(MMW *mmw) {
1222 : unsigned int i;
1223 :
1224 0 : GDrawSetVisible(mmw->subwins[mmw->state],true);
1225 0 : for ( i=mmw_counts; i<=mmw_others; ++i )
1226 0 : if ( i!=mmw->state )
1227 0 : GDrawSetVisible(mmw->subwins[i],false);
1228 :
1229 0 : GGadgetSetEnabled(GWidgetGetControl(mmw->gw,CID_Prev),mmw->state!=mmw_counts);
1230 0 : GGadgetSetEnabled(GWidgetGetControl(mmw->gw,CID_Next),
1231 0 : mmw->state!=mmw_others && mmw->state!=mmw_named);
1232 0 : GGadgetSetEnabled(GWidgetGetControl(mmw->gw,CID_OK),
1233 0 : mmw->state==mmw_others || mmw->state==mmw_named);
1234 0 : }
1235 :
1236 0 : static int ParseWeights(GWindow gw,int cid, char *str,
1237 : real *list, int expected, int tabset_cid, int aspect ) {
1238 0 : int cnt=0;
1239 : const unichar_t *ret, *pt; unichar_t *endpt;
1240 :
1241 0 : ret= _GGadgetGetTitle(GWidgetGetControl(gw,cid));
1242 :
1243 0 : for ( pt=ret; *pt==' '; ++pt );
1244 0 : for ( ; *pt; ) {
1245 0 : list[cnt++] = u_strtod(pt,&endpt);
1246 0 : if ( pt==endpt || ( *endpt!='\0' && *endpt!=' ' )) {
1247 0 : if ( tabset_cid!=-1 )
1248 0 : GTabSetSetSel(GWidgetGetControl(gw,tabset_cid),aspect);
1249 0 : ff_post_error(_("Bad Axis"),_("Bad Number in %s"), str);
1250 0 : return( 0 );
1251 : }
1252 0 : for ( pt = endpt; *pt==' '; ++pt );
1253 : }
1254 0 : if ( cnt!=expected && expected!=-1 ) {
1255 0 : if ( tabset_cid!=-1 )
1256 0 : GTabSetSetSel(GWidgetGetControl(gw,tabset_cid),aspect);
1257 0 : ff_post_error(_("Bad Axis"),_("Wrong number of entries in %s"), str);
1258 0 : return( 0 );
1259 : }
1260 :
1261 0 : return( cnt );
1262 : }
1263 :
1264 0 : static int ParseList(GWindow gw,int cid, char *str8, int *err, real start,
1265 : real def, real end, real **_list, int tabset_cid, int aspect,
1266 : int isapple ) {
1267 : int i, cnt;
1268 : const unichar_t *ret, *pt; unichar_t *endpt;
1269 : real *list, val;
1270 0 : int defdone = false;
1271 :
1272 0 : *_list = NULL;
1273 :
1274 0 : ret= _GGadgetGetTitle(GWidgetGetControl(gw,cid));
1275 0 : for ( pt=ret; *pt==' '; ++pt );
1276 0 : cnt = *pt=='\0'?0:1 ;
1277 0 : for ( ; *pt; ++pt ) {
1278 0 : if ( *pt==' ' ) ++cnt;
1279 0 : while ( *pt==' ' ) ++pt;
1280 : }
1281 0 : if ( start!=end )
1282 0 : cnt+=2;
1283 0 : if ( isapple && start!=end )
1284 0 : ++cnt;
1285 0 : if ( !isapple || start==end )
1286 0 : defdone = true;
1287 0 : list = malloc(cnt*sizeof(real));
1288 0 : if ( start==end )
1289 0 : cnt = 0;
1290 : else {
1291 0 : list[0] = start;
1292 0 : cnt = 1;
1293 : }
1294 :
1295 0 : for ( pt=ret; *pt==' '; ++pt );
1296 0 : for ( ; *pt; ) {
1297 0 : val = u_strtod(pt,&endpt);
1298 0 : if ( !defdone && val>def ) {
1299 0 : list[cnt++] = def;
1300 0 : defdone = true;
1301 : }
1302 0 : list[cnt++] = val;
1303 0 : if ( pt==endpt || ( *endpt!='\0' && *endpt!=' ' )) {
1304 0 : GTabSetSetSel(GWidgetGetControl(gw,tabset_cid),aspect);
1305 0 : free(list);
1306 0 : ff_post_error(_("Bad Axis"),_("Bad Number in %s"), str8);
1307 0 : *err = true;
1308 0 : return( 0 );
1309 : }
1310 0 : for ( pt = endpt; *pt==' '; ++pt );
1311 : }
1312 0 : if ( start!=end )
1313 0 : list[cnt++] = end;
1314 0 : for ( i=1; i<cnt; ++i )
1315 0 : if ( list[i-1]>list[i] ) {
1316 0 : GTabSetSetSel(GWidgetGetControl(gw,tabset_cid),aspect);
1317 0 : ff_post_error(_("Bad Axis"),_("The %s list is not ordered"), str8);
1318 0 : free(list);
1319 0 : *err = true;
1320 0 : return( 0 );
1321 : }
1322 :
1323 0 : *_list = list;
1324 0 : return( cnt );
1325 : }
1326 :
1327 0 : static char *_ChooseFonts(char *buffer, SplineFont **sfs, real *positions,
1328 : int i, int cnt) {
1329 0 : char *elsepart=NULL, *ret;
1330 : int pos;
1331 : int k;
1332 :
1333 0 : if ( i<cnt-2 )
1334 0 : elsepart = _ChooseFonts(buffer,sfs,positions,i+1,cnt);
1335 :
1336 0 : pos = 0;
1337 0 : if ( positions[i]!=0 ) {
1338 0 : sprintf(buffer, "%g sub ", (double) positions[i]);
1339 0 : pos += strlen(buffer);
1340 : }
1341 0 : sprintf(buffer+pos, "%g div dup 1 sub exch ", (double) (positions[i+1]-positions[i]));
1342 0 : pos += strlen( buffer+pos );
1343 0 : for ( k=0; k<i; ++k ) {
1344 0 : strcpy(buffer+pos, "0 ");
1345 0 : pos += 2;
1346 : }
1347 0 : if ( i!=0 ) {
1348 0 : sprintf(buffer+pos, "%d -2 roll ", i+2 );
1349 0 : pos += strlen(buffer+pos);
1350 : }
1351 0 : for ( k=i+2; k<cnt; ++k ) {
1352 0 : strcpy(buffer+pos, "0 ");
1353 0 : pos += 2;
1354 : }
1355 :
1356 0 : if ( elsepart==NULL )
1357 0 : return( copy(buffer));
1358 :
1359 0 : ret = malloc(strlen(buffer)+strlen(elsepart)+40);
1360 0 : sprintf(ret,"dup %g le {%s} {%s} ifelse", (double) positions[i+1], buffer, elsepart );
1361 0 : free(elsepart);
1362 0 : return( ret );
1363 : }
1364 :
1365 0 : static unichar_t *Figure1AxisCDV(MMW *mmw) {
1366 : real positions[MmMax];
1367 : SplineFont *sfs[MmMax];
1368 : int i;
1369 : char *temp;
1370 : unichar_t *ret;
1371 : char buffer[400];
1372 :
1373 0 : if ( mmw->axis_count!=1 )
1374 0 : return( uc_copy(""));
1375 0 : if ( mmw->instance_count==2 )
1376 0 : return( uc_copy( standard_cdvs[1]));
1377 :
1378 0 : for ( i=0; i<mmw->instance_count; ++i ) {
1379 0 : positions[i] = mmw->mm->positions[4*i];
1380 0 : sfs[i] = mmw->mm->instances[i];
1381 0 : if ( i>0 && positions[i-1]>=positions[i] )
1382 0 : return( uc_copy(""));
1383 : }
1384 0 : temp = _ChooseFonts(buffer,sfs,positions,0,mmw->instance_count);
1385 0 : ret = uc_copy(temp);
1386 0 : free(temp);
1387 0 : return( ret );
1388 : }
1389 :
1390 0 : static char *_NormalizeAxis(char *buffer, struct axismap *axis, int i) {
1391 0 : char *elsepart=NULL, *ret;
1392 : int pos;
1393 :
1394 0 : if ( i<axis->points-2 )
1395 0 : elsepart = _NormalizeAxis(buffer,axis,i+1);
1396 :
1397 0 : pos = 0;
1398 0 : if ( axis->blends[i+1]==axis->blends[i] ) {
1399 0 : sprintf( buffer, "%g ", (double) axis->blends[i] );
1400 0 : pos = strlen(buffer);
1401 : } else {
1402 0 : if ( axis->designs[i]!=0 ) {
1403 0 : sprintf(buffer, "%g sub ", (double) axis->designs[i]);
1404 0 : pos += strlen(buffer);
1405 : }
1406 0 : sprintf(buffer+pos, "%g div ", (double) ((axis->designs[i+1]-axis->designs[i])/
1407 0 : (axis->blends[i+1]-axis->blends[i])));
1408 0 : pos += strlen( buffer+pos );
1409 0 : if ( axis->blends[i]!=0 ) {
1410 0 : sprintf(buffer+pos, "%g add ", (double) axis->blends[i]);
1411 0 : pos += strlen(buffer+pos);
1412 : }
1413 : }
1414 :
1415 0 : if ( elsepart==NULL )
1416 0 : return( copy(buffer));
1417 :
1418 0 : ret = malloc(strlen(buffer)+strlen(elsepart)+40);
1419 0 : sprintf(ret,"dup %g le {%s} {%s} ifelse", (double) axis->designs[i+1], buffer, elsepart );
1420 0 : free(elsepart);
1421 0 : return( ret );
1422 : }
1423 :
1424 0 : static char *NormalizeAxis(char *header,struct axismap *axis) {
1425 : char *ret;
1426 : char buffer[200];
1427 :
1428 0 : ret = _NormalizeAxis(buffer,axis,0);
1429 0 : if ( *header ) {
1430 : char *temp;
1431 0 : temp = malloc(strlen(header)+strlen(ret)+2);
1432 0 : strcpy(temp,header);
1433 0 : strcat(temp,ret);
1434 0 : strcat(temp,"\n");
1435 0 : free(ret);
1436 0 : ret = temp;
1437 : }
1438 0 : return( ret );
1439 : }
1440 :
1441 0 : static int SameAxes(int cnt1,int cnt2,struct axismap *axismaps1,struct axismap *axismaps2) {
1442 : int i,j;
1443 :
1444 0 : if ( cnt1!=cnt2 )
1445 0 : return( false );
1446 0 : for ( i=0; i<cnt1; ++i ) {
1447 0 : if ( axismaps1[i].points!=axismaps2[i].points )
1448 0 : return( false );
1449 0 : for ( j=0; j<axismaps1[i].points; ++j ) {
1450 0 : if ( axismaps1[i].designs[j]>=axismaps2[i].designs[j]+.01 ||
1451 0 : axismaps1[i].designs[j]<=axismaps2[i].designs[j]-.01 )
1452 0 : return( false );
1453 0 : if ( axismaps1[i].blends[j]>=axismaps2[i].blends[j]+.001 ||
1454 0 : axismaps1[i].blends[j]<=axismaps2[i].blends[j]-.001 )
1455 0 : return( false );
1456 : }
1457 : }
1458 0 : return( true );
1459 : }
1460 :
1461 0 : static void AxisDataCopyFree(struct axismap *into,struct axismap *from,int count) {
1462 : int i;
1463 :
1464 0 : for ( i=0; i<4; ++i ) {
1465 0 : free(into->blends); free(into->designs);
1466 0 : into->blends = NULL; into->designs = NULL;
1467 0 : into->points = 0;
1468 : }
1469 0 : for ( i=0; i<count; ++i ) {
1470 0 : into[i].points = from[i].points;
1471 0 : into[i].blends = malloc(into[i].points*sizeof(real));
1472 0 : memcpy(into[i].blends,from[i].blends,into[i].points*sizeof(real));
1473 0 : into[i].designs = malloc(into[i].points*sizeof(real));
1474 0 : memcpy(into[i].designs,from[i].designs,into[i].points*sizeof(real));
1475 : }
1476 0 : }
1477 :
1478 0 : static int PositionsMatch(MMSet *old,MMSet *mm) {
1479 : int i,j;
1480 :
1481 0 : for ( i=0; i<old->instance_count; ++i ) {
1482 0 : for ( j=0; j<old->axis_count; ++j )
1483 0 : if ( old->positions[i*old->axis_count+j] != mm->positions[i*mm->axis_count+j] )
1484 0 : return( false );
1485 : }
1486 0 : return( true );
1487 : }
1488 :
1489 0 : static void MMW_FuncsValid(MMW *mmw) {
1490 : unichar_t *ut;
1491 : int pos, i;
1492 :
1493 0 : if ( !SameAxes(mmw->axis_count,mmw->last_axis_count,mmw->mm->axismaps,mmw->last_axismaps)) {
1494 0 : if ( mmw->old!=NULL &&
1495 0 : SameAxes(mmw->axis_count,mmw->old->axis_count,mmw->mm->axismaps,mmw->old->axismaps)) {
1496 0 : ut = uc_copy(mmw->old->ndv);
1497 : } else {
1498 0 : char *header = mmw->axis_count==1 ? " " :
1499 0 : mmw->axis_count==2 ? " exch " :
1500 0 : mmw->axis_count==3 ? " 3 -1 roll " :
1501 : " 4 -1 roll ";
1502 : char *lines[4];
1503 0 : for ( i=0; i<mmw->axis_count; ++i )
1504 0 : lines[i] = NormalizeAxis(header,&mmw->mm->axismaps[i]);
1505 0 : pos = 0;
1506 0 : for ( i=0; i<mmw->axis_count; ++i )
1507 0 : pos += strlen(lines[i]);
1508 0 : ut = malloc((pos+20)*sizeof(unichar_t));
1509 0 : uc_strcpy(ut,"{\n" ); pos = 2;
1510 0 : for ( i=0; i<mmw->axis_count; ++i ) {
1511 0 : uc_strcpy(ut+pos,lines[i]);
1512 0 : pos += strlen(lines[i]);
1513 : }
1514 0 : uc_strcpy(ut+pos,"}" );
1515 : }
1516 0 : GGadgetSetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_NDV),
1517 : ut);
1518 0 : free(ut);
1519 0 : AxisDataCopyFree(mmw->last_axismaps,mmw->mm->axismaps,mmw->axis_count);
1520 0 : mmw->last_axis_count = mmw->axis_count;
1521 : }
1522 0 : if ( mmw->last_instance_count!=mmw->instance_count ) {
1523 0 : if ( standard_cdvs[4]==NULL ) {
1524 0 : standard_cdvs[4] = malloc(strlen(cdv_4axis[0])+strlen(cdv_4axis[1])+
1525 0 : strlen(cdv_4axis[2])+2);
1526 0 : strcpy(standard_cdvs[4],cdv_4axis[0]);
1527 0 : strcat(standard_cdvs[4],cdv_4axis[1]);
1528 0 : strcat(standard_cdvs[4],cdv_4axis[2]);
1529 : }
1530 0 : if ( mmw->old!=NULL &&
1531 0 : mmw->axis_count==mmw->old->axis_count &&
1532 0 : mmw->instance_count==mmw->old->instance_count &&
1533 0 : PositionsMatch(mmw->old,mmw->mm)) {
1534 0 : ut = uc_copy(mmw->old->cdv);
1535 0 : } else if ( mmw->instance_count==(1<<mmw->axis_count) &&
1536 0 : StandardPositions(mmw->mm,mmw->instance_count,mmw->axis_count,false)) {
1537 0 : ut = uc_copy(standard_cdvs[mmw->axis_count]);
1538 0 : } else if ( mmw->axis_count==1 &&
1539 0 : OrderedPositions(mmw->mm,mmw->instance_count,false)) {
1540 0 : ut = Figure1AxisCDV(mmw);
1541 : } else {
1542 0 : ut = uc_copy("");
1543 : }
1544 0 : GGadgetSetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_CDV),
1545 : ut);
1546 0 : free(ut);
1547 : }
1548 0 : mmw->last_instance_count = mmw->instance_count;
1549 0 : }
1550 :
1551 0 : static void MMW_WeightsValid(MMW *mmw) {
1552 : char *temp;
1553 : unichar_t *ut, *utc;
1554 : int pos, i;
1555 : real axiscoords[4], weights[2*MmMax];
1556 :
1557 0 : if ( mmw->lastw_instance_count!=mmw->instance_count ) {
1558 0 : temp = malloc(mmw->instance_count*20+1);
1559 0 : pos = 0;
1560 0 : if ( mmw->old!=NULL && mmw->instance_count==mmw->old->instance_count ) {
1561 0 : for ( i=0; i<mmw->instance_count; ++i ) {
1562 0 : sprintf(temp+pos,"%g ", (double) mmw->old->defweights[i] );
1563 0 : pos += strlen(temp+pos);
1564 : }
1565 0 : utc = MMDesignCoords(mmw->old);
1566 : } else {
1567 0 : for ( i=0; i<mmw->axis_count; ++i ) {
1568 0 : if ( strcmp(mmw->mm->axes[i],"Weight")==0 &&
1569 0 : 400>=mmw->mm->axismaps[i].designs[0] &&
1570 0 : 400<=mmw->mm->axismaps[i].designs[mmw->mm->axismaps[i].points-1])
1571 0 : axiscoords[i] = 400;
1572 0 : else if ( strcmp(mmw->mm->axes[i],"OpticalSize")==0 &&
1573 0 : 12>=mmw->mm->axismaps[i].designs[0] &&
1574 0 : 12<=mmw->mm->axismaps[i].designs[mmw->mm->axismaps[i].points-1])
1575 0 : axiscoords[i] = 12;
1576 : else
1577 0 : axiscoords[i] = (mmw->mm->axismaps[i].designs[0]+
1578 0 : mmw->mm->axismaps[i].designs[mmw->mm->axismaps[i].points-1])/2;
1579 : }
1580 0 : i = ExecConvertDesignVector(axiscoords,mmw->axis_count,mmw->mm->ndv,mmw->mm->cdv,
1581 : weights);
1582 0 : if ( i!=mmw->instance_count ) { /* The functions don't work */
1583 0 : for ( i=0; i<mmw->instance_count; ++i )
1584 0 : weights[i] = 1.0/mmw->instance_count;
1585 0 : utc = uc_copy("");
1586 : } else {
1587 0 : for ( i=0; i<mmw->axis_count; ++i ) {
1588 0 : sprintf(temp+pos,"%g ", (double) axiscoords[i] );
1589 0 : pos += strlen(temp+pos);
1590 : }
1591 0 : temp[pos-1] = '\0';
1592 0 : utc = uc_copy(temp);
1593 0 : pos = 0;
1594 : }
1595 0 : for ( i=0; i<mmw->instance_count; ++i ) {
1596 0 : sprintf(temp+pos,"%g ", (double) weights[i] );
1597 0 : pos += strlen(temp+pos);
1598 : }
1599 : }
1600 0 : temp[pos-1] = '\0';
1601 0 : ut = uc_copy(temp);
1602 0 : GGadgetSetTitle(GWidgetGetControl(mmw->subwins[mmw_others],CID_NewBlends),
1603 : ut);
1604 0 : free(temp); free(ut);
1605 :
1606 0 : GGadgetSetTitle(GWidgetGetControl(mmw->subwins[mmw_others],CID_NewDesign),utc);
1607 0 : free(utc);
1608 0 : mmw->lastw_instance_count = mmw->instance_count;
1609 : }
1610 0 : }
1611 :
1612 0 : static GTextInfo *NamedDesigns(MMW *mmw) {
1613 : int cnt, i, j;
1614 : GTextInfo *ti;
1615 : char buffer[120], *pt;
1616 : char *ustyle;
1617 :
1618 0 : if ( !mmw->mm->apple || mmw->old==NULL )
1619 0 : return( NULL );
1620 :
1621 0 : cnt = mmw->old->named_instance_count;
1622 0 : ti = calloc((cnt+1),sizeof(GTextInfo));
1623 0 : for ( i=0; i<mmw->old->named_instance_count; ++i ) {
1624 0 : pt = buffer; *pt++='[';
1625 0 : for ( j=0; j<mmw->old->axis_count; ++j ) {
1626 0 : sprintf( pt, "%.4g ", (double) mmw->old->named_instances[i].coords[j]);
1627 0 : pt += strlen(pt);
1628 : }
1629 0 : pt[-1] = ']';
1630 0 : ustyle = PickNameFromMacName(mmw->old->named_instances[i].names);
1631 0 : ti[i].bg = ti[i].fg = COLOR_DEFAULT;
1632 0 : ti[i].text = malloc((strlen(buffer)+3+strlen(ustyle))*sizeof(unichar_t));
1633 0 : utf82u_strcpy(ti[i].text,ustyle);
1634 0 : uc_strcat(ti[i].text," ");
1635 0 : uc_strcat(ti[i].text,buffer);
1636 0 : ti[i].userdata = MacNameCopy(mmw->old->named_instances[i].names);
1637 0 : free(ustyle);
1638 : }
1639 :
1640 0 : return(ti);
1641 : }
1642 :
1643 0 : static GTextInfo *TiFromFont(SplineFont *sf) {
1644 0 : GTextInfo *ti = calloc(1,sizeof(GTextInfo));
1645 0 : ti->text = uc_copy(sf->fontname);
1646 0 : ti->fg = ti->bg = COLOR_DEFAULT;
1647 0 : ti->userdata = sf;
1648 0 : return( ti );
1649 : }
1650 :
1651 0 : static GTextInfo **FontList(MMW *mmw, int instance, int *sel) {
1652 : FontView *fv;
1653 : int cnt, i, pos;
1654 : GTextInfo **ti;
1655 :
1656 0 : cnt = 0;
1657 0 : if ( mmw->old!=NULL ) {
1658 0 : cnt = mmw->old->instance_count;
1659 0 : if ( mmw->old->apple )
1660 0 : ++cnt;
1661 : }
1662 0 : for ( fv=fv_list; fv!=NULL; fv=(FontView *) (fv->b.next) ) {
1663 0 : if ( fv->b.cidmaster==NULL && fv->b.sf->mm==NULL )
1664 0 : ++cnt;
1665 : }
1666 0 : cnt += mmw->lcnt;
1667 :
1668 0 : ++cnt; /* New */
1669 0 : ++cnt; /* Browse... */
1670 :
1671 0 : ti = malloc((cnt+1)*sizeof(GTextInfo *));
1672 0 : pos = -1;
1673 0 : cnt = 0;
1674 0 : if ( mmw->old!=NULL ) {
1675 0 : for ( i=0; i<mmw->old->instance_count; ++i ) {
1676 0 : if ( mmw->old->instances[i]==mmw->mm->instances[instance] ) pos = cnt;
1677 0 : ti[cnt++] = TiFromFont(mmw->old->instances[i]);
1678 : }
1679 0 : if ( mmw->old->apple ) {
1680 0 : if ( mmw->old->normal==mmw->mm->instances[instance] ) pos = cnt;
1681 0 : ti[cnt++] = TiFromFont(mmw->old->normal);
1682 : }
1683 : }
1684 0 : for ( fv=fv_list; fv!=NULL; fv=(FontView *) (fv->b.next) ) {
1685 0 : if ( fv->b.cidmaster==NULL && fv->b.sf->mm==NULL ) {
1686 0 : if ( fv->b.sf==mmw->mm->instances[instance] ) pos = cnt;
1687 0 : ti[cnt++] = TiFromFont(fv->b.sf);
1688 : }
1689 : }
1690 0 : for ( i=0; i<mmw->lcnt; ++i ) {
1691 0 : if ( mmw->loaded[i]==mmw->mm->instances[instance] ) pos = cnt;
1692 0 : ti[cnt++] = TiFromFont( mmw->loaded[i]);
1693 : }
1694 0 : if ( pos==-1 ) pos=cnt;
1695 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
1696 0 : ti[cnt]->text = utf82u_copy(S_("Font|New"));
1697 0 : ti[cnt]->bg = ti[cnt]->fg = COLOR_DEFAULT;
1698 0 : ++cnt;
1699 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
1700 0 : ti[cnt]->text = utf82u_copy(_("Browse..."));
1701 0 : ti[cnt]->bg = ti[cnt]->fg = COLOR_DEFAULT;
1702 0 : ti[cnt]->userdata = (void *) (-1);
1703 0 : ++cnt;
1704 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
1705 :
1706 0 : ti[pos]->selected = true;
1707 0 : *sel = pos;
1708 :
1709 0 : return(ti);
1710 : }
1711 :
1712 0 : static void MMW_DesignsSetup(MMW *mmw) {
1713 : int i,j,sel;
1714 : char buffer[80], *pt;
1715 : unichar_t ubuf[80];
1716 : GTextInfo **ti;
1717 :
1718 0 : for ( i=0; i<mmw->instance_count; ++i ) {
1719 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_designs],CID_DesignFonts+i*DesignScaleFactor);
1720 0 : ti = FontList(mmw,i,&sel);
1721 0 : GGadgetSetList(list, ti,false);
1722 0 : GGadgetSetTitle(list, ti[sel]->text);
1723 0 : pt = buffer;
1724 0 : for ( j=0; j<mmw->axis_count; ++j ) {
1725 0 : sprintf(pt,"%g ",(double) mmw->mm->positions[i*4+j]);
1726 0 : pt += strlen(pt);
1727 : }
1728 0 : if ( pt>buffer ) pt[-1] = '\0';
1729 0 : uc_strcpy(ubuf,buffer);
1730 0 : GGadgetSetTitle(GWidgetGetControl(mmw->subwins[mmw_designs],CID_AxisWeights+i*DesignScaleFactor),
1731 : ubuf);
1732 : }
1733 0 : }
1734 :
1735 0 : static void MMW_ParseNamedStyles(MMSet *setto,MMW *mmw) {
1736 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_named],CID_NamedDesigns);
1737 : int32 i,j,len;
1738 0 : GTextInfo **ti = GGadgetGetList(list,&len);
1739 : unichar_t *upt, *end;
1740 :
1741 0 : setto->named_instance_count = len;
1742 0 : if ( len!=0 ) {
1743 0 : setto->named_instances = calloc(len,sizeof(struct named_instance));
1744 0 : for ( i=0; i<len; ++i ) {
1745 0 : setto->named_instances[i].coords = calloc(setto->axis_count,sizeof(real));
1746 0 : upt = u_strchr(ti[i]->text,'[');
1747 0 : if ( upt!=NULL ) {
1748 0 : for ( j=0, ++upt; j<setto->axis_count; ++j ) {
1749 0 : setto->named_instances[i].coords[j] = rint(u_strtod(upt,&end)*8096)/8096;
1750 0 : if ( *end==' ' ) ++end;
1751 0 : upt = end;
1752 : }
1753 : }
1754 0 : setto->named_instances[i].names = ti[i]->userdata;
1755 0 : ti[i]->userdata = NULL;
1756 : }
1757 : }
1758 0 : }
1759 :
1760 0 : static void MMW_DoOK(MMW *mmw) {
1761 : real weights[AppleMmMax+1];
1762 : real fbt;
1763 0 : int err = false;
1764 0 : char *familyname, *fn, *origname=NULL;
1765 : int i,j;
1766 : MMSet *setto, *dlgmm;
1767 0 : FontView *fv = NULL;
1768 0 : int isapple = GGadgetIsChecked(GWidgetGetControl(mmw->subwins[mmw_counts],CID_Apple));
1769 : int defpos;
1770 0 : struct psdict *oldprivate = NULL;
1771 0 : Encoding *enc = NULL;
1772 :
1773 0 : if ( !isapple ) {
1774 0 : if ( !GetWeights(mmw->gw, weights, mmw->mm, mmw->instance_count, mmw->axis_count))
1775 0 : return;
1776 0 : fbt = GetReal8(mmw->subwins[mmw_others],CID_ForceBoldThreshold,
1777 : _("Force Bold Threshold:"),&err);
1778 0 : if ( err )
1779 0 : return;
1780 : }
1781 :
1782 0 : familyname = cu_copy(_GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_counts],CID_FamilyName)));
1783 : /* They only need specify a family name if there are new fonts */
1784 0 : if ( *familyname=='\0' ) {
1785 0 : free(familyname);
1786 0 : for ( i=0; i<mmw->instance_count; ++i )
1787 0 : if ( mmw->mm->instances[i]==NULL )
1788 0 : break;
1789 : else
1790 0 : fn = mmw->mm->instances[i]->familyname;
1791 0 : if ( i!=mmw->instance_count ) {
1792 0 : ff_post_error(_("Bad Multiple Master Font"),_("A Font Family name is required"));
1793 0 : return;
1794 : }
1795 0 : familyname = copy(fn);
1796 : }
1797 :
1798 : /* Did we have a fontview open on this mm? */
1799 0 : if ( mmw->old!=NULL ) {
1800 0 : for ( j=0; j<mmw->old->instance_count; ++j )
1801 0 : if ( mmw->old->instances[j]->fv!=NULL ) {
1802 0 : fv = (FontView *) mmw->old->instances[j]->fv;
1803 0 : origname = copy(mmw->old->instances[j]->origname);
1804 0 : enc = fv->b.map->enc;
1805 0 : break;
1806 : }
1807 : }
1808 :
1809 : /* Make sure we free all fonts that we have lying around and aren't going */
1810 : /* to be using. (ones we opened, ones in the old version of the mm). Also */
1811 : /* if any font we want to use is attached to a fontview, then close the */
1812 : /* window */
1813 0 : for ( i=0; i<mmw->instance_count; ++i ) if ( mmw->mm->instances[i]!=NULL ) {
1814 0 : if ( mmw->old!=NULL ) {
1815 0 : for ( j=0; j<mmw->old->instance_count; ++j )
1816 0 : if ( mmw->mm->instances[i]==mmw->old->instances[j] )
1817 0 : break;
1818 0 : if ( j!=mmw->old->instance_count ) {
1819 0 : mmw->old->instances[j] = NULL;
1820 0 : continue;
1821 0 : } else if ( mmw->old->normal==mmw->mm->instances[i] ) {
1822 0 : mmw->old->normal = NULL;
1823 0 : continue;
1824 : }
1825 : }
1826 0 : for ( j=0; j<mmw->lcnt; ++j )
1827 0 : if ( mmw->mm->instances[i]==mmw->loaded[j] )
1828 0 : break;
1829 0 : if ( j!=mmw->lcnt ) {
1830 0 : mmw->loaded[j] = NULL;
1831 0 : continue;
1832 : }
1833 0 : if ( enc==NULL && mmw->mm->instances[i]->fv!=NULL )
1834 0 : enc = mmw->mm->instances[i]->fv->map->enc;
1835 0 : MMUsurpNew(mmw->mm->instances[i]);
1836 : }
1837 0 : if ( mmw->old!=NULL ) {
1838 0 : for ( j=0; j<mmw->old->instance_count; ++j )
1839 0 : if ( mmw->old->instances[j]!=NULL ) {
1840 0 : MMDetachOld(mmw->old->instances[j]);
1841 0 : mmw->old->instances[j] = NULL;
1842 : }
1843 0 : if ( mmw->old->normal!=NULL ) {
1844 0 : oldprivate = mmw->old->normal->private;
1845 0 : mmw->old->normal->private = NULL;
1846 0 : MMDetachOld(mmw->old->normal);
1847 0 : mmw->old->normal = NULL;
1848 : }
1849 : }
1850 0 : for ( j=0; j<mmw->lcnt; ++j ) {
1851 0 : if ( mmw->loaded[j]!=NULL ) {
1852 0 : MMDetachNew(mmw->loaded[j]);
1853 0 : mmw->loaded[j] = NULL;
1854 : }
1855 : }
1856 :
1857 0 : dlgmm = mmw->mm;
1858 0 : setto = mmw->old;
1859 0 : if ( setto!=NULL ) {
1860 0 : MMSetFreeContents(setto);
1861 0 : memset(setto,0,sizeof(MMSet));
1862 : } else
1863 0 : setto = chunkalloc(sizeof(MMSet));
1864 0 : setto->apple = isapple;
1865 0 : setto->axis_count = mmw->axis_count;
1866 0 : setto->instance_count = mmw->instance_count;
1867 0 : defpos = mmw->instance_count;
1868 0 : if ( isapple ) {
1869 0 : for ( defpos=0; defpos<mmw->instance_count; ++defpos ) {
1870 0 : for ( j=0; j<mmw->axis_count; ++j )
1871 0 : if ( dlgmm->positions[defpos*dlgmm->axis_count+j]!=0 )
1872 0 : break;
1873 0 : if ( j==mmw->axis_count )
1874 0 : break;
1875 : }
1876 0 : if ( defpos==mmw->instance_count )
1877 0 : --defpos;
1878 0 : --setto->instance_count;
1879 0 : setto->normal = dlgmm->instances[defpos];
1880 0 : if ( setto->normal!=NULL )
1881 0 : setto->normal->mm = setto;
1882 : }
1883 0 : for ( i=0; i<setto->axis_count; ++i )
1884 0 : setto->axes[i] = dlgmm->axes[i];
1885 0 : setto->axismaps = dlgmm->axismaps;
1886 0 : setto->defweights = calloc(setto->instance_count,sizeof(real));
1887 0 : if ( !isapple )
1888 0 : memcpy(setto->defweights,weights,setto->instance_count*sizeof(real));
1889 0 : free(dlgmm->defweights);
1890 0 : setto->positions = malloc(setto->instance_count*setto->axis_count*sizeof(real));
1891 0 : for ( i=0; i<setto->instance_count; ++i ) {
1892 0 : int k = i<defpos ? i : i+1;
1893 0 : memcpy(setto->positions+i*setto->axis_count,dlgmm->positions+k*dlgmm->axis_count,
1894 0 : setto->axis_count*sizeof(real));
1895 : }
1896 0 : free(dlgmm->positions);
1897 0 : setto->instances = calloc(setto->instance_count,sizeof(SplineFont *));
1898 0 : for ( i=0; i<setto->instance_count; ++i ) {
1899 0 : if ( dlgmm->instances[i]!=NULL ) {
1900 0 : int k = i<defpos ? i : i+1;
1901 0 : setto->instances[i] = dlgmm->instances[k];
1902 0 : setto->instances[i]->mm = setto;
1903 : }
1904 : }
1905 0 : MMMatchGlyphs(setto);
1906 0 : if ( setto->normal==NULL ) {
1907 0 : setto->normal = MMNewFont(setto,-1,familyname);
1908 0 : setto->normal->private = oldprivate;
1909 : }
1910 0 : if ( !isapple ) {
1911 0 : if ( fbt>0 && fbt<=1 ) {
1912 : char buffer[20];
1913 0 : sprintf(buffer,"%g", (double) fbt );
1914 0 : if ( oldprivate==NULL )
1915 0 : setto->normal->private = calloc(1,sizeof(struct psdict));
1916 0 : PSDictChangeEntry(setto->normal->private,"ForceBoldThreshold",buffer);
1917 : }
1918 : }
1919 0 : if ( !isapple ) {
1920 0 : setto->cdv = dlgmm->cdv;
1921 0 : setto->ndv = dlgmm->ndv;
1922 : } else
1923 0 : MMW_ParseNamedStyles(setto,mmw);
1924 0 : for ( i=0; i<setto->instance_count; ++i ) {
1925 0 : if ( setto->instances[i]==NULL )
1926 0 : setto->instances[i] = MMNewFont(setto,i,familyname);
1927 0 : setto->instances[i]->fv = (FontViewBase *) fv;
1928 : }
1929 0 : free(dlgmm->instances);
1930 0 : chunkfree(dlgmm,sizeof(MMSet));
1931 0 : if ( origname!=NULL ) {
1932 0 : for ( i=0; i<setto->instance_count; ++i ) {
1933 0 : free(setto->instances[i]->origname);
1934 0 : setto->instances[i]->origname = copy(origname);
1935 : }
1936 0 : free(setto->normal->origname);
1937 0 : setto->normal->origname = origname;
1938 : } else {
1939 0 : for ( i=0; i<setto->instance_count; ++i ) {
1940 0 : free(setto->instances[i]->origname);
1941 0 : setto->instances[i]->origname = copy(setto->normal->origname);
1942 : }
1943 : }
1944 0 : if ( !isapple )
1945 0 : MMReblend((FontViewBase *) fv,setto);
1946 0 : if ( fv!=NULL ) {
1947 0 : for ( i=0; i<setto->instance_count; ++i )
1948 0 : if ( fv->b.sf==setto->instances[i])
1949 0 : break;
1950 0 : if ( i==setto->instance_count ) {
1951 0 : SplineFont *sf = setto->normal;
1952 : BDFFont *bdf;
1953 0 : int same = fv->filled == fv->show;
1954 0 : fv->b.sf = sf;
1955 0 : bdf = SplineFontPieceMeal(fv->b.sf,ly_fore,sf->display_size<0?-sf->display_size:default_fv_font_size,72,
1956 0 : (fv->antialias?pf_antialias:0)|(fv->bbsized?pf_bbsized:0),
1957 : NULL);
1958 0 : BDFFontFree(fv->filled);
1959 0 : fv->filled = bdf;
1960 0 : if ( same )
1961 0 : fv->show = bdf;
1962 : }
1963 : }
1964 0 : free(familyname);
1965 :
1966 : /* Multi-Mastered bitmaps don't make much sense */
1967 : /* Well, maybe grey-scaled could be interpolated, but yuck */
1968 0 : for ( i=0; i<setto->instance_count; ++i ) {
1969 : BDFFont *bdf, *bnext;
1970 0 : for ( bdf = setto->instances[i]->bitmaps; bdf!=NULL; bdf = bnext ) {
1971 0 : bnext = bdf->next;
1972 0 : BDFFontFree(bdf);
1973 : }
1974 0 : setto->instances[i]->bitmaps = NULL;
1975 : }
1976 :
1977 0 : if ( fv==NULL )
1978 0 : fv = (FontView *) FontViewCreate(setto->normal,false);
1979 0 : if ( enc==NULL )
1980 0 : enc = default_encoding;
1981 0 : FVReencode((FontViewBase *) fv,enc);
1982 0 : mmw->done = true;
1983 : }
1984 :
1985 0 : static void MMW_DoNext(MMW *mmw) {
1986 : int i, err;
1987 : real start, end, def, *designs, *norm;
1988 : int n, n2;
1989 0 : int isapple = GGadgetIsChecked(GWidgetGetControl(mmw->subwins[mmw_counts],CID_Apple));
1990 : char *yesno[3];
1991 0 : yesno[0] = _("_Yes"); yesno[1] = _("_No"); yesno[2] = NULL;
1992 :
1993 0 : if ( mmw->state==mmw_others )
1994 0 : return;
1995 :
1996 0 : if ( mmw->state==mmw_counts ) {
1997 0 : mmw->axis_count = GGadgetGetFirstListSelectedItem(GWidgetGetControl(mmw->subwins[mmw_counts],CID_AxisCount))+1;
1998 0 : mmw->instance_count = GGadgetGetFirstListSelectedItem(GWidgetGetControl(mmw->subwins[mmw_counts],CID_MasterCount))+1;
1999 : /* Arrays are already allocated out to maximum, and we will just leave*/
2000 : /* them there until user hits OK, then we make them the right size */
2001 0 : for ( i=0; i<4; ++i )
2002 0 : GTabSetSetEnabled(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2003 0 : i,i<mmw->axis_count);
2004 0 : for ( i=0; i<AppleMmMax+1; ++i )
2005 0 : GTabSetSetEnabled(GWidgetGetControl(mmw->subwins[mmw_designs],CID_WhichDesign),
2006 0 : i,i<mmw->instance_count);
2007 : /* If we've changed the axis count, and the old selected axis isn't */
2008 : /* available any more, choose another one */
2009 0 : if ( GTabSetGetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis))>=
2010 0 : mmw->axis_count )
2011 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2012 : 0);
2013 0 : if ( isapple ) {
2014 0 : int cnt = 1;
2015 0 : for ( i=0; i<mmw->axis_count; ++i ) cnt *= 3;
2016 0 : if ( mmw->instance_count==cnt ) {
2017 0 : for ( i=(mmw->old==NULL)?0:mmw->old->instance_count; i<mmw->instance_count-1; ++i ) {
2018 0 : int j = (i>=(cnt-1)/2) ? i+1 : i;
2019 0 : mmw->mm->positions[i*4 ] = (j%3==0) ? -1: (j%3==1) ? 0 : 1;
2020 0 : mmw->mm->positions[i*4+1] = ((j/3)%3==0) ? -1: ((j/3)%3==1) ? 0 : 1;
2021 0 : mmw->mm->positions[i*4+2] = ((j/9)%3==0) ? -1: ((j/9)%3==1) ? 0 : 1;
2022 0 : mmw->mm->positions[i*4+3] = ((j/27)%3==0) ? -1: ((j/27)%3==1) ? 0 : 1;
2023 : }
2024 : /* Place the default psuedo-instance last */
2025 0 : mmw->mm->positions[i*4 ] = 0;
2026 0 : mmw->mm->positions[i*4+1] = 0;
2027 0 : mmw->mm->positions[i*4+2] = 0;
2028 0 : mmw->mm->positions[i*4+3] = 0;
2029 : }
2030 : } else {
2031 0 : if ( mmw->instance_count==(1<<mmw->axis_count) ) {
2032 0 : for ( i=(mmw->old==NULL)?0:mmw->old->instance_count; i<mmw->instance_count; ++i ) {
2033 0 : mmw->mm->positions[i*4 ] = (i&1) ? 1 : 0;
2034 0 : mmw->mm->positions[i*4+1] = (i&2) ? 1 : 0;
2035 0 : mmw->mm->positions[i*4+2] = (i&4) ? 1 : 0;
2036 0 : mmw->mm->positions[i*4+3] = (i&8) ? 1 : 0;
2037 : }
2038 : }
2039 : }
2040 0 : } else if ( mmw->state==mmw_axes ) {
2041 0 : for ( i=0; i<mmw->axis_count; ++i ) {
2042 0 : free(mmw->mm->axes[i]);
2043 0 : mmw->mm->axes[i] = cu_copy(_GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_axes],CID_AxisType+i*100)));
2044 0 : if ( *mmw->mm->axes[i]=='\0' ) {
2045 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2046 : i);
2047 0 : ff_post_error(_("Bad Axis"),_("Please set the Axis Type field"));
2048 0 : return; /* Failure */
2049 : }
2050 : /* Don't free the current value. If it is non-null then it just */
2051 : /* points into the data structure that the Names gadgets manipulate */
2052 : /* and they will have done any freeing that needs doing. Freeing */
2053 : /* it here would destroy the data they work on */
2054 : /*MacNameListFree(mmw->mm->axismaps[i].axisnames);*/
2055 0 : mmw->mm->axismaps[i].axisnames = NULL;
2056 0 : if ( isapple ) {
2057 0 : mmw->mm->axismaps[i].axisnames = NameGadgetsGetNames(GTabSetGetSubwindow(
2058 0 : GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),i));
2059 0 : if ( mmw->mm->axismaps[i].axisnames == NULL ) {
2060 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2061 : i);
2062 0 : ff_post_error(_("Bad Axis"),_("When building an Apple distortable font, you must specify at least one name for the axis"));
2063 0 : return; /* Failure */
2064 : }
2065 : }
2066 0 : err = false;
2067 0 : start = GetReal8(mmw->subwins[mmw_axes],CID_AxisBegin+i*100,
2068 : _("Begin:"),&err);
2069 0 : end = GetReal8(mmw->subwins[mmw_axes],CID_AxisEnd+i*100,
2070 : _("End:"),&err);
2071 0 : if ( isapple ) {
2072 0 : def = rint(GetReal8(mmw->subwins[mmw_axes],CID_AxisDefault+i*100,
2073 : S_("AxisValue|Default"),&err)*8096)/8096;
2074 0 : start = rint(start*8096)/8096;
2075 0 : end = rint(end*8096)/8096;
2076 : } else
2077 0 : def = start;
2078 0 : if ( start>=end || def<start || def>end ) {
2079 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2080 : i);
2081 0 : ff_post_error(_("Bad Axis"),_("Axis range not valid"));
2082 0 : return; /* Failure */
2083 : }
2084 0 : n = ParseList(mmw->subwins[mmw_axes],CID_IntermediateDesign+i*100,
2085 : _("Design Settings:"),&err,start,def,end,&designs,CID_WhichAxis,i,isapple);
2086 0 : n2 = ParseList(mmw->subwins[mmw_axes],CID_IntermediateNormalized+i*100,
2087 : _("Normalized Settings:"),&err,
2088 : isapple?-1:0,0,1,&norm,CID_WhichAxis,i,isapple);
2089 0 : if ( n!=n2 || err ) {
2090 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_axes],CID_WhichAxis),
2091 : i);
2092 0 : if ( !err )
2093 0 : ff_post_error(_("Bad Axis"),_("The number of entries in the design settings must match the number in normalized settings"));
2094 0 : free(designs); free(norm);
2095 0 : return; /* Failure */
2096 : }
2097 0 : mmw->mm->axismaps[i].points = n;
2098 0 : free(mmw->mm->axismaps[i].blends); free(mmw->mm->axismaps[i].designs);
2099 0 : mmw->mm->axismaps[i].blends = norm; mmw->mm->axismaps[i].designs=designs;
2100 0 : mmw->mm->axismaps[i].min = start;
2101 0 : mmw->mm->axismaps[i].def = def;
2102 0 : mmw->mm->axismaps[i].max = end;
2103 : }
2104 0 : } else if ( mmw->state==mmw_designs ) {
2105 : real positions[AppleMmMax+1][4];
2106 : int used[AppleMmMax+1];
2107 : int j,k,mask, mul;
2108 : SplineFont *sfs[AppleMmMax+1];
2109 : GTextInfo *ti;
2110 :
2111 0 : memset(used,0,sizeof(used));
2112 0 : memset(positions,0,sizeof(positions));
2113 0 : for ( i=0; i<mmw->instance_count; ++i ) {
2114 0 : if ( !ParseWeights(mmw->subwins[mmw_designs],CID_AxisWeights+i*DesignScaleFactor,
2115 0 : _("Normalized position of this design along each axis"),positions[i],mmw->axis_count,
2116 : CID_WhichDesign,i))
2117 0 : return;
2118 0 : if ( isapple ) {
2119 0 : mask = 0; mul = 1;
2120 0 : for ( j=0; j<mmw->axis_count; ++j ) {
2121 0 : if ( positions[i][j]==-1 )
2122 : /* Do Nothing */;
2123 0 : else if ( positions[i][j]==0.0 )
2124 0 : mask += mul;
2125 0 : else if ( positions[i][j]==1.0 )
2126 0 : mask += 2*mul;
2127 : else
2128 0 : break;
2129 : }
2130 : } else {
2131 0 : mask = 0;
2132 0 : for ( j=0; j<mmw->axis_count; ++j ) {
2133 0 : if ( positions[i][j]==0 )
2134 : /* Do Nothing */;
2135 0 : else if ( positions[i][j]==1.0 )
2136 0 : mask |= (1<<j);
2137 : else
2138 0 : break;
2139 : }
2140 : }
2141 0 : if ( j==mmw->axis_count )
2142 0 : used[mask] = true;
2143 0 : for ( j=0; j<i-1; ++j ) {
2144 0 : for ( k=0; k<mmw->axis_count; ++k )
2145 0 : if ( positions[j][k] != positions[i][k] )
2146 0 : break;
2147 0 : if ( k==mmw->axis_count ) {
2148 : char *temp;
2149 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_designs],CID_WhichDesign),i);
2150 0 : ff_post_error(_("Bad Multiple Master Font"),_("The set of positions, %.30s, is used more than once"),
2151 0 : temp = GGadgetGetTitle8(GWidgetGetControl(mmw->subwins[mmw_designs],CID_AxisWeights+i*DesignScaleFactor)));
2152 0 : free(temp);
2153 0 : return;
2154 : }
2155 : }
2156 0 : ti = GGadgetGetListItemSelected(GWidgetGetControl(mmw->subwins[mmw_designs],CID_DesignFonts+i*DesignScaleFactor));
2157 0 : sfs[i] = ti->userdata;
2158 0 : if ( sfs[i]!=NULL ) {
2159 0 : for ( j=0; j<i; ++j )
2160 0 : if ( sfs[i]==sfs[j] ) {
2161 0 : GTabSetSetSel(GWidgetGetControl(mmw->subwins[mmw_designs],CID_WhichDesign),i);
2162 0 : ff_post_error(_("Bad Multiple Master Font"),_("The font %.30s is assigned to two master designs"),sfs[i]->fontname);
2163 0 : return;
2164 : }
2165 : }
2166 : }
2167 0 : for ( i=0; i<(1<<mmw->axis_count); ++i ) if ( !used[i] ) {
2168 0 : char buffer[20], *pt = buffer;
2169 0 : for ( j=0; j<mmw->axis_count; ++j ) {
2170 0 : sprintf( pt, "%d ", (i&(1<<j))? 1: 0 );
2171 0 : pt += 2;
2172 : }
2173 0 : if ( !isapple ) {
2174 0 : ff_post_error(_("Bad Multiple Master Font"),_("The set of positions, %.30s, is not specified in any design (and should be)"), buffer );
2175 0 : return;
2176 : } else {
2177 0 : if ( gwwv_ask(_("Bad Multiple Master Font"),(const char **) yesno,0,1,_("The set of positions, %.30s, is not specified in any design.\nIs that what you want?"),buffer)==1 )
2178 0 : return;
2179 : }
2180 : }
2181 0 : memcpy(mmw->mm->positions,positions,sizeof(positions));
2182 0 : for ( i=0; i<mmw->instance_count; ++i )
2183 0 : mmw->mm->instances[i] = sfs[i];
2184 0 : if ( mmw->old!=NULL &&
2185 0 : mmw->axis_count==mmw->old->axis_count &&
2186 0 : mmw->instance_count==mmw->old->instance_count &&
2187 0 : PositionsMatch(mmw->old,mmw->mm))
2188 : /* It's what the font started with, don't complain, already has a cdv */;
2189 0 : else if ( mmw->instance_count==(1<<mmw->axis_count) &&
2190 0 : StandardPositions(mmw->mm,mmw->instance_count,mmw->axis_count,isapple))
2191 : /* It's arranged as we expect it to be */;
2192 0 : else if ( mmw->axis_count==1 &&
2193 0 : OrderedPositions(mmw->mm,mmw->instance_count,isapple))
2194 : /* It's arranged according to our secondary expectations */;
2195 0 : else if ( !isapple && (mmw->instance_count==(1<<mmw->axis_count) ||
2196 0 : mmw->axis_count==1 )) {
2197 0 : if ( gwwv_ask(_("Disordered designs"),(const char **) yesno,0,1,_("The master designs are not positioned in the expected order. FontForge will be unable to suggest a ConvertDesignVector for you. Is this what you want?"))==1 )
2198 0 : return;
2199 : }
2200 0 : } else if ( mmw->state==mmw_funcs ) {
2201 0 : if ( *_GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_NDV))=='\0' ||
2202 0 : *_GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_CDV))=='\0' ) {
2203 0 : ff_post_error(_("Bad PostScript function"),_("Bad PostScript function"));
2204 0 : return;
2205 : }
2206 0 : free(mmw->mm->ndv); free(mmw->mm->cdv);
2207 0 : mmw->mm->ndv = cu_copy( _GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_NDV)));
2208 0 : mmw->mm->cdv = cu_copy( _GGadgetGetTitle(GWidgetGetControl(mmw->subwins[mmw_funcs],CID_CDV)));
2209 : }
2210 :
2211 0 : if ( mmw->state==mmw_designs && !isapple )
2212 0 : mmw->state += 2;
2213 : else
2214 0 : ++mmw->state;
2215 0 : if ( mmw->state==mmw_others )
2216 0 : MMW_WeightsValid(mmw);
2217 0 : else if ( mmw->state==mmw_funcs )
2218 0 : MMW_FuncsValid(mmw);
2219 0 : else if ( mmw->state==mmw_designs )
2220 0 : MMW_DesignsSetup(mmw);
2221 0 : MMW_SetState(mmw);
2222 : }
2223 :
2224 0 : static void MMW_SimulateDefaultButton(MMW *mmw) {
2225 0 : if ( mmw->state==mmw_others || mmw->state==mmw_named )
2226 0 : MMW_DoOK(mmw);
2227 : else
2228 0 : MMW_DoNext(mmw);
2229 0 : }
2230 :
2231 0 : static int MMW_OK(GGadget *g, GEvent *e) {
2232 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2233 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2234 0 : MMW_DoOK(mmw);
2235 : }
2236 0 : return( true );
2237 : }
2238 :
2239 0 : static int MMW_Next(GGadget *g, GEvent *e) {
2240 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2241 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2242 0 : MMW_DoNext(mmw);
2243 : }
2244 0 : return( true );
2245 : }
2246 :
2247 0 : static int MMW_Prev(GGadget *g, GEvent *e) {
2248 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2249 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2250 0 : if ( mmw->state!=mmw_counts ) {
2251 0 : if ( mmw->state==mmw_funcs )
2252 0 : mmw->state = mmw_designs;
2253 : else
2254 0 : --mmw->state;
2255 0 : MMW_SetState(mmw);
2256 : }
2257 : }
2258 0 : return( true );
2259 : }
2260 :
2261 0 : static int MMW_NamedNew(GGadget *g, GEvent *e) {
2262 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2263 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2264 0 : EditStyleName(mmw,-1);
2265 : }
2266 0 : return( true );
2267 : }
2268 :
2269 0 : static int MMW_NamedEdit(GGadget *g, GEvent *e) {
2270 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2271 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2272 0 : EditStyleName(mmw,GGadgetGetFirstListSelectedItem(GWidgetGetControl(mmw->subwins[mmw_named],CID_NamedDesigns)));
2273 : }
2274 0 : return( true );
2275 : }
2276 :
2277 0 : static int MMW_NamedDelete(GGadget *g, GEvent *e) {
2278 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2279 0 : GWindow gw = GGadgetGetWindow(g);
2280 0 : GGadget *list = GWidgetGetControl(gw,CID_NamedDesigns);
2281 : int32 i,len;
2282 0 : GTextInfo **ti = GGadgetGetList(list,&len);
2283 0 : for ( i=0; i<len; ++i ) {
2284 0 : if ( ti[i]->selected ) {
2285 0 : MacNameListFree(ti[i]->userdata);
2286 0 : ti[i]->userdata = NULL;
2287 : }
2288 : }
2289 0 : GListDelSelected(list);
2290 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NamedDelete),false);
2291 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NamedEdit),false);
2292 : }
2293 0 : return( true );
2294 : }
2295 :
2296 0 : static int MMW_NamedSel(GGadget *g, GEvent *e) {
2297 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
2298 : int32 len;
2299 0 : GTextInfo **ti = GGadgetGetList(g,&len);
2300 0 : GWindow gw = GGadgetGetWindow(g);
2301 0 : int i, sel_cnt=0;
2302 0 : for ( i=0; i<len; ++i )
2303 0 : if ( ti[i]->selected ) ++sel_cnt;
2304 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NamedDelete),sel_cnt!=0);
2305 0 : GGadgetSetEnabled(GWidgetGetControl(gw,CID_NamedEdit),sel_cnt==1);
2306 0 : } else if ( e->type==et_controlevent && e->u.control.subtype == et_listdoubleclick ) {
2307 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2308 0 : EditStyleName(mmw,GGadgetGetFirstListSelectedItem(g));
2309 : }
2310 0 : return( true );
2311 : }
2312 :
2313 0 : static int MMW_CheckOptical(GGadget *g, GEvent *e) {
2314 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2315 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2316 : char *top, *bottom, *def;
2317 : unichar_t *ut;
2318 0 : const unichar_t *ret = _GGadgetGetTitle(g);
2319 0 : int di = (GGadgetGetCid(g)-CID_AxisType)/100;
2320 : char buf1[20], buf2[20], buf3[20];
2321 :
2322 0 : if ( mmw->old!=NULL && di<mmw->old->axis_count &&
2323 0 : uc_strcmp(ret,mmw->old->axes[di])==0 ) {
2324 0 : sprintf(buf1,"%g", (double) mmw->old->axismaps[di].designs[0]);
2325 0 : sprintf(buf2,"%g", (double) mmw->old->axismaps[di].designs[mmw->old->axismaps[di].points-1]);
2326 0 : sprintf(buf3,"%g", (double) mmw->old->axismaps[di].def);
2327 0 : def = buf3;
2328 0 : top = buf2;
2329 0 : bottom = buf1;
2330 0 : } else if ( uc_strcmp(ret,"OpticalSize")==0 ) {
2331 0 : top = "72";
2332 0 : def = "12";
2333 0 : bottom = "6";
2334 0 : } else if ( uc_strcmp(ret,"Slant")==0 ) {
2335 0 : top = "22";
2336 0 : def = "0";
2337 0 : bottom = "-22";
2338 0 : } else if ( GGadgetIsChecked(GWidgetGetControl(mmw->subwins[mmw_counts],CID_Apple)) ) {
2339 0 : top = "2.0";
2340 0 : bottom = "0.5";
2341 0 : def = "1.0";
2342 : } else {
2343 0 : top = "999";
2344 0 : bottom = "50";
2345 0 : def = "400";
2346 : }
2347 0 : ut = uc_copy(top);
2348 0 : GGadgetSetTitle(GWidgetGetControl(GGadgetGetWindow(g),
2349 0 : GGadgetGetCid(g)-CID_AxisType + CID_AxisEnd), ut);
2350 0 : free(ut);
2351 0 : ut = uc_copy(bottom);
2352 0 : GGadgetSetTitle(GWidgetGetControl(GGadgetGetWindow(g),
2353 0 : GGadgetGetCid(g)-CID_AxisType + CID_AxisBegin), ut);
2354 0 : free(ut);
2355 0 : ut = uc_copy(def);
2356 0 : GGadgetSetTitle(GWidgetGetControl(GGadgetGetWindow(g),
2357 0 : GGadgetGetCid(g)-CID_AxisType + CID_AxisDefault), ut);
2358 0 : free(ut);
2359 : }
2360 0 : return( true );
2361 : }
2362 :
2363 0 : static int MMW_CheckBrowse(GGadget *g, GEvent *e) {
2364 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
2365 0 : MMW *mmw = GDrawGetUserData(GGadgetGetWindow(g));
2366 : /*int di = (GGadgetGetCid(g)-CID_DesignFonts)/DesignScaleFactor;*/
2367 0 : GTextInfo *ti = GGadgetGetListItemSelected(g);
2368 : char *temp;
2369 : SplineFont *sf;
2370 : GTextInfo **tis;
2371 : int i,sel,oldsel;
2372 : unichar_t *ut;
2373 :
2374 0 : if ( ti!=NULL && ti->userdata == (void *) -1 ) {
2375 0 : temp = GetPostScriptFontName(NULL,false);
2376 0 : if ( temp==NULL )
2377 0 : return(true);
2378 0 : sf = LoadSplineFont(temp,0);
2379 0 : free(temp); temp = NULL;
2380 0 : if ( sf==NULL )
2381 0 : return(true);
2382 0 : if ( sf->cidmaster!=NULL || sf->subfonts!=0 ) {
2383 0 : ff_post_error(_("Bad Multiple Master Font"),_("CID keyed fonts may not be a master design of a multiple master font"));
2384 0 : return(true);
2385 0 : } else if ( sf->mm!=NULL ) {
2386 0 : ff_post_error(_("Bad Multiple Master Font"),_("CID keyed fonts may not be a master design of a multiple master font"));
2387 0 : return(true);
2388 : }
2389 0 : if ( sf->fv==NULL ) {
2390 0 : if ( mmw->lcnt>=mmw->lmax ) {
2391 0 : if ( mmw->lmax==0 )
2392 0 : mmw->loaded = malloc((mmw->lmax=10)*sizeof(SplineFont *));
2393 : else
2394 0 : mmw->loaded = realloc(mmw->loaded,(mmw->lmax+=10)*sizeof(SplineFont *));
2395 : }
2396 0 : mmw->loaded[mmw->lcnt++] = sf;
2397 0 : for ( i=0; i<mmw->instance_count; ++i ) {
2398 0 : GGadget *list = GWidgetGetControl(mmw->subwins[mmw_designs],CID_DesignFonts+i*DesignScaleFactor);
2399 0 : oldsel = GGadgetGetFirstListSelectedItem(list);
2400 0 : tis = FontList(mmw,i,&sel);
2401 0 : tis[sel]->selected = false;
2402 0 : tis[oldsel]->selected = true;
2403 0 : GGadgetSetList(list, tis, false);
2404 : }
2405 : }
2406 0 : GGadgetSetTitle(g,ut = uc_copy(sf->fontname));
2407 0 : free(ut);
2408 : }
2409 : }
2410 0 : return( true );
2411 : }
2412 :
2413 0 : static int mmwsub_e_h(GWindow gw, GEvent *event) {
2414 0 : if ( event->type==et_char ) {
2415 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
2416 0 : help("multiplemaster.html");
2417 0 : return( true );
2418 0 : } else if ( event->u.chr.keysym=='q' && (event->u.chr.state&ksm_control)) {
2419 0 : if ( event->u.chr.state&ksm_shift )
2420 0 : MMW_Close(GDrawGetUserData(gw));
2421 0 : return( true );
2422 0 : } else if ( event->u.chr.chars[0]=='\r' ) {
2423 0 : MMW_SimulateDefaultButton( (MMW *) GDrawGetUserData(gw));
2424 0 : return( true );
2425 : }
2426 0 : return( false );
2427 : }
2428 0 : return( true );
2429 : }
2430 :
2431 0 : static int mmw_e_h(GWindow gw, GEvent *event) {
2432 0 : if ( event->type==et_close ) {
2433 0 : MMW *mmw = GDrawGetUserData(gw);
2434 0 : MMW_Close(mmw);
2435 0 : } else if ( event->type==et_char ) {
2436 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
2437 0 : help("multiplemaster.html");
2438 0 : return( true );
2439 0 : } else if ( event->u.chr.keysym=='q' && (event->u.chr.state&ksm_control)) {
2440 0 : if ( event->u.chr.state&ksm_shift )
2441 0 : MMW_Close(GDrawGetUserData(gw));
2442 : else
2443 0 : MenuExit(NULL,NULL,NULL);
2444 0 : return( true );
2445 0 : } else if ( event->u.chr.chars[0]=='\r' ) {
2446 0 : MMW_SimulateDefaultButton( (MMW *) GDrawGetUserData(gw));
2447 0 : return( true );
2448 : }
2449 0 : return( false );
2450 : }
2451 0 : return( true );
2452 : }
2453 :
2454 0 : static MMSet *MMCopy(MMSet *orig) {
2455 : MMSet *mm;
2456 : int i;
2457 : /* Allocate the arrays out to maximum, we'll fix them up later, and we */
2458 : /* retain the proper counts in the mmw structure. This means we don't */
2459 : /* lose data when they shrink and then restore a value */
2460 :
2461 0 : mm = chunkalloc(sizeof(MMSet));
2462 0 : mm->apple = orig->apple;
2463 0 : mm->instance_count = AppleMmMax+1;
2464 0 : mm->axis_count = 4;
2465 0 : for ( i=0; i<orig->axis_count; ++i )
2466 0 : mm->axes[i] = copy(orig->axes[i]);
2467 0 : mm->instances = calloc(AppleMmMax+1,sizeof(SplineFont *));
2468 0 : memcpy(mm->instances,orig->instances,orig->instance_count*sizeof(SplineFont *));
2469 0 : if ( mm->apple )
2470 0 : mm->instances[orig->instance_count] = orig->normal;
2471 0 : mm->positions = calloc((AppleMmMax+1)*4,sizeof(real));
2472 0 : for ( i=0; i<orig->instance_count; ++i )
2473 0 : memcpy(mm->positions+i*4,orig->positions+i*orig->axis_count,orig->axis_count*sizeof(real));
2474 0 : mm->defweights = calloc(AppleMmMax+1,sizeof(real));
2475 0 : memcpy(mm->defweights,orig->defweights,orig->instance_count*sizeof(real));
2476 0 : mm->axismaps = calloc(4,sizeof(struct axismap));
2477 0 : for ( i=0; i<orig->axis_count; ++i ) {
2478 0 : mm->axismaps[i].points = orig->axismaps[i].points;
2479 0 : mm->axismaps[i].blends = malloc(mm->axismaps[i].points*sizeof(real));
2480 0 : memcpy(mm->axismaps[i].blends,orig->axismaps[i].blends,mm->axismaps[i].points*sizeof(real));
2481 0 : mm->axismaps[i].designs = malloc(mm->axismaps[i].points*sizeof(real));
2482 0 : memcpy(mm->axismaps[i].designs,orig->axismaps[i].designs,mm->axismaps[i].points*sizeof(real));
2483 0 : mm->axismaps[i].min = orig->axismaps[i].min;
2484 0 : mm->axismaps[i].max = orig->axismaps[i].max;
2485 0 : mm->axismaps[i].def = orig->axismaps[i].def;
2486 : }
2487 0 : mm->cdv = copy(orig->cdv);
2488 0 : mm->ndv = copy(orig->ndv);
2489 0 : return( mm );
2490 : }
2491 :
2492 0 : void MMWizard(MMSet *mm) {
2493 : MMW mmw;
2494 : GRect pos, subpos;
2495 : GWindow gw;
2496 : GWindowAttrs wattrs;
2497 : GTabInfo axisaspects[5], designaspects[AppleMmMax+1+1];
2498 : GGadgetCreateData bgcd[8], cntgcd[11], axisgcd[4][20], designgcd[AppleMmMax+1][5],
2499 : agcd[2], dgcd[3], ogcd[7], ngcd[7];
2500 : GTextInfo blabel[8], cntlabel[11], axislabel[4][20], designlabel[AppleMmMax+1][5],
2501 : dlabel, olabels[7], nlabel[5];
2502 : char axisbegins[4][20], axisends[4][20], axisdefs[4][20];
2503 : char *normalized[4], *designs[4];
2504 : char *pt, *freeme;
2505 : int i,k;
2506 0 : int isadobe = mm==NULL || !mm->apple;
2507 0 : int space,blen= GIntGetResource(_NUM_Buttonsize)*100/GGadgetScale(100);
2508 : static char *designtablab[] = { "1", "2", "3", "4", "5", "6", "7", "8",
2509 : "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
2510 : "20", "21", "22", "23", "24", "25", "26", "27", NULL };
2511 : #if AppleMmMax!=26
2512 : #error "The designtablab array needs to be expanded to match AppleMmMax"
2513 : /* Actually it should be one bigger than AppleMmMax */
2514 : #endif
2515 :
2516 0 : memset(&mmw,0,sizeof(mmw));
2517 0 : mmw.old = mm;
2518 0 : if ( mm!=NULL ) {
2519 0 : mmw.mm = MMCopy(mm);
2520 0 : mmw.axis_count = mm->axis_count;
2521 0 : mmw.instance_count = mm->instance_count;
2522 0 : if ( mm->apple )
2523 0 : ++mmw.instance_count; /* Normal (default) design is a master in the mac format */
2524 : } else {
2525 0 : mmw.mm = chunkalloc(sizeof(MMSet));
2526 0 : mmw.axis_count = 1;
2527 0 : mmw.instance_count = 2;
2528 0 : mmw.mm->axis_count = 4; mmw.mm->instance_count = AppleMmMax+1;
2529 0 : mmw.mm->instances = calloc(AppleMmMax+1,sizeof(SplineFont *));
2530 0 : mmw.mm->positions = calloc((AppleMmMax+1)*4,sizeof(real));
2531 0 : mmw.mm->defweights = calloc(AppleMmMax+1,sizeof(real));
2532 0 : mmw.mm->axismaps = calloc(4,sizeof(struct axismap));
2533 0 : mmw.isnew = true;
2534 : }
2535 :
2536 0 : memset(&wattrs,0,sizeof(wattrs));
2537 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
2538 0 : wattrs.event_masks = ~(1<<et_charup);
2539 0 : wattrs.is_dlg = true;
2540 0 : wattrs.restrict_input_to_me = true;
2541 0 : wattrs.undercursor = 1;
2542 0 : wattrs.cursor = ct_pointer;
2543 0 : wattrs.utf8_window_title = mmw.isnew?_("Create MM"):_("MM _Info") ;
2544 0 : pos.x = pos.y = 0;
2545 0 : pos.width =GDrawPointsToPixels(NULL,GGadgetScale(MMW_Width));
2546 0 : pos.height = GDrawPointsToPixels(NULL,MMW_Height);
2547 0 : mmw.gw = gw = GDrawCreateTopWindow(NULL,&pos,mmw_e_h,&mmw,&wattrs);
2548 :
2549 0 : memset(&blabel,0,sizeof(blabel));
2550 0 : memset(&bgcd,0,sizeof(bgcd));
2551 :
2552 0 : mmw.canceldrop = GDrawPointsToPixels(NULL,30);
2553 0 : bgcd[0].gd.pos.x = 20; bgcd[0].gd.pos.y = GDrawPixelsToPoints(NULL,pos.height)-33;
2554 0 : bgcd[0].gd.pos.width = -1; bgcd[0].gd.pos.height = 0;
2555 0 : bgcd[0].gd.flags = gg_visible | gg_enabled;
2556 0 : blabel[0].text = (unichar_t *) _("_OK");
2557 0 : blabel[0].text_is_1byte = true;
2558 0 : blabel[0].text_in_resource = true;
2559 0 : bgcd[0].gd.label = &blabel[0];
2560 0 : bgcd[0].gd.cid = CID_OK;
2561 0 : bgcd[0].gd.handle_controlevent = MMW_OK;
2562 0 : bgcd[0].creator = GButtonCreate;
2563 :
2564 0 : space = (MMW_Width-4*blen-40)/3;
2565 0 : bgcd[1].gd.pos.x = bgcd[0].gd.pos.x+blen+space; bgcd[1].gd.pos.y = bgcd[0].gd.pos.y;
2566 0 : bgcd[1].gd.pos.width = -1; bgcd[1].gd.pos.height = 0;
2567 0 : bgcd[1].gd.flags = gg_visible;
2568 0 : blabel[1].text = (unichar_t *) _("< _Prev");
2569 0 : blabel[1].text_is_1byte = true;
2570 0 : blabel[1].text_in_resource = true;
2571 0 : bgcd[1].gd.label = &blabel[1];
2572 0 : bgcd[1].gd.handle_controlevent = MMW_Prev;
2573 0 : bgcd[1].gd.cid = CID_Prev;
2574 0 : bgcd[1].creator = GButtonCreate;
2575 :
2576 0 : bgcd[2].gd.pos.x = bgcd[1].gd.pos.x+blen+space; bgcd[2].gd.pos.y = bgcd[1].gd.pos.y;
2577 0 : bgcd[2].gd.pos.width = -1; bgcd[2].gd.pos.height = 0;
2578 0 : bgcd[2].gd.flags = gg_visible;
2579 0 : blabel[2].text = (unichar_t *) _("_Next >");
2580 0 : blabel[2].text_in_resource = true;
2581 0 : blabel[2].text_is_1byte = true;
2582 0 : bgcd[2].gd.label = &blabel[2];
2583 0 : bgcd[2].gd.handle_controlevent = MMW_Next;
2584 0 : bgcd[2].gd.cid = CID_Next;
2585 0 : bgcd[2].creator = GButtonCreate;
2586 :
2587 0 : bgcd[3].gd.pos.x = -20; bgcd[3].gd.pos.y = bgcd[1].gd.pos.y;
2588 0 : bgcd[3].gd.pos.width = -1; bgcd[3].gd.pos.height = 0;
2589 0 : bgcd[3].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
2590 0 : blabel[3].text = (unichar_t *) _("_Cancel");
2591 0 : blabel[3].text_in_resource = true;
2592 0 : blabel[3].text_is_1byte = true;
2593 0 : bgcd[3].gd.label = &blabel[3];
2594 0 : bgcd[3].gd.handle_controlevent = MMW_Cancel;
2595 0 : bgcd[3].gd.cid = CID_Cancel;
2596 0 : bgcd[3].creator = GButtonCreate;
2597 :
2598 0 : bgcd[4].gd.pos.x = 2; bgcd[4].gd.pos.y = 2;
2599 0 : bgcd[4].gd.pos.width = pos.width-4; bgcd[4].gd.pos.height = pos.height-4;
2600 0 : bgcd[4].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
2601 0 : bgcd[4].gd.cid = CID_Group;
2602 0 : bgcd[4].creator = GGroupCreate;
2603 :
2604 0 : GGadgetsCreate(gw,bgcd);
2605 :
2606 0 : subpos = pos;
2607 0 : subpos.y = subpos.x = 4;
2608 0 : subpos.width -= 8;
2609 0 : mmw.subheightdiff = GDrawPointsToPixels(NULL,44)-8;
2610 0 : subpos.height -= mmw.subheightdiff;
2611 0 : wattrs.mask = wam_events;
2612 0 : for ( i=mmw_counts; i<=mmw_others; ++i )
2613 0 : mmw.subwins[i] = GWidgetCreateSubWindow(mmw.gw,&subpos,mmwsub_e_h,&mmw,&wattrs);
2614 :
2615 0 : memset(&cntlabel,0,sizeof(cntlabel));
2616 0 : memset(&cntgcd,0,sizeof(cntgcd));
2617 :
2618 0 : k=0;
2619 0 : cntlabel[k].text = (unichar_t *) _("Type of distortable font:");
2620 0 : cntlabel[k].text_is_1byte = true;
2621 0 : cntgcd[k].gd.label = &cntlabel[k];
2622 0 : cntgcd[k].gd.pos.x = 5; cntgcd[k].gd.pos.y = 11;
2623 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2624 0 : cntgcd[k++].creator = GLabelCreate;
2625 :
2626 0 : cntlabel[k].text = (unichar_t *) _("Adobe");
2627 0 : cntlabel[k].text_is_1byte = true;
2628 0 : cntgcd[k].gd.label = &cntlabel[k];
2629 0 : cntgcd[k].gd.pos.x = 10; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+12;
2630 0 : cntgcd[k].gd.flags = isadobe ? (gg_visible | gg_enabled | gg_cb_on) :
2631 : ( gg_visible | gg_enabled );
2632 0 : cntgcd[k].gd.cid = CID_Adobe;
2633 0 : cntgcd[k].gd.handle_controlevent = MMW_TypeChanged;
2634 0 : cntgcd[k++].creator = GRadioCreate;
2635 :
2636 0 : cntlabel[k].text = (unichar_t *) _("Apple");
2637 0 : cntlabel[k].text_is_1byte = true;
2638 0 : cntgcd[k].gd.label = &cntlabel[k];
2639 0 : cntgcd[k].gd.pos.x = 70; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y;
2640 0 : cntgcd[k].gd.flags = !isadobe ? (gg_visible | gg_enabled | gg_cb_on) :
2641 : ( gg_visible | gg_enabled );
2642 0 : cntgcd[k].gd.cid = CID_Apple;
2643 0 : cntgcd[k].gd.handle_controlevent = MMW_TypeChanged;
2644 0 : cntgcd[k++].creator = GRadioCreate;
2645 :
2646 0 : cntlabel[k].text = (unichar_t *) _("Number of Axes:");
2647 0 : cntlabel[k].text_is_1byte = true;
2648 0 : cntgcd[k].gd.label = &cntlabel[k];
2649 0 : cntgcd[k].gd.pos.x = 5; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+18;
2650 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2651 0 : cntgcd[k++].creator = GLabelCreate;
2652 :
2653 0 : cntgcd[k].gd.pos.x = 10; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+12;
2654 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2655 0 : cntgcd[k].gd.u.list = axiscounts;
2656 0 : cntgcd[k].gd.label = &axiscounts[mmw.axis_count-1];
2657 0 : cntgcd[k].gd.cid = CID_AxisCount;
2658 0 : cntgcd[k].gd.handle_controlevent = MMW_AxisCntChanged;
2659 0 : cntgcd[k++].creator = GListButtonCreate;
2660 0 : for ( i=0; i<4; ++i )
2661 0 : axiscounts[i].selected = false;
2662 0 : axiscounts[mmw.axis_count-1].selected = true;
2663 :
2664 0 : cntlabel[k].text = (unichar_t *) _("Number of Master Designs:");
2665 0 : cntlabel[k].text_is_1byte = true;
2666 0 : cntgcd[k].gd.label = &cntlabel[k];
2667 0 : cntgcd[k].gd.pos.x = 5; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+30;
2668 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2669 0 : cntgcd[k++].creator = GLabelCreate;
2670 :
2671 0 : cntgcd[k].gd.pos.x = 10; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+12;
2672 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2673 0 : cntgcd[k].gd.u.list = mastercounts;
2674 0 : cntgcd[k].gd.label = &mastercounts[mmw.instance_count-1];
2675 0 : cntgcd[k].gd.cid = CID_MasterCount;
2676 0 : cntgcd[k++].creator = GListButtonCreate;
2677 0 : for ( i=0; i<AppleMmMax+1; ++i )
2678 0 : mastercounts[i].selected = false;
2679 0 : mastercounts[mmw.instance_count-1].selected = true;
2680 :
2681 0 : cntlabel[k].text = (unichar_t *) _("_Family Name:");
2682 0 : cntlabel[k].text_is_1byte = true;
2683 0 : cntlabel[k].text_in_resource = true;
2684 0 : cntgcd[k].gd.label = &cntlabel[k];
2685 0 : cntgcd[k].gd.pos.x = 10; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+30;
2686 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2687 0 : cntgcd[k++].creator = GLabelCreate;
2688 :
2689 0 : freeme=NULL;
2690 0 : if ( mmw.old!=NULL && mmw.old->normal->familyname!=NULL )
2691 0 : cntlabel[k].text = (unichar_t *) (mmw.old->normal->familyname);
2692 : else
2693 0 : cntlabel[k].text = (unichar_t *) (freeme= GetNextUntitledName());
2694 0 : cntlabel[k].text_is_1byte = true;
2695 0 : cntgcd[k].gd.label = &cntlabel[k];
2696 0 : cntgcd[k].gd.pos.x = 15; cntgcd[k].gd.pos.y = cntgcd[k-1].gd.pos.y+14;
2697 0 : cntgcd[k].gd.pos.width = 150;
2698 0 : cntgcd[k].gd.flags = gg_visible | gg_enabled;
2699 0 : cntgcd[k].gd.cid = CID_FamilyName;
2700 0 : cntgcd[k++].creator = GTextFieldCreate;
2701 :
2702 0 : GGadgetsCreate(mmw.subwins[mmw_counts],cntgcd);
2703 0 : SetMasterToAxis(&mmw,true);
2704 0 : free(freeme);
2705 :
2706 0 : memset(&axisgcd,0,sizeof(axisgcd));
2707 0 : memset(&axislabel,0,sizeof(axislabel));
2708 0 : memset(&agcd,0,sizeof(agcd));
2709 0 : memset(&axisaspects,0,sizeof(axisaspects));
2710 :
2711 0 : for ( i=0; i<4; ++i ) {
2712 0 : k=0;
2713 0 : axislabel[i][k].text = (unichar_t *) _("Axis Type:");
2714 0 : axislabel[i][k].text_is_1byte = true;
2715 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2716 0 : axisgcd[i][k].gd.pos.x = 5; axisgcd[i][k].gd.pos.y = 11;
2717 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2718 0 : axisgcd[i][k++].creator = GLabelCreate;
2719 :
2720 0 : axisgcd[i][k].gd.pos.x = 120; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y-4;
2721 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2722 0 : axisgcd[i][k].gd.u.list = axistypes;
2723 0 : axisgcd[i][k].gd.cid = CID_AxisType+i*100;
2724 0 : axisgcd[i][k].gd.handle_controlevent = MMW_CheckOptical;
2725 0 : if ( i<mmw.axis_count && mmw.mm->axes[i]!=NULL ) {
2726 0 : axislabel[i][k].text = uc_copy(mmw.mm->axes[i]);
2727 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2728 : }
2729 0 : axisgcd[i][k++].creator = GListFieldCreate;
2730 :
2731 0 : axislabel[i][k].text = (unichar_t *) _("Axis Range:");
2732 0 : axislabel[i][k].text_is_1byte = true;
2733 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2734 0 : axisgcd[i][k].gd.pos.x = 5; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y+20;
2735 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2736 0 : axisgcd[i][k++].creator = GLabelCreate;
2737 :
2738 0 : if ( mmw.mm->axismaps[i].points<2 ) {
2739 0 : strcpy(axisbegins[i],"50");
2740 0 : strcpy(axisdefs[i],"400");
2741 0 : strcpy(axisends[i],"999");
2742 : } else {
2743 0 : sprintf(axisbegins[i],"%.4g", (double) mmw.mm->axismaps[i].designs[0]);
2744 0 : sprintf(axisends[i],"%.4g", (double) mmw.mm->axismaps[i].designs[mmw.mm->axismaps[i].points-1]);
2745 0 : if ( mmw.mm->apple )
2746 0 : sprintf(axisdefs[i],"%.4g", (double) mmw.mm->axismaps[i].def );
2747 : else
2748 0 : sprintf(axisdefs[i],"%g", (double) (mmw.mm->axismaps[i].designs[0]+
2749 0 : mmw.mm->axismaps[i].designs[mmw.mm->axismaps[i].points-1])/2);
2750 : }
2751 :
2752 0 : axislabel[i][k].text = (unichar_t *) _("Begin:");
2753 0 : axislabel[i][k].text_is_1byte = true;
2754 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2755 0 : axisgcd[i][k].gd.pos.x = 10; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y+16;
2756 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2757 0 : axisgcd[i][k++].creator = GLabelCreate;
2758 :
2759 0 : axislabel[i][k].text = (unichar_t *) axisbegins[i];
2760 0 : axislabel[i][k].text_is_1byte = true;
2761 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2762 0 : axisgcd[i][k].gd.pos.x = 50; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y-4;
2763 0 : axisgcd[i][k].gd.pos.width=50;
2764 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2765 0 : axisgcd[i][k].gd.cid = CID_AxisBegin+i*100;
2766 0 : axisgcd[i][k++].creator = GTextFieldCreate;
2767 :
2768 0 : axislabel[i][k].text = (unichar_t *) _("Default:");
2769 0 : axislabel[i][k].text_is_1byte = true;
2770 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2771 0 : axisgcd[i][k].gd.pos.x = 110; axisgcd[i][k].gd.pos.y = axisgcd[i][k-2].gd.pos.y;
2772 0 : axisgcd[i][k].gd.flags = mmw.mm->apple ? (gg_visible | gg_enabled) : gg_visible;
2773 0 : axisgcd[i][k].gd.cid = CID_AxisDefaultLabel+i*100;
2774 0 : axisgcd[i][k++].creator = GLabelCreate;
2775 :
2776 0 : axislabel[i][k].text = (unichar_t *) axisdefs[i];
2777 0 : axislabel[i][k].text_is_1byte = true;
2778 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2779 0 : axisgcd[i][k].gd.pos.x = 148; axisgcd[i][k].gd.pos.y = axisgcd[i][k-2].gd.pos.y;
2780 0 : axisgcd[i][k].gd.pos.width=50;
2781 0 : axisgcd[i][k].gd.flags = mmw.mm->apple ? (gg_visible | gg_enabled) : gg_visible;
2782 0 : axisgcd[i][k].gd.cid = CID_AxisDefault+i*100;
2783 0 : axisgcd[i][k++].creator = GTextFieldCreate;
2784 :
2785 0 : axislabel[i][k].text = (unichar_t *) _("End:");
2786 0 : axislabel[i][k].text_is_1byte = true;
2787 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2788 0 : axisgcd[i][k].gd.pos.x = 210; axisgcd[i][k].gd.pos.y = axisgcd[i][k-2].gd.pos.y;
2789 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2790 0 : axisgcd[i][k++].creator = GLabelCreate;
2791 :
2792 0 : axislabel[i][k].text = (unichar_t *) axisends[i];
2793 0 : axislabel[i][k].text_is_1byte = true;
2794 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2795 0 : axisgcd[i][k].gd.pos.x = 240; axisgcd[i][k].gd.pos.y = axisgcd[i][k-2].gd.pos.y;
2796 0 : axisgcd[i][k].gd.pos.width=50;
2797 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2798 0 : axisgcd[i][k].gd.cid = CID_AxisEnd+i*100;
2799 0 : axisgcd[i][k++].creator = GTextFieldCreate;
2800 :
2801 0 : axislabel[i][k].text = (unichar_t *) _("Intermediate Points:");
2802 0 : axislabel[i][k].text_is_1byte = true;
2803 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2804 0 : axisgcd[i][k].gd.pos.x = 5; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y+26;
2805 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2806 0 : axisgcd[i][k++].creator = GLabelCreate;
2807 :
2808 0 : normalized[i]=NULL;
2809 0 : designs[i]=NULL;
2810 0 : if ( mmw.mm->axismaps[i].points>2+mmw.mm->apple ) {
2811 : int l,j,len1, len2;
2812 : char buffer[30];
2813 0 : len1 = len2 = 0;
2814 0 : for ( l=0; l<2; ++l ) {
2815 0 : for ( j=1; j<mmw.mm->axismaps[i].points-1; ++j ) {
2816 0 : if ( mmw.mm->apple && mmw.mm->axismaps[i].designs[j]==mmw.mm->axismaps[i].def )
2817 0 : continue;
2818 : /* I wanted to separate things with commas, but that isn't*/
2819 : /* a good idea in Europe (comma==decimal point) */
2820 0 : sprintf(buffer,"%g ",(double) mmw.mm->axismaps[i].designs[j]);
2821 0 : if ( designs[i]!=NULL )
2822 0 : strcpy(designs[i]+len1, buffer );
2823 0 : len1 += strlen(buffer);
2824 0 : sprintf(buffer,"%g ",(double) mmw.mm->axismaps[i].blends[j]);
2825 0 : if ( normalized[i]!=NULL )
2826 0 : strcpy(normalized[i]+len2, buffer );
2827 0 : len2 += strlen(buffer);
2828 : }
2829 0 : if ( l==0 ) {
2830 0 : normalized[i] = malloc(len2+2);
2831 0 : designs[i] = malloc(len1+2);
2832 : } else {
2833 0 : normalized[i][len2-1] = '\0';
2834 0 : designs[i][len1-1] = '\0';
2835 : }
2836 : }
2837 : }
2838 :
2839 0 : axislabel[i][k].text = (unichar_t *) _("Design Settings:");
2840 0 : axislabel[i][k].text_is_1byte = true;
2841 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2842 0 : axisgcd[i][k].gd.pos.x = 10; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y+12;
2843 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2844 0 : axisgcd[i][k++].creator = GLabelCreate;
2845 :
2846 0 : if ( designs[i]!=NULL ) {
2847 0 : axislabel[i][k].text = (unichar_t *) designs[i];
2848 0 : axislabel[i][k].text_is_1byte = true;
2849 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2850 : }
2851 0 : axisgcd[i][k].gd.pos.x = 120; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y-4;
2852 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2853 0 : axisgcd[i][k].gd.cid = CID_IntermediateDesign+i*100;
2854 0 : axisgcd[i][k++].creator = GTextFieldCreate;
2855 :
2856 0 : axislabel[i][k].text = (unichar_t *) _("Normalized Settings:");
2857 0 : axislabel[i][k].text_is_1byte = true;
2858 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2859 0 : axisgcd[i][k].gd.pos.x = 10; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y+28;
2860 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2861 0 : axisgcd[i][k++].creator = GLabelCreate;
2862 :
2863 0 : if ( normalized[i]!=NULL ) {
2864 0 : axislabel[i][k].text = (unichar_t *) normalized[i];
2865 0 : axislabel[i][k].text_is_1byte = true;
2866 0 : axisgcd[i][k].gd.label = &axislabel[i][k];
2867 : }
2868 0 : axisgcd[i][k].gd.pos.x = 120; axisgcd[i][k].gd.pos.y = axisgcd[i][k-1].gd.pos.y-4;
2869 0 : axisgcd[i][k].gd.flags = gg_visible | gg_enabled;
2870 0 : axisgcd[i][k].gd.cid = CID_IntermediateNormalized+i*100;
2871 0 : axisgcd[i][k++].creator = GTextFieldCreate;
2872 :
2873 0 : k = GCDBuildNames(axisgcd[i],axislabel[i],k,mm==NULL || i>=mm->axis_count ? NULL :
2874 0 : mm->axismaps[i].axisnames);
2875 :
2876 0 : axisaspects[i].text = (unichar_t *) _(axistablab[i]);
2877 0 : axisaspects[i].text_is_1byte = true;
2878 0 : axisaspects[i].gcd = axisgcd[i];
2879 : }
2880 0 : axisaspects[0].selected = true;
2881 :
2882 0 : agcd[0].gd.pos.x = 3; agcd[0].gd.pos.y = 3;
2883 0 : agcd[0].gd.pos.width = MMW_Width-10;
2884 0 : agcd[0].gd.pos.height = MMW_Height-45;
2885 0 : agcd[0].gd.u.tabs = axisaspects;
2886 0 : agcd[0].gd.flags = gg_visible | gg_enabled;
2887 0 : agcd[0].gd.cid = CID_WhichAxis;
2888 0 : agcd[0].creator = GTabSetCreate;
2889 :
2890 0 : GGadgetsCreate(mmw.subwins[mmw_axes],agcd);
2891 0 : for ( i=0; i<4; ++i ) {
2892 0 : free(axislabel[i][1].text);
2893 0 : free(normalized[i]);
2894 0 : free(designs[i]);
2895 : }
2896 :
2897 0 : memset(&designgcd,0,sizeof(designgcd));
2898 0 : memset(&designlabel,0,sizeof(designlabel));
2899 0 : memset(&dgcd,0,sizeof(dgcd));
2900 0 : memset(&dlabel,0,sizeof(dlabel));
2901 0 : memset(&designaspects,0,sizeof(designaspects));
2902 :
2903 0 : for ( i=0; i<AppleMmMax+1; ++i ) {
2904 0 : designlabel[i][0].text = (unichar_t *) _("Source from which this design is to be taken");
2905 0 : designlabel[i][0].text_is_1byte = true;
2906 0 : designgcd[i][0].gd.label = &designlabel[i][0];
2907 0 : designgcd[i][0].gd.pos.x = 3; designgcd[i][0].gd.pos.y = 4;
2908 0 : designgcd[i][0].gd.flags = gg_visible | gg_enabled;
2909 0 : designgcd[i][0].creator = GLabelCreate;
2910 :
2911 0 : designgcd[i][1].gd.pos.x = 15; designgcd[i][1].gd.pos.y = 18;
2912 0 : designgcd[i][1].gd.pos.width = 200;
2913 0 : designgcd[i][1].gd.flags = gg_visible | gg_enabled;
2914 0 : designgcd[i][1].gd.cid = CID_DesignFonts + i*DesignScaleFactor;
2915 0 : designgcd[i][1].gd.handle_controlevent = MMW_CheckBrowse;
2916 0 : designgcd[i][1].creator = GListButtonCreate;
2917 :
2918 0 : designlabel[i][2].text = (unichar_t *) _("Normalized position of this design along each axis");
2919 0 : designlabel[i][2].text_is_1byte = true;
2920 0 : designgcd[i][2].gd.label = &designlabel[i][2];
2921 0 : designgcd[i][2].gd.pos.x = 3; designgcd[i][2].gd.pos.y = 50;
2922 0 : designgcd[i][2].gd.flags = gg_visible | gg_enabled;
2923 0 : designgcd[i][2].creator = GLabelCreate;
2924 :
2925 0 : designgcd[i][3].gd.pos.x = 15; designgcd[i][3].gd.pos.y = 64;
2926 0 : designgcd[i][3].gd.pos.width = 200;
2927 0 : designgcd[i][3].gd.flags = gg_visible | gg_enabled;
2928 0 : designgcd[i][3].gd.cid = CID_AxisWeights + i*DesignScaleFactor;
2929 0 : designgcd[i][3].creator = GTextFieldCreate;
2930 :
2931 0 : designaspects[i].text = (unichar_t *) designtablab[i];
2932 0 : designaspects[i].text_is_1byte = true;
2933 0 : designaspects[i].gcd = designgcd[i];
2934 : }
2935 0 : designaspects[0].selected = true;
2936 :
2937 0 : dlabel.text = (unichar_t *) _("Master Designs");
2938 0 : dlabel.text_is_1byte = true;
2939 0 : dgcd[0].gd.label = &dlabel;
2940 0 : dgcd[0].gd.pos.x = 3; dgcd[0].gd.pos.y = 4;
2941 0 : dgcd[0].gd.flags = gg_visible | gg_enabled;
2942 0 : dgcd[0].creator = GLabelCreate;
2943 :
2944 0 : dgcd[1].gd.pos.x = 3; dgcd[1].gd.pos.y = 18;
2945 0 : dgcd[1].gd.pos.width = MMW_Width-10;
2946 0 : dgcd[1].gd.pos.height = MMW_Height-60;
2947 0 : dgcd[1].gd.u.tabs = designaspects;
2948 0 : dgcd[1].gd.flags = gg_visible | gg_enabled;
2949 0 : dgcd[1].gd.cid = CID_WhichDesign;
2950 0 : dgcd[1].creator = GTabSetCreate;
2951 :
2952 0 : GGadgetsCreate(mmw.subwins[mmw_designs],dgcd);
2953 :
2954 0 : memset(&ngcd,0,sizeof(ngcd));
2955 0 : memset(&nlabel,0,sizeof(nlabel));
2956 :
2957 0 : nlabel[0].text = (unichar_t *) _("Named Styles");
2958 0 : nlabel[0].text_is_1byte = true;
2959 0 : ngcd[0].gd.label = &nlabel[0];
2960 0 : ngcd[0].gd.pos.x = 3; ngcd[0].gd.pos.y = 4;
2961 0 : ngcd[0].gd.flags = gg_visible | gg_enabled;
2962 0 : ngcd[0].creator = GLabelCreate;
2963 :
2964 0 : ngcd[1].gd.pos.x = 3; ngcd[1].gd.pos.y = 18;
2965 0 : ngcd[1].gd.pos.width = MMW_Width-10;
2966 0 : ngcd[1].gd.pos.height = MMW_Height-100;
2967 0 : ngcd[1].gd.u.list = NamedDesigns(&mmw);
2968 0 : ngcd[1].gd.flags = gg_visible | gg_enabled | gg_list_multiplesel;
2969 0 : ngcd[1].gd.cid = CID_NamedDesigns;
2970 0 : ngcd[1].gd.handle_controlevent = MMW_NamedSel;
2971 0 : ngcd[1].creator = GListCreate;
2972 :
2973 0 : ngcd[2].gd.pos.x = 20; ngcd[2].gd.pos.y = ngcd[1].gd.pos.y + ngcd[1].gd.pos.height+5;
2974 0 : ngcd[2].gd.pos.width = -1;
2975 0 : ngcd[2].gd.flags = gg_visible | gg_enabled;
2976 0 : nlabel[2].text = (unichar_t *) S_("Design|_New...");
2977 0 : nlabel[2].text_is_1byte = true;
2978 0 : nlabel[2].text_in_resource = true;
2979 0 : ngcd[2].gd.label = &nlabel[2];
2980 0 : ngcd[2].gd.cid = CID_NamedNew;
2981 0 : ngcd[2].gd.handle_controlevent = MMW_NamedNew;
2982 0 : ngcd[2].creator = GButtonCreate;
2983 :
2984 0 : ngcd[3].gd.pos.x = 20+blen+10; ngcd[3].gd.pos.y = ngcd[2].gd.pos.y;
2985 0 : ngcd[3].gd.pos.width = -1;
2986 0 : ngcd[3].gd.flags = gg_visible;
2987 0 : nlabel[3].text = (unichar_t *) _("_Delete");
2988 0 : nlabel[3].text_is_1byte = true;
2989 0 : nlabel[3].text_in_resource = true;
2990 0 : ngcd[3].gd.label = &nlabel[3];
2991 0 : ngcd[3].gd.cid = CID_NamedDelete;
2992 0 : ngcd[3].gd.handle_controlevent = MMW_NamedDelete;
2993 0 : ngcd[3].creator = GButtonCreate;
2994 :
2995 0 : ngcd[4].gd.pos.x = 20+2*blen+20; ngcd[4].gd.pos.y = ngcd[2].gd.pos.y;
2996 0 : ngcd[4].gd.pos.width = -1;
2997 0 : ngcd[4].gd.flags = gg_visible;
2998 0 : nlabel[4].text = (unichar_t *) _("_Edit...");
2999 0 : nlabel[4].text_is_1byte = true;
3000 0 : nlabel[4].text_in_resource = true;
3001 0 : ngcd[4].gd.label = &nlabel[4];
3002 0 : ngcd[4].gd.cid = CID_NamedEdit;
3003 0 : ngcd[4].gd.handle_controlevent = MMW_NamedEdit;
3004 0 : ngcd[4].creator = GButtonCreate;
3005 :
3006 0 : GGadgetsCreate(mmw.subwins[mmw_named],ngcd);
3007 0 : if ( ngcd[1].gd.u.list!=NULL )
3008 0 : GTextInfoListFree(ngcd[1].gd.u.list);
3009 :
3010 0 : memset(&ogcd,0,sizeof(ogcd));
3011 0 : memset(&olabels,0,sizeof(olabels));
3012 :
3013 0 : k=0;
3014 0 : olabels[k].text = (unichar_t *) _("Normalize Design Vector Function:");
3015 0 : olabels[k].text_is_1byte = true;
3016 0 : ogcd[k].gd.label = &olabels[k];
3017 0 : ogcd[k].gd.pos.x = 3; ogcd[k].gd.pos.y = 4;
3018 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3019 0 : ogcd[k++].creator = GLabelCreate;
3020 :
3021 0 : ogcd[k].gd.pos.x = 3; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+15;
3022 0 : ogcd[k].gd.pos.width = MMW_Width-10;
3023 0 : ogcd[k].gd.pos.height = 8*12+10;
3024 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3025 0 : ogcd[k].gd.cid = CID_NDV;
3026 0 : ogcd[k++].creator = GTextAreaCreate;
3027 :
3028 0 : olabels[k].text = (unichar_t *) _("Convert Design Vector Function:");
3029 0 : olabels[k].text_is_1byte = true;
3030 0 : ogcd[k].gd.label = &olabels[k];
3031 0 : ogcd[k].gd.pos.x = 3; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+ogcd[k-1].gd.pos.height+5;
3032 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3033 0 : ogcd[k++].creator = GLabelCreate;
3034 :
3035 0 : ogcd[k].gd.pos.x = 3; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+15;
3036 0 : ogcd[k].gd.pos.width = MMW_Width-10;
3037 0 : ogcd[k].gd.pos.height = 8*12+10;
3038 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3039 0 : ogcd[k].gd.cid = CID_CDV;
3040 0 : ogcd[k++].creator = GTextAreaCreate;
3041 :
3042 0 : GGadgetsCreate(mmw.subwins[mmw_funcs],ogcd);
3043 :
3044 0 : memset(&ogcd,0,sizeof(ogcd));
3045 0 : memset(&olabels,0,sizeof(olabels));
3046 :
3047 0 : k=0;
3048 0 : olabels[k].text = (unichar_t *) _("Contribution of each master design");
3049 0 : olabels[k].text_is_1byte = true;
3050 0 : ogcd[k].gd.label = &olabels[k];
3051 0 : ogcd[k].gd.pos.x = 10; ogcd[k].gd.pos.y = 4;
3052 0 : ogcd[k].gd.flags = gg_visible | gg_enabled | gg_cb_on;
3053 0 : ogcd[k].gd.cid = CID_Explicit;
3054 0 : ogcd[k].gd.handle_controlevent = MMCB_Changed;
3055 0 : ogcd[k++].creator = GRadioCreate;
3056 :
3057 0 : olabels[k].text = (unichar_t *) _("Design Axis Values");
3058 0 : olabels[k].text_is_1byte = true;
3059 0 : ogcd[k].gd.label = &olabels[k];
3060 0 : ogcd[k].gd.pos.x = 10; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+45;
3061 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3062 0 : ogcd[k].gd.cid = CID_ByDesign;
3063 0 : ogcd[k].gd.handle_controlevent = MMCB_Changed;
3064 0 : ogcd[k++].creator = GRadioCreate;
3065 :
3066 0 : ogcd[k].gd.pos.x = 15; ogcd[k].gd.pos.y = ogcd[k-2].gd.pos.y+18;
3067 0 : ogcd[k].gd.pos.width = 240;
3068 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3069 0 : ogcd[k].gd.cid = CID_NewBlends;
3070 0 : ogcd[k++].creator = GTextFieldCreate;
3071 :
3072 0 : ogcd[k].gd.pos.x = 15; ogcd[k].gd.pos.y = ogcd[k-2].gd.pos.y+18;
3073 0 : ogcd[k].gd.pos.width = 240;
3074 0 : ogcd[k].gd.flags = gg_visible;
3075 0 : ogcd[k].gd.cid = CID_NewDesign;
3076 0 : ogcd[k++].creator = GTextFieldCreate;
3077 :
3078 0 : olabels[k].text = (unichar_t *) _("Force Bold Threshold:");
3079 0 : olabels[k].text_is_1byte = true;
3080 0 : ogcd[k].gd.label = &olabels[k];
3081 0 : ogcd[k].gd.pos.x = 10; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+45;
3082 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3083 0 : ogcd[k++].creator = GLabelCreate;
3084 :
3085 0 : if ( mmw.old!=NULL &&
3086 0 : (pt = PSDictHasEntry(mmw.old->normal->private,"ForceBoldThreshold"))!=NULL )
3087 0 : olabels[k].text = (unichar_t *) pt;
3088 : else
3089 0 : olabels[k].text = (unichar_t *) ".3";
3090 0 : olabels[k].text_is_1byte = true;
3091 0 : ogcd[k].gd.label = &olabels[k];
3092 0 : ogcd[k].gd.pos.x = 15; ogcd[k].gd.pos.y = ogcd[k-1].gd.pos.y+13;
3093 0 : ogcd[k].gd.flags = gg_visible | gg_enabled;
3094 0 : ogcd[k].gd.cid = CID_ForceBoldThreshold;
3095 0 : ogcd[k++].creator = GTextFieldCreate;
3096 :
3097 0 : GGadgetsCreate(mmw.subwins[mmw_others],ogcd);
3098 :
3099 0 : mmw.state = mmw_counts;
3100 0 : MMW_SetState(&mmw);
3101 0 : GDrawSetVisible(mmw.subwins[mmw.state],true);
3102 0 : GDrawSetVisible(mmw.gw,true);
3103 :
3104 0 : while ( !mmw.done )
3105 0 : GDrawProcessOneEvent(NULL);
3106 :
3107 0 : GDrawDestroyWindow(gw);
3108 0 : }
|