Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #include "cvundoes.h"
28 : #include "fontforgeui.h"
29 : #include "lookups.h"
30 : #include "parsettf.h"
31 : #include "spiro.h"
32 : #include "splineorder2.h"
33 : #include "splineutil.h"
34 : #include "splineutil2.h"
35 : #include "tottfgpos.h"
36 : #include <ustring.h>
37 : #include <math.h>
38 : #include <utype.h>
39 : #include <gkeysym.h>
40 : #include <dlist.h>
41 :
42 : #define RAD2DEG (180/3.1415926535897932)
43 : #define TCnt 3
44 :
45 : typedef struct gidata {
46 : struct dlistnode ln;
47 : CharView *cv;
48 : SplineChar *sc;
49 : RefChar *rf;
50 : ImageList *img;
51 : AnchorPoint *ap;
52 : SplinePoint *cursp;
53 : spiro_cp *curcp;
54 : SplinePointList *curspl;
55 : SplinePointList *oldstate;
56 : AnchorPoint *oldaps;
57 : GWindow gw;
58 : int done, first, changed;
59 : int prevchanged, nextchanged;
60 : int normal_start, normal_end;
61 : int interp_start, interp_end;
62 : GGadgetCreateData* gcd;
63 : GGadget *group1ret, *group2ret;
64 : int nonmodal;
65 : } GIData;
66 :
67 : #define CID_BaseX 2001
68 : #define CID_BaseY 2002
69 : #define CID_NextXOff 2003
70 : #define CID_NextYOff 2004
71 : #define CID_NextPos 2005
72 : #define CID_PrevXOff 2006
73 : #define CID_PrevYOff 2007
74 : #define CID_PrevPos 2008
75 : #define CID_NextDef 2009
76 : #define CID_PrevDef 2010
77 : #define CID_NextR 2014
78 : #define CID_NextTheta 2015
79 : #define CID_PrevR 2016
80 : #define CID_PrevTheta 2017
81 : #define CID_HintMask 2020
82 : #define CID_ActiveHints 2030
83 : #define CID_NextX 2031
84 : #define CID_NextY 2032
85 : #define CID_PrevX 2033
86 : #define CID_PrevY 2034
87 : #define CID_BasePos 2035
88 : #define CID_Normal 2036
89 : #define CID_Interpolated 2037
90 : #define CID_NeverInterpolate 2038
91 : /* Also use CID_Next, CID_Prev below */
92 : #define CID_NextC 2041
93 : #define CID_PrevC 2042
94 : #define CID_PrevCurvature 2043
95 : #define CID_NextCurvature 2044
96 : #define CID_DeltaCurvature 2045
97 : #define CID_Curve 2050 /* Next four must be in order */
98 : #define CID_Corner 2051
99 : #define CID_Tangent 2052
100 : #define CID_HVCurve 2053
101 : #define CID_SpiroLeft 2054
102 : #define CID_SpiroRight 2055
103 : #define CID_TabSet 2100
104 :
105 : #define CID_X 3001
106 : #define CID_Y 3002
107 : #define CID_NameList 3003
108 : #define CID_Mark 3004
109 : #define CID_BaseChar 3005
110 : #define CID_BaseLig 3006
111 : #define CID_BaseMark 3007
112 : #define CID_CursEntry 3008
113 : #define CID_CursExit 3009
114 : #define CID_LigIndex 3010
115 : #define CID_Next 3011
116 : #define CID_Prev 3012
117 : #define CID_Delete 3013
118 : #define CID_New 3014
119 : #define CID_MatchPt 3015
120 :
121 : #define RI_Width 225
122 : #define RI_Height 246
123 : #define CID_Match_Pt_Base 1010
124 : #define CID_Match_Pt_Ref 1011
125 :
126 : #define II_Width 130
127 : #define II_Height 70
128 :
129 : #define PI_Width 228
130 : #define PI_Height 434
131 :
132 : #define AI_Width 160
133 : #define AI_Height 258
134 :
135 0 : static int GI_Cancel(GGadget *g, GEvent *e) {
136 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
137 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
138 0 : ci->done = true;
139 : }
140 0 : return( true );
141 : }
142 :
143 0 : static int GI_TransChange(GGadget *g, GEvent *e) {
144 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
145 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
146 0 : ci->changed = true;
147 : }
148 0 : return( true );
149 : }
150 :
151 0 : static int GI_MatchPtChange(GGadget *g, GEvent *e) {
152 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
153 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
154 0 : const unichar_t *t1 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Base));
155 0 : const unichar_t *t2 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Ref));
156 0 : while ( *t1==' ' ) ++t1;
157 0 : while ( *t2==' ' ) ++t2;
158 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,1004),*t1=='\0' && *t2=='\0' );
159 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,1005),*t1=='\0' && *t2=='\0' );
160 0 : if ( isdigit(*t1) && isdigit(*t2)) {
161 : BasePoint inbase, inref;
162 : int basept, refpt;
163 0 : basept = u_strtol(t1,NULL,10);
164 0 : refpt = u_strtol(t2,NULL,10);
165 0 : if ( ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),basept,&inbase,ci->rf)==-1 &&
166 0 : ttfFindPointInSC(ci->rf->sc,CVLayer((CharViewBase *) ci->cv),refpt,&inref,NULL)==-1 ) {
167 : char buffer[40];
168 0 : sprintf(buffer,"%g",(double) (inbase.x-inref.x));
169 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,1004),buffer);
170 0 : sprintf(buffer,"%g",(double) (inbase.y-inref.y));
171 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,1005),buffer);
172 : }
173 : }
174 : }
175 0 : return( true );
176 : }
177 :
178 0 : static int GI_ROK_Do(GIData *ci) {
179 0 : int errs=false,i;
180 : real trans[6];
181 : SplinePointList *spl, *new;
182 0 : RefChar *ref = ci->rf, *subref;
183 0 : int usemy = GGadgetIsChecked(GWidgetGetControl(ci->gw,6+1000));
184 0 : int round = GGadgetIsChecked(GWidgetGetControl(ci->gw,7+1000));
185 0 : int basept=-1, refpt=-1;
186 : BasePoint inbase, inref;
187 :
188 0 : for ( i=0; i<6; ++i ) {
189 0 : trans[i] = GetReal8(ci->gw,1000+i,_("Transformation Matrix"),&errs);
190 0 : if ( !errs &&
191 0 : ((i<4 && (trans[i]>30 || trans[i]<-30)) ||
192 0 : (i>=4 && (trans[i]>16000 || trans[i]<-16000))) ) {
193 : /* Don't want the user to insert an enormous scale factor or */
194 : /* it will move points outside the legal range. */
195 0 : GTextFieldSelect(GWidgetGetControl(ci->gw,1000+i),0,-1);
196 0 : ff_post_error(_("Value out of range"),_("Value out of range"));
197 0 : errs = true;
198 : }
199 0 : if ( errs )
200 0 : return( false );
201 : }
202 0 : if ( !ci->cv->b.sc->layers[ly_fore].order2 )
203 : /* No point matching */;
204 : else {
205 : const unichar_t *txt;
206 0 : txt = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Base));
207 0 : while ( isspace(*txt)) ++txt;
208 0 : if ( *txt!='\0' )
209 0 : basept = GetInt8(ci->gw,CID_Match_Pt_Base,_("_Base:"),&errs);
210 0 : txt = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_Match_Pt_Ref));
211 0 : while ( isspace(*txt)) ++txt;
212 0 : if ( *txt!='\0' )
213 0 : refpt = GetInt8(ci->gw,CID_Match_Pt_Ref,_("Ref:"),&errs);
214 0 : if ( errs )
215 0 : return( false );
216 0 : if ( (basept!=-1) ^ (refpt!=-1) ) {
217 0 : ff_post_error(_("Bad Point Match"),_("Both points must be specified, or neither"));
218 : }
219 0 : if ( basept!=-1 ) {
220 0 : if ( ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),basept,&inbase,ci->rf)!=-1 ) {
221 0 : ff_post_error(_("Bad Point Match"),_("Couldn't find base point"));
222 0 : return( false );
223 0 : } else if ( ttfFindPointInSC(ci->rf->sc,CVLayer((CharViewBase *) ci->cv),refpt,&inref,NULL)!=-1 ) {
224 0 : ff_post_error(_("Bad Point Match"),_("Couldn't find point in reference"));
225 0 : return( false );
226 : }
227 : /* Override user specified value */
228 0 : trans[4] = inbase.x-inref.x;
229 0 : trans[5] = inbase.y-inref.y;
230 : }
231 : }
232 :
233 0 : for ( i=0; i<6 && ref->transform[i]==trans[i]; ++i );
234 0 : if ( i==6 &&
235 0 : usemy==ref->use_my_metrics &&
236 0 : round==ref->round_translation_to_grid &&
237 0 : (basept!=-1)==ref->point_match &&
238 0 : (basept==-1 ||
239 0 : (ref->match_pt_base==basept && ref->match_pt_ref==refpt))) {
240 0 : ref->point_match_out_of_date = false;
241 0 : return( true ); /* Didn't really change */
242 : }
243 :
244 0 : for ( i=0; i<6; ++i )
245 0 : ref->transform[i] = trans[i];
246 0 : SplinePointListsFree(ref->layers[0].splines);
247 0 : ref->layers[0].splines = SplinePointListTransform(SplinePointListCopy(ref->sc->layers[ly_fore].splines),trans,tpt_AllPoints);
248 0 : spl = NULL;
249 0 : if ( ref->layers[0].splines!=NULL )
250 0 : for ( spl = ref->layers[0].splines; spl->next!=NULL; spl = spl->next );
251 0 : for ( subref = ref->sc->layers[ly_fore].refs; subref!=NULL; subref=subref->next ) {
252 0 : new = SplinePointListTransform(SplinePointListCopy(subref->layers[0].splines),trans,tpt_AllPoints);
253 0 : if ( spl==NULL )
254 0 : ref->layers[0].splines = new;
255 : else
256 0 : spl->next = new;
257 0 : if ( new!=NULL )
258 0 : for ( spl = new; spl->next!=NULL; spl = spl->next );
259 : }
260 0 : ref->use_my_metrics = usemy;
261 0 : ref->round_translation_to_grid = round;
262 0 : ref->point_match = basept!=-1;
263 0 : ref->match_pt_base = basept; ref->match_pt_ref = refpt;
264 0 : ref->point_match_out_of_date = false;
265 :
266 0 : SplineSetFindBounds(ref->layers[0].splines,&ref->bb);
267 0 : CVCharChangedUpdate(&ci->cv->b);
268 0 : return( true );
269 : }
270 :
271 0 : static int GI_ROK(GGadget *g, GEvent *e) {
272 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
273 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
274 0 : if ( GI_ROK_Do(ci))
275 0 : ci->done = true;
276 : }
277 0 : return( true );
278 : }
279 :
280 0 : static int GI_Show(GGadget *g, GEvent *e) {
281 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
282 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
283 0 : if ( ci->changed ) {
284 : char *buts[4];
285 : int ans;
286 0 : buts[0] = _("C_hange");
287 0 : buts[1] = _("_Retain");
288 0 : buts[2] = _("_Cancel");
289 0 : buts[3] = NULL;
290 0 : ans = gwwv_ask(_("Transformation Matrix Changed"),(const char **)buts,0,2,_("You have changed the transformation matrix, do you wish to use the new version?"));
291 0 : if ( ans==2 )
292 0 : return( true );
293 0 : else if ( ans==0 ) {
294 0 : if ( !GI_ROK_Do(ci))
295 0 : return( true );
296 : }
297 : }
298 0 : ci->done = true;
299 0 : CharViewCreate(ci->rf->sc,(FontView *) (ci->cv->b.fv),-1);
300 : }
301 0 : return( true );
302 : }
303 :
304 0 : static int gi_e_h(GWindow gw, GEvent *event) {
305 0 : if ( event->type==et_close ) {
306 0 : GIData *ci = GDrawGetUserData(gw);
307 0 : ci->done = true;
308 0 : } else if ( event->type==et_char ) {
309 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
310 0 : help("getinfo.html");
311 0 : return( true );
312 : }
313 0 : return( false );
314 0 : } else if ( event->type == et_map ) {
315 : /* Above palettes */
316 0 : GDrawRaise(gw);
317 : }
318 0 : return( true );
319 : }
320 :
321 0 : static void RefGetInfo(CharView *cv, RefChar *ref) {
322 : static GIData gi;
323 : GRect pos;
324 : GWindowAttrs wattrs;
325 : GGadgetCreateData gcd[33], boxes[7];
326 : GGadgetCreateData *varray[19], *hvarray[16], *harray1[6], *harray2[4],
327 : *harray3[7], *hvarray2[4][6];
328 : GTextInfo label[33];
329 : char tbuf[6][40], bbbuf[4][40];
330 : char basebuf[20], refbuf[20];
331 : char namebuf[100];
332 : char ubuf[40];
333 : int i,j,l;
334 :
335 0 : gi.cv = cv;
336 0 : gi.sc = cv->b.sc;
337 0 : gi.rf = ref;
338 0 : gi.changed = false;
339 0 : gi.done = false;
340 :
341 0 : memset(&wattrs,0,sizeof(wattrs));
342 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
343 0 : wattrs.event_masks = ~(1<<et_charup);
344 0 : wattrs.restrict_input_to_me = 1;
345 0 : wattrs.undercursor = 1;
346 0 : wattrs.cursor = ct_pointer;
347 0 : wattrs.utf8_window_title = _("Reference Info");
348 0 : wattrs.is_dlg = true;
349 0 : pos.x = pos.y = 0;
350 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,RI_Width));
351 0 : pos.height = GDrawPointsToPixels(NULL,
352 0 : ref->sc->unicodeenc!=-1?RI_Height+12:RI_Height);
353 0 : gi.gw = GDrawCreateTopWindow(NULL,&pos,gi_e_h,&gi,&wattrs);
354 :
355 0 : memset(&gcd,0,sizeof(gcd));
356 0 : memset(&label,0,sizeof(label));
357 0 : memset(&boxes,0,sizeof(boxes));
358 :
359 0 : snprintf( namebuf, sizeof(namebuf),
360 0 : _("Reference to character %1$.20s at %2$d"),
361 0 : ref->sc->name, (int) cv->b.fv->map->backmap[ref->sc->orig_pos]);
362 0 : label[0].text = (unichar_t *) namebuf;
363 0 : label[0].text_is_1byte = true;
364 0 : gcd[0].gd.label = &label[0];
365 0 : gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5;
366 0 : gcd[0].gd.flags = gg_enabled|gg_visible;
367 0 : gcd[0].creator = GLabelCreate;
368 0 : l = 0;
369 0 : varray[l++] = &gcd[0];
370 0 : j = 1;
371 :
372 0 : if ( ref->sc->unicodeenc!=-1 ) {
373 0 : sprintf( ubuf, " Unicode: U+%04x", ref->sc->unicodeenc );
374 0 : label[1].text = (unichar_t *) ubuf;
375 0 : label[1].text_is_1byte = true;
376 0 : gcd[1].gd.label = &label[1];
377 0 : gcd[1].gd.pos.x = 5; gcd[1].gd.pos.y = 17;
378 0 : gcd[1].gd.flags = gg_enabled|gg_visible;
379 0 : gcd[1].creator = GLabelCreate;
380 0 : varray[l++] = &gcd[1];
381 0 : j=2;
382 : }
383 :
384 0 : label[j].text = (unichar_t *) _("Transformed by:");
385 0 : label[j].text_is_1byte = true;
386 0 : gcd[j].gd.label = &label[j];
387 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
388 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
389 0 : gcd[j].gd.popup_msg = (unichar_t *) _("The transformation matrix specifies how the points in\nthe source glyph should be transformed before\nthey are drawn in the current glyph.\n x(new) = tm[1,1]*x + tm[2,1]*y + tm[3,1]\n y(new) = tm[1,2]*x + tm[2,2]*y + tm[3,2]");
390 0 : gcd[j].creator = GLabelCreate;
391 0 : varray[l++] = &gcd[j];
392 0 : ++j;
393 :
394 0 : for ( i=0; i<6; ++i ) {
395 0 : if ( !(i&1) ) hvarray[5*(i/2)] = GCD_Glue;
396 0 : sprintf(tbuf[i],"%g", (double) ref->transform[i]);
397 0 : label[i+j].text = (unichar_t *) tbuf[i];
398 0 : label[i+j].text_is_1byte = true;
399 0 : gcd[i+j].gd.label = &label[i+j];
400 0 : gcd[i+j].gd.pos.x = 20+((i&1)?85:0); gcd[i+j].gd.pos.width=75;
401 0 : gcd[i+j].gd.pos.y = gcd[j-1].gd.pos.y+14+(i/2)*26;
402 0 : gcd[i+j].gd.flags = gg_enabled|gg_visible;
403 0 : gcd[i+j].gd.cid = i+1000;
404 0 : gcd[i+j].gd.handle_controlevent = GI_TransChange;
405 0 : gcd[i+j].creator = (i>=4 ? GNumericFieldCreate : GTextFieldCreate);
406 0 : hvarray[5*(i/2)+1+(i&1)] = &gcd[i+j];
407 0 : if ( (i&1) ) { hvarray[5*(i/2)+3] = GCD_Glue; hvarray[5*(i/2)+4] = NULL; }
408 : }
409 0 : if ( ref->point_match )
410 0 : gcd[4+j].gd.flags = gcd[5+j].gd.flags = gg_visible;
411 0 : hvarray[15] = NULL;
412 :
413 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
414 0 : boxes[2].gd.u.boxelements = hvarray;
415 0 : boxes[2].creator = GHVBoxCreate;
416 0 : varray[l++] = &boxes[2];
417 :
418 0 : label[6+j].text = (unichar_t *) _("_Use My Metrics");
419 0 : label[6+j].text_in_resource = true;
420 0 : label[6+j].text_is_1byte = true;
421 0 : gcd[6+j].gd.label = &label[6+j];
422 0 : gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+21;
423 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup | (ref->use_my_metrics?gg_cb_on:0);
424 0 : gcd[i+j].gd.cid = 6+1000;
425 0 : gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that the width\nof the composite glyph should be the same as the width of this reference.");
426 0 : varray[l++] = &gcd[6+j];
427 0 : gcd[6+j++].creator = GCheckBoxCreate;
428 :
429 0 : label[6+j].text = (unichar_t *) _("_Round To Grid");
430 0 : label[6+j].text_in_resource = true;
431 0 : label[6+j].text_is_1byte = true;
432 0 : gcd[6+j].gd.label = &label[6+j];
433 0 : gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+14;
434 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup | (ref->round_translation_to_grid?gg_cb_on:0);
435 0 : gcd[i+j].gd.cid = 7+1000;
436 0 : gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that if the reference\nis translated, then the translation should be rounded during grid fitting.");
437 0 : varray[l++] = &gcd[6+j];
438 0 : gcd[6+j++].creator = GCheckBoxCreate;
439 :
440 0 : label[6+j].text = (unichar_t *) _("TrueType Point _Matching:");
441 0 : label[6+j].text_in_resource = true;
442 0 : label[6+j].text_is_1byte = true;
443 0 : gcd[6+j].gd.label = &label[6+j];
444 0 : gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+17;
445 0 : gcd[6+j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible|gg_utf8_popup) : (gg_visible|gg_utf8_popup);
446 0 : gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
447 0 : varray[l++] = &gcd[6+j];
448 0 : gcd[6+j++].creator = GLabelCreate;
449 :
450 0 : label[6+j].text = (unichar_t *) _("_Base:");
451 0 : label[6+j].text_is_1byte = true;
452 0 : label[6+j].text_in_resource = true;
453 0 : gcd[6+j].gd.label = &label[6+j];
454 0 : gcd[6+j].gd.pos.x = 8; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+19;
455 0 : gcd[6+j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible|gg_utf8_popup) : (gg_visible|gg_utf8_popup);
456 0 : gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
457 0 : harray1[0] = &gcd[6+j];
458 0 : gcd[6+j++].creator = GLabelCreate;
459 :
460 0 : if ( ref->point_match ) {
461 0 : sprintf(basebuf,"%d", ref->match_pt_base);
462 0 : label[6+j].text = (unichar_t *) basebuf;
463 0 : label[6+j].text_is_1byte = true;
464 0 : gcd[6+j].gd.label = &label[6+j];
465 : }
466 0 : gcd[6+j].gd.pos.x = 40; gcd[6+j].gd.pos.width=50;
467 0 : gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y-4;
468 0 : gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
469 0 : gcd[6+j].gd.cid = CID_Match_Pt_Base;
470 0 : gcd[6+j].gd.handle_controlevent = GI_MatchPtChange;
471 0 : harray1[1] = &gcd[6+j];
472 0 : gcd[6+j++].creator = GTextFieldCreate;
473 :
474 0 : label[6+j].text = (unichar_t *) _("Ref:");
475 0 : label[6+j].text_is_1byte = true;
476 0 : gcd[6+j].gd.label = &label[6+j];
477 0 : gcd[6+j].gd.pos.x = 95; gcd[6+j].gd.pos.y = gcd[6+j-2].gd.pos.y;
478 0 : gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
479 0 : gcd[6+j].gd.popup_msg = (unichar_t *) _("Only relevant in a truetype font, this flag indicates that this\nreference should not be translated normally, but rather its position\nshould be determined by moving the reference so that the indicated\npoint in the reference falls on top of the indicated point in the base\ncharacter.");
480 0 : harray1[2] = &gcd[6+j];
481 0 : gcd[6+j++].creator = GLabelCreate;
482 :
483 0 : if ( ref->point_match ) {
484 0 : sprintf(refbuf,"%d", ref->match_pt_ref);
485 0 : label[6+j].text = (unichar_t *) refbuf;
486 0 : label[6+j].text_is_1byte = true;
487 0 : gcd[6+j].gd.label = &label[6+j];
488 : }
489 0 : gcd[6+j].gd.pos.x = 127; gcd[6+j].gd.pos.width=50;
490 0 : gcd[6+j].gd.pos.y = gcd[6+j-2].gd.pos.y;
491 0 : gcd[6+j].gd.flags = gcd[6+j-1].gd.flags;
492 0 : gcd[6+j].gd.cid = CID_Match_Pt_Ref;
493 0 : gcd[6+j].gd.handle_controlevent = GI_MatchPtChange;
494 0 : harray1[3] = &gcd[6+j];
495 0 : gcd[6+j++].creator = GTextFieldCreate;
496 0 : harray1[4] = GCD_Glue; harray1[5] = NULL;
497 :
498 0 : boxes[3].gd.flags = gg_enabled|gg_visible;
499 0 : boxes[3].gd.u.boxelements = harray1;
500 0 : boxes[3].creator = GHBoxCreate;
501 0 : varray[l++] = &boxes[3];
502 :
503 0 : varray[l++] = GCD_Glue;
504 :
505 0 : gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = RI_Height+(j==10?12:0)-70;
506 0 : gcd[6+j].gd.pos.width = RI_Width-10;
507 0 : gcd[6+j].gd.flags = gg_visible | gg_enabled;
508 0 : varray[l++] = &gcd[6+j];
509 0 : gcd[6+j++].creator = GLineCreate;
510 :
511 0 : label[6+j].text = (unichar_t *) _("Bounding Box:");
512 0 : label[6+j].text_is_1byte = true;
513 0 : gcd[6+j].gd.label = &label[6+j];
514 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
515 0 : gcd[6+j].creator = GLabelCreate;
516 0 : varray[l++] = &gcd[6+j];
517 0 : ++j;
518 :
519 0 : hvarray2[0][0] = GCD_Glue; hvarray2[0][1] = GCD_Glue;
520 :
521 0 : label[6+j].text = (unichar_t *) _("Min");
522 0 : label[6+j].text_is_1byte = true;
523 0 : gcd[6+j].gd.label = &label[6+j];
524 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
525 0 : gcd[6+j].creator = GLabelCreate;
526 0 : hvarray2[0][2] = &gcd[6+j++];
527 :
528 0 : label[6+j].text = (unichar_t *) _("Max");
529 0 : label[6+j].text_is_1byte = true;
530 0 : gcd[6+j].gd.label = &label[6+j];
531 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
532 0 : gcd[6+j].creator = GLabelCreate;
533 0 : hvarray2[0][3] = &gcd[6+j++]; hvarray2[0][4] = GCD_Glue; hvarray2[0][5] = NULL;
534 :
535 0 : hvarray2[1][0] = hvarray2[1][4] = GCD_Glue; hvarray2[1][5] = NULL;
536 0 : hvarray2[2][0] = hvarray2[2][4] = GCD_Glue; hvarray2[2][5] = NULL;
537 :
538 0 : label[6+j].text = (unichar_t *) _("X:");
539 0 : label[6+j].text_is_1byte = true;
540 0 : gcd[6+j].gd.label = &label[6+j];
541 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
542 0 : gcd[6+j].creator = GLabelCreate;
543 0 : hvarray2[1][1] = &gcd[6+j++];
544 :
545 0 : label[6+j].text = (unichar_t *) _("Y:");
546 0 : label[6+j].text_is_1byte = true;
547 0 : gcd[6+j].gd.label = &label[6+j];
548 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
549 0 : gcd[6+j].creator = GLabelCreate;
550 0 : hvarray2[2][1] = &gcd[6+j++];
551 :
552 0 : for ( i=0; i<4; ++i ) {
553 0 : sprintf(bbbuf[i],"%g", (double) ((&ref->bb.minx)[i]));
554 0 : label[6+j].text = (unichar_t *) bbbuf[i];
555 0 : label[6+j].text_is_1byte = true;
556 0 : gcd[6+j].gd.label = &label[6+j];
557 0 : gcd[6+j].gd.flags = gg_enabled|gg_visible;
558 0 : gcd[6+j].creator = GLabelCreate;
559 0 : hvarray2[1+i/2][2+(i&1)] = &gcd[6+j++];
560 : }
561 0 : hvarray2[3][0] = NULL;
562 :
563 0 : boxes[4].gd.flags = gg_enabled|gg_visible;
564 0 : boxes[4].gd.u.boxelements = hvarray2[0];
565 0 : boxes[4].creator = GHVBoxCreate;
566 0 : varray[l++] = &boxes[4];
567 :
568 0 : gcd[6+j].gd.pos.x = 5; gcd[6+j].gd.pos.y = RI_Height+(j==10?12:0)-70;
569 0 : gcd[6+j].gd.pos.width = RI_Width-10;
570 0 : gcd[6+j].gd.flags = gg_visible | gg_enabled;
571 0 : varray[l++] = &gcd[6+j];
572 0 : gcd[6+j++].creator = GLineCreate;
573 :
574 0 : gcd[6+j].gd.pos.x = (RI_Width-GIntGetResource(_NUM_Buttonsize))/2;
575 0 : gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+6;
576 0 : gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
577 0 : gcd[6+j].gd.flags = gg_visible | gg_enabled ;
578 0 : label[6+j].text = (unichar_t *) _("_Show");
579 0 : label[6+j].text_is_1byte = true;
580 0 : label[6+j].text_in_resource = true;
581 0 : gcd[6+j].gd.mnemonic = 'S';
582 0 : gcd[6+j].gd.label = &label[6+j];
583 0 : gcd[6+j].gd.handle_controlevent = GI_Show;
584 0 : harray2[0] = GCD_Glue; harray2[1] = &gcd[6+j]; harray2[2] = GCD_Glue; harray2[3] = NULL;
585 0 : gcd[6+j++].creator = GButtonCreate;
586 :
587 0 : boxes[5].gd.flags = gg_enabled|gg_visible;
588 0 : boxes[5].gd.u.boxelements = harray2;
589 0 : boxes[5].creator = GHBoxCreate;
590 0 : varray[l++] = &boxes[5];
591 :
592 0 : gcd[6+j] = gcd[6+j-2];
593 0 : varray[l++] = &gcd[6+j++];
594 :
595 0 : gcd[6+j].gd.pos.x = 30-3; gcd[6+j].gd.pos.y = RI_Height+(j==13?12:0)-30-3;
596 0 : gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
597 0 : gcd[6+j].gd.flags = gg_visible | gg_enabled | gg_but_default;
598 0 : label[6+j].text = (unichar_t *) _("_OK");
599 0 : label[6+j].text_is_1byte = true;
600 0 : label[6+j].text_in_resource = true;
601 0 : gcd[6+j].gd.mnemonic = 'O';
602 0 : gcd[6+j].gd.label = &label[6+j];
603 0 : gcd[6+j].gd.handle_controlevent = GI_ROK;
604 0 : gcd[6+j++].creator = GButtonCreate;
605 :
606 0 : gcd[6+j].gd.pos.x = -30; gcd[6+j].gd.pos.y = gcd[6+j-1].gd.pos.y+3;
607 0 : gcd[6+j].gd.pos.width = -1; gcd[6+j].gd.pos.height = 0;
608 0 : gcd[6+j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
609 0 : label[6+j].text = (unichar_t *) _("_Cancel");
610 0 : label[6+j].text_is_1byte = true;
611 0 : label[6+j].text_in_resource = true;
612 0 : gcd[6+j].gd.mnemonic = 'C';
613 0 : gcd[6+j].gd.label = &label[6+j];
614 0 : gcd[6+j].gd.handle_controlevent = GI_Cancel;
615 0 : gcd[6+j].creator = GButtonCreate;
616 :
617 0 : harray3[0] = GCD_Glue; harray3[1] = &gcd[6+j-1]; harray3[2] = GCD_Glue;
618 0 : harray3[3] = GCD_Glue; harray3[4] = &gcd[6+j]; harray3[5] = GCD_Glue;
619 0 : harray3[6] = NULL;
620 0 : boxes[6].gd.flags = gg_enabled|gg_visible;
621 0 : boxes[6].gd.u.boxelements = harray3;
622 0 : boxes[6].creator = GHBoxCreate;
623 0 : varray[l++] = &boxes[6];
624 0 : varray[l] = NULL;
625 :
626 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
627 0 : boxes[0].gd.u.boxelements = varray;
628 0 : boxes[0].creator = GVBoxCreate;
629 :
630 0 : GGadgetsCreate(gi.gw,boxes);
631 0 : GWidgetIndicateFocusGadget(gcd[j].ret);
632 0 : GHVBoxSetExpandableRow(boxes[0].ret,0);
633 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
634 0 : GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
635 0 : GHVBoxSetPadding(boxes[3].ret,6,2);
636 0 : GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
637 0 : GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
638 0 : GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
639 0 : GHVBoxFitWindow(boxes[0].ret);
640 :
641 0 : GWidgetHidePalettes();
642 0 : GDrawSetVisible(gi.gw,true);
643 0 : while ( !gi.done )
644 0 : GDrawProcessOneEvent(NULL);
645 0 : GDrawDestroyWindow(gi.gw);
646 0 : }
647 :
648 0 : static void ImgGetInfo(CharView *cv, ImageList *img) {
649 : static GIData gi;
650 : GRect pos;
651 : GWindowAttrs wattrs;
652 : GGadgetCreateData gcd[12], boxes[3], *varray[11], *harray[6];
653 : GTextInfo label[12];
654 : char posbuf[100], scalebuf[100], sizebuf[100];
655 0 : struct _GImage *base = img->image->list_len==0?
656 0 : img->image->u.image:img->image->u.images[0];
657 :
658 0 : gi.cv = cv;
659 0 : gi.sc = cv->b.sc;
660 0 : gi.img = img;
661 0 : gi.done = false;
662 :
663 0 : memset(&wattrs,0,sizeof(wattrs));
664 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
665 0 : wattrs.event_masks = ~(1<<et_charup);
666 0 : wattrs.restrict_input_to_me = 1;
667 0 : wattrs.undercursor = 1;
668 0 : wattrs.cursor = ct_pointer;
669 0 : wattrs.utf8_window_title = _("Image Info");
670 0 : wattrs.is_dlg = true;
671 0 : pos.x = pos.y = 0;
672 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,II_Width));
673 0 : pos.height = GDrawPointsToPixels(NULL,II_Height);
674 0 : gi.gw = GDrawCreateTopWindow(NULL,&pos,gi_e_h,&gi,&wattrs);
675 :
676 0 : memset(&gcd,0,sizeof(gcd));
677 0 : memset(&label,0,sizeof(label));
678 :
679 0 : sprintf( posbuf, _("Image at: (%.0f,%.0f)"), (double) img->xoff,
680 0 : (double) (img->yoff-GImageGetHeight(img->image)*img->yscale));
681 0 : label[0].text = (unichar_t *) posbuf;
682 0 : label[0].text_is_1byte = true;
683 0 : gcd[0].gd.label = &label[0];
684 0 : gcd[0].gd.pos.x = 5; gcd[0].gd.pos.y = 5;
685 0 : gcd[0].gd.flags = gg_enabled|gg_visible;
686 0 : gcd[0].creator = GLabelCreate;
687 0 : varray[0] = &gcd[0]; varray[1] = NULL;
688 :
689 0 : sprintf( scalebuf, _("Scaled by: (%.2f,%.2f)"), (double) img->xscale, (double) img->yscale );
690 0 : label[1].text = (unichar_t *) scalebuf;
691 0 : label[1].text_is_1byte = true;
692 0 : gcd[1].gd.label = &label[1];
693 0 : gcd[1].gd.pos.x = 5; gcd[1].gd.pos.y = 19;
694 0 : gcd[1].gd.flags = gg_enabled|gg_visible;
695 0 : gcd[1].creator = GLabelCreate;
696 0 : varray[2] = &gcd[1]; varray[3] = NULL;
697 :
698 0 : sprintf( sizebuf, _("Image Size: %d x %d pixels"), (int) base->width, (int) base->height );
699 0 : label[2].text = (unichar_t *) sizebuf;
700 0 : label[2].text_is_1byte = true;
701 0 : gcd[2].gd.label = &label[2];
702 0 : gcd[2].gd.pos.x = 5; gcd[2].gd.pos.y = 19;
703 0 : gcd[2].gd.flags = gg_enabled|gg_visible;
704 0 : gcd[2].creator = GLabelCreate;
705 0 : varray[4] = &gcd[2]; varray[5] = NULL;
706 0 : varray[6] = GCD_Glue; varray[7] = NULL;
707 :
708 0 : gcd[3].gd.pos.x = (II_Width-GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor)-6)/2; gcd[3].gd.pos.y = II_Height-32-3;
709 0 : gcd[3].gd.pos.width = -1; gcd[3].gd.pos.height = 0;
710 0 : gcd[3].gd.flags = gg_visible | gg_enabled | gg_but_default | gg_but_cancel;
711 0 : label[3].text = (unichar_t *) _("_OK");
712 0 : label[3].text_is_1byte = true;
713 0 : label[3].text_in_resource = true;
714 0 : gcd[3].gd.mnemonic = 'O';
715 0 : gcd[3].gd.label = &label[3];
716 0 : gcd[3].gd.handle_controlevent = GI_Cancel;
717 0 : gcd[3].creator = GButtonCreate;
718 0 : harray[0] = GCD_Glue; harray[1] = &gcd[3]; harray[2] = GCD_Glue; harray[3] = NULL;
719 0 : varray[8] = &boxes[2]; varray[9] = NULL;
720 0 : varray[10] = NULL;
721 :
722 0 : memset(boxes,0,sizeof(boxes));
723 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
724 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
725 0 : boxes[0].gd.u.boxelements = varray;
726 0 : boxes[0].creator = GHVGroupCreate;
727 :
728 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
729 0 : boxes[2].gd.u.boxelements = harray;
730 0 : boxes[2].creator = GHBoxCreate;
731 :
732 0 : GGadgetsCreate(gi.gw,boxes);
733 0 : GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
734 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
735 0 : GHVBoxFitWindow(boxes[0].ret);
736 :
737 0 : GWidgetHidePalettes();
738 0 : GDrawSetVisible(gi.gw,true);
739 0 : while ( !gi.done )
740 0 : GDrawProcessOneEvent(NULL);
741 0 : GDrawDestroyWindow(gi.gw);
742 0 : }
743 :
744 0 : static AnchorClass *_AnchorClassUnused(SplineChar *sc,int *waslig, int classmatch) {
745 : AnchorClass *an, *maybe;
746 : int val, maybelig;
747 : SplineFont *sf;
748 : int ismarkglyph, isligatureglyph;
749 : PST *pst;
750 : /* Are there any anchors with this name? If so can't reuse it */
751 : /* unless they are ligature anchors */
752 : /* or 'curs' anchors, which allow exactly two points (entry, exit) */
753 : /* or 'mkmk' anchors, which allow a mark to be both a base and an attach */
754 :
755 0 : ismarkglyph = (sc->width==0) || sc->glyph_class==(3+1) ||
756 0 : ( sc->unicodeenc!=-1 && sc->unicodeenc<0x10000 && iscombining(sc->unicodeenc)) ||
757 0 : ( sc->anchor!=NULL && (sc->anchor->type == at_mark || sc->anchor->type == at_basemark));
758 0 : for ( pst = sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
759 0 : isligatureglyph = (pst!=NULL) || sc->glyph_class==2+1;
760 :
761 0 : *waslig = false; maybelig = false; maybe = NULL;
762 0 : sf = sc->parent;
763 0 : if ( sf->cidmaster!=NULL ) sf = sf->cidmaster;
764 0 : for ( an=sf->anchor; an!=NULL; an=an->next ) {
765 0 : if ( classmatch ) {
766 0 : if (( an->type == act_mklg && !isligatureglyph && !ismarkglyph ) ||
767 0 : ( an->type == act_mkmk && !ismarkglyph ))
768 0 : continue;
769 : }
770 0 : val = IsAnchorClassUsed(sc,an);
771 0 : if ( val>=0 ) {
772 0 : *waslig = val;
773 0 : return( an );
774 0 : } else if ( val!=-1 && maybe==NULL ) {
775 0 : maybe = an;
776 0 : maybelig = val;
777 : }
778 : }
779 0 : *waslig = maybelig;
780 0 : return( maybe );
781 : }
782 :
783 0 : AnchorClass *AnchorClassUnused(SplineChar *sc,int *waslig) {
784 0 : return( _AnchorClassUnused(sc,waslig,false));
785 : }
786 :
787 0 : static AnchorPoint *AnchorPointNew(CharView *cv) {
788 : AnchorClass *an;
789 : AnchorPoint *ap;
790 : int waslig;
791 0 : SplineChar *sc = cv->b.sc;
792 : PST *pst;
793 :
794 0 : an = _AnchorClassUnused(sc,&waslig,true);
795 0 : if ( an==NULL )
796 0 : an = AnchorClassUnused(sc,&waslig);
797 :
798 0 : if ( an==NULL )
799 0 : return(NULL);
800 0 : ap = chunkalloc(sizeof(AnchorPoint));
801 0 : ap->anchor = an;
802 0 : ap->me.x = cv->p.cx; /* cv->p.cx = 0; */
803 0 : ap->me.y = cv->p.cy; /* cv->p.cy = 0; */
804 0 : ap->type = an->type==act_mark ? at_basechar :
805 0 : an->type==act_mkmk ? at_basemark :
806 0 : an->type==act_mklg ? at_baselig :
807 0 : an->type==act_curs ? at_centry :
808 : at_basechar;
809 0 : for ( pst = cv->b.sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
810 0 : if ( waslig<-1 && an->type==act_mkmk ) {
811 0 : ap->type = waslig==-2 ? at_basemark : at_mark;
812 0 : } else if ( waslig==-2 && an->type==act_curs )
813 0 : ap->type = at_cexit;
814 0 : else if ( waslig==-3 || an->type==act_curs )
815 0 : ap->type = at_centry;
816 0 : else if (( sc->unicodeenc!=-1 && sc->unicodeenc<0x10000 &&
817 0 : iscombining(sc->unicodeenc)) || sc->width==0 || sc->glyph_class==(3+1) /* mark class+1 */)
818 0 : ap->type = at_mark;
819 0 : else if ( an->type==act_mkmk )
820 0 : ap->type = at_basemark;
821 0 : else if (( pst!=NULL || waslig || sc->glyph_class==2+1) && an->type==act_mklg )
822 0 : ap->type = at_baselig;
823 0 : if (( ap->type==at_basechar || ap->type==at_baselig ) && an->type==act_mkmk )
824 0 : ap->type = at_basemark;
825 0 : ap->next = sc->anchor;
826 0 : if ( waslig>=0 )
827 0 : ap->lig_index = waslig;
828 0 : sc->anchor = ap;
829 0 : return( ap );
830 : }
831 :
832 0 : static void AI_SelectList(GIData *ci,AnchorPoint *ap) {
833 : int i;
834 : AnchorClass *an;
835 0 : SplineFont *sf = ci->sc->parent;
836 :
837 0 : if ( sf->cidmaster ) sf = sf->cidmaster;
838 :
839 0 : for ( i=0, an=sf->anchor; an!=ap->anchor; ++i, an=an->next );
840 0 : GGadgetSelectOneListItem(GWidgetGetControl(ci->gw,CID_NameList),i);
841 0 : }
842 :
843 0 : static void AI_DisplayClass(GIData *ci,AnchorPoint *ap) {
844 0 : AnchorClass *ac = ap->anchor;
845 : AnchorPoint *aps;
846 : int saw[at_max];
847 :
848 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseChar),ac->type==act_mark || ac->type==act_unknown);
849 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseLig),ac->type==act_mklg);
850 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseMark),ac->type==act_mkmk);
851 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursEntry),ac->type==act_curs);
852 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursExit),ac->type==act_curs);
853 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Mark),ac->type!=act_curs);
854 :
855 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
856 :
857 0 : if ( ac->type==act_mkmk && (ap->type==at_basechar || ap->type==at_baselig)) {
858 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseMark),true);
859 0 : ap->type = at_basemark;
860 0 : } else if ( ac->type==act_mark && ap->type==at_basemark ) {
861 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseChar),true);
862 0 : ap->type = at_basechar;
863 0 : } else if ( ac->type==act_curs && ap->type!=at_centry && ap->type!=at_cexit ) {
864 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursEntry),true);
865 0 : ap->type = at_centry;
866 : }
867 :
868 0 : memset(saw,0,sizeof(saw));
869 0 : for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) if ( aps!=ap ) {
870 0 : if ( aps->anchor==ac ) saw[aps->type] = true;
871 : }
872 0 : if ( ac->type==act_curs ) {
873 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursEntry),!saw[at_centry]);
874 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_CursExit),!saw[at_cexit]);
875 : } else {
876 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Mark),!saw[at_mark]);
877 0 : if ( saw[at_basechar]) GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseChar),false);
878 0 : if ( saw[at_basemark]) GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_BaseMark),false);
879 : }
880 0 : }
881 :
882 0 : static void AI_DisplayIndex(GIData *ci,AnchorPoint *ap) {
883 : char buffer[12];
884 :
885 0 : sprintf(buffer,"%d", ap->lig_index );
886 :
887 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_LigIndex),buffer);
888 0 : }
889 :
890 0 : static void AI_DisplayRadio(GIData *ci,enum anchor_type type) {
891 0 : switch ( type ) {
892 : case at_mark:
893 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Mark),true);
894 0 : break;
895 : case at_basechar:
896 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseChar),true);
897 0 : break;
898 : case at_baselig:
899 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseLig),true);
900 0 : break;
901 : case at_basemark:
902 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_BaseMark),true);
903 0 : break;
904 : case at_centry:
905 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursEntry),true);
906 0 : break;
907 : case at_cexit:
908 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_CursExit),true);
909 0 : break;
910 : }
911 0 : }
912 :
913 0 : static void AI_Display(GIData *ci,AnchorPoint *ap) {
914 : char val[40];
915 : unichar_t uval[40];
916 : AnchorPoint *aps;
917 :
918 0 : if ( ap==NULL) {
919 0 : SCUpdateAll(ci->sc);
920 0 : return;
921 : }
922 :
923 0 : ci->ap = ap;
924 0 : for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next )
925 0 : aps->selected = false;
926 0 : ap->selected = true;
927 0 : sprintf(val,"%g",(double) ap->me.x);
928 0 : uc_strcpy(uval,val);
929 0 : GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_X),uval);
930 0 : sprintf(val,"%g",(double) ap->me.y);
931 0 : uc_strcpy(uval,val);
932 0 : GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_Y),uval);
933 0 : sprintf(val,"%d",ap->type==at_baselig?ap->lig_index:0);
934 0 : uc_strcpy(uval,val);
935 0 : GGadgetSetTitle(GWidgetGetControl(ci->gw,CID_LigIndex),uval);
936 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
937 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Next),ap->next!=NULL);
938 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Prev),ci->sc->anchor!=ap);
939 0 : if ( ap->has_ttf_pt )
940 0 : sprintf(val,"%d",ap->ttf_pt_index);
941 : else
942 0 : val[0] = '\0';
943 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_MatchPt),val);
944 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_X),!ap->has_ttf_pt);
945 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Y),!ap->has_ttf_pt);
946 :
947 0 : AI_DisplayClass(ci,ap);
948 0 : AI_DisplayRadio(ci,ap->type);
949 :
950 0 : AI_SelectList(ci,ap);
951 0 : SCUpdateAll(ci->sc);
952 : }
953 :
954 0 : static int AI_Next(GGadget *g, GEvent *e) {
955 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
956 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
957 :
958 0 : if ( ci->ap->next==NULL )
959 0 : return( true );
960 0 : AI_Display(ci,ci->ap->next);
961 : }
962 0 : return( true );
963 : }
964 :
965 0 : static int AI_Prev(GGadget *g, GEvent *e) {
966 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
967 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
968 : AnchorPoint *ap, *prev;
969 :
970 0 : prev = NULL;
971 0 : for ( ap=ci->sc->anchor; ap!=ci->ap; ap = ap->next )
972 0 : prev = ap;
973 0 : if ( prev==NULL )
974 0 : return( true );
975 0 : AI_Display(ci,prev);
976 : }
977 0 : return( true );
978 : }
979 :
980 : static int AI_Ok(GGadget *g, GEvent *e);
981 0 : static int AI_Delete(GGadget *g, GEvent *e) {
982 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
983 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
984 : AnchorPoint *ap, *prev, *delete_it;
985 :
986 0 : prev=NULL;
987 0 : for ( ap=ci->sc->anchor; ap!=ci->ap; ap=ap->next )
988 0 : prev = ap;
989 0 : if ( prev==NULL && ci->ap->next==NULL ) {
990 : static char *buts[3];
991 0 : buts[0] = _("_Yes"); buts[1] = _("_No"); buts[2] = NULL;
992 0 : if ( gwwv_ask(_("Last Anchor Point"),(const char **) buts,0,1, _("You are deleting the last anchor point in this character.\nDoing so will cause this dialog to close, is that what you want?"))==1 ) {
993 0 : AI_Ok(g,e);
994 0 : return( true );
995 : }
996 : }
997 :
998 0 : delete_it = ci->ap;
999 :
1000 0 : if ((prev == NULL) && (ci->ap->next == NULL)) {
1001 0 : ci->sc->anchor = NULL;
1002 0 : AnchorPointsFree(delete_it);
1003 0 : AI_Ok(g,e);
1004 0 : SCUpdateAll(ci->sc);
1005 : }
1006 0 : else if (ci->ap->next == NULL) {
1007 0 : prev->next = NULL;
1008 0 : AnchorPointsFree(delete_it);
1009 0 : AI_Display(ci,prev);
1010 : }
1011 0 : else if (prev == NULL) {
1012 0 : ci->sc->anchor = delete_it->next;
1013 0 : delete_it->next = NULL;
1014 0 : AnchorPointsFree(delete_it);
1015 0 : AI_Display(ci,ci->sc->anchor);
1016 : }
1017 : else {
1018 0 : prev->next = delete_it->next;
1019 0 : delete_it->next = NULL;
1020 0 : AnchorPointsFree(delete_it);
1021 0 : AI_Display(ci,prev->next);
1022 : }
1023 :
1024 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1025 : }
1026 0 : return( true );
1027 : }
1028 :
1029 0 : static GTextInfo **AnchorClassesLList(SplineFont *sf) {
1030 : AnchorClass *an;
1031 : int cnt;
1032 : GTextInfo **ti;
1033 :
1034 0 : if ( sf->cidmaster ) sf=sf->cidmaster;
1035 :
1036 0 : for ( cnt=0, an=sf->anchor; an!=NULL; ++cnt, an=an->next );
1037 0 : ti = calloc(cnt+1,sizeof(GTextInfo*));
1038 0 : for ( cnt=0, an=sf->anchor; an!=NULL; ++cnt, an=an->next ) {
1039 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
1040 0 : ti[cnt]->text = utf82u_copy(an->name);
1041 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
1042 0 : ti[cnt]->userdata = an;
1043 : }
1044 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
1045 0 : return( ti );
1046 : }
1047 :
1048 0 : static int AI_NewClass(GGadget *g, GEvent *e) {
1049 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1050 0 : SplineFont *sf = ci->sc->parent;
1051 : AnchorClass *ac;
1052 : GTextInfo **ti;
1053 : int j;
1054 0 : char *name = gwwv_ask_string(_("Anchor Class Name"),"",_("Please enter the name of a Anchor point class to create"));
1055 0 : if ( name==NULL )
1056 0 : return( true );
1057 0 : ac = SFFindOrAddAnchorClass(sf,name,NULL);
1058 0 : GGadgetSetList(GWidgetGetControl(ci->gw,CID_NameList),
1059 : ti = AnchorClassesLList(sf),false);
1060 0 : for ( j=0; ti[j]->text!=NULL && ti[j]->userdata!=ac; ++j )
1061 0 : GGadgetSelectOneListItem(GWidgetGetControl(ci->gw,CID_NameList),j);
1062 0 : return( true );
1063 : }
1064 :
1065 0 : static int AI_New(GGadget *g, GEvent *e) {
1066 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1067 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1068 : int waslig;
1069 : AnchorPoint *ap;
1070 0 : SplineFont *sf = ci->sc->parent;
1071 :
1072 0 : if ( sf->cidmaster ) sf = sf->cidmaster;
1073 :
1074 0 : if ( AnchorClassUnused(ci->sc,&waslig)==NULL ) {
1075 0 : if ( !AI_NewClass(g, e) )
1076 0 : return( false );
1077 : }
1078 0 : ap = AnchorPointNew(ci->cv);
1079 0 : if ( ap==NULL )
1080 0 : return( true );
1081 0 : AI_Display(ci,ap);
1082 : }
1083 0 : return( true );
1084 : }
1085 :
1086 0 : static int AI_TypeChanged(GGadget *g, GEvent *e) {
1087 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
1088 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1089 0 : AnchorPoint *ap = ci->ap;
1090 :
1091 0 : if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Mark)) )
1092 0 : ap->type = at_mark;
1093 0 : else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseChar)) )
1094 0 : ap->type = at_basechar;
1095 0 : else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseLig)) )
1096 0 : ap->type = at_baselig;
1097 0 : else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_BaseMark)) )
1098 0 : ap->type = at_basemark;
1099 0 : else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_CursEntry)) )
1100 0 : ap->type = at_centry;
1101 0 : else if ( GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_CursExit)) )
1102 0 : ap->type = at_cexit;
1103 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_LigIndex),ap->type==at_baselig);
1104 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1105 : }
1106 0 : return( true );
1107 : }
1108 :
1109 0 : static void AI_TestOrdering(GIData *ci,real x) {
1110 0 : AnchorPoint *aps, *ap=ci->ap;
1111 0 : AnchorClass *ac = ap->anchor;
1112 : int isr2l;
1113 :
1114 0 : isr2l = SCRightToLeft(ci->sc);
1115 0 : for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) {
1116 0 : if ( aps->anchor==ac && aps!=ci->ap ) {
1117 0 : if (( aps->lig_index<ap->lig_index &&
1118 0 : ((!isr2l && aps->me.x>x) ||
1119 0 : ( isr2l && aps->me.x<x))) ||
1120 0 : ( aps->lig_index>ap->lig_index &&
1121 0 : (( isr2l && aps->me.x>x) ||
1122 0 : (!isr2l && aps->me.x<x))) ) {
1123 0 : ff_post_error(_("Out Of Order"),_("Marks within a ligature should be ordered with the direction of writing.\nThis one and %d are out of order."),aps->lig_index);
1124 0 : return;
1125 : }
1126 : }
1127 : }
1128 0 : return;
1129 : }
1130 :
1131 0 : static int AI_LigIndexChanged(GGadget *g, GEvent *e) {
1132 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
1133 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1134 : int index, max;
1135 0 : int err=false;
1136 0 : AnchorPoint *ap = ci->ap, *aps;
1137 :
1138 0 : index = GetCalmReal8(ci->gw,CID_LigIndex,_("Lig Index:"),&err);
1139 0 : if ( index<0 || err )
1140 0 : return( true );
1141 0 : if ( *_GGadgetGetTitle(g)=='\0' )
1142 0 : return( true );
1143 0 : max = 0;
1144 0 : AI_TestOrdering(ci,ap->me.x);
1145 0 : for ( aps=ci->sc->anchor; aps!=NULL; aps=aps->next ) {
1146 0 : if ( aps->anchor==ap->anchor && aps!=ap ) {
1147 0 : if ( aps->lig_index==index ) {
1148 0 : ff_post_error(_("Index in use"),_("This ligature index is already in use"));
1149 0 : return( true );
1150 0 : } else if ( aps->lig_index>max )
1151 0 : max = aps->lig_index;
1152 : }
1153 : }
1154 0 : if ( index>max+10 ) {
1155 : char buf[20];
1156 0 : ff_post_error(_("Too Big"),_("This index is much larger than the closest neighbor"));
1157 0 : sprintf(buf,"%d", max+1);
1158 0 : GGadgetSetTitle8(g,buf);
1159 0 : index = max+1;
1160 : }
1161 0 : ap->lig_index = index;
1162 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1163 : }
1164 0 : return( true );
1165 : }
1166 :
1167 0 : static int AI_ANameChanged(GGadget *g, GEvent *e) {
1168 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
1169 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1170 : AnchorPoint *ap;
1171 0 : GTextInfo *ti = GGadgetGetListItemSelected(g);
1172 0 : AnchorClass *an = ti->userdata;
1173 0 : int change=0, max=0;
1174 : int ntype;
1175 : int sawentry, sawexit;
1176 :
1177 0 : if ( an==ci->ap->anchor )
1178 0 : return( true ); /* No op */
1179 :
1180 0 : ntype = ci->ap->type;
1181 0 : if ( an->type==act_curs ) {
1182 0 : if ( ntype!=at_centry && ntype!=at_cexit )
1183 0 : ntype = at_centry;
1184 0 : } else if ( an->type==act_mkmk ) {
1185 0 : if ( ntype!=at_basemark && ntype!=at_mark )
1186 0 : ntype = at_basemark;
1187 0 : } else if ( ntype==at_centry || ntype==at_cexit || ntype==at_basemark ||
1188 0 : ntype==at_baselig || ntype == at_basechar ) {
1189 : PST *pst;
1190 0 : for ( pst = ci->sc->possub; pst!=NULL && pst->type!=pst_ligature; pst=pst->next );
1191 0 : if (ci->sc->glyph_class==3+1 ||
1192 0 : (ci->sc->unicodeenc!=-1 && ci->sc->unicodeenc<0x10000 &&
1193 0 : iscombining(ci->sc->unicodeenc)))
1194 0 : ntype = at_mark;
1195 0 : else if (( pst!=NULL || ci->sc->glyph_class==2+1 ) && an->type==act_mklg )
1196 0 : ntype = at_baselig;
1197 : else
1198 0 : ntype = at_basechar;
1199 : }
1200 :
1201 0 : sawentry = sawexit = false;
1202 0 : for ( ap=ci->sc->anchor; ap!=NULL; ap = ap->next ) {
1203 0 : if ( ap!=ci->ap && ap->anchor==an ) {
1204 0 : if ( an->type==act_curs ) {
1205 0 : if ( ap->type == at_centry ) sawentry = true;
1206 0 : else if ( ap->type== at_cexit ) sawexit = true;
1207 0 : } else if ( an->type==act_mkmk ) {
1208 0 : if ( ap->type == at_mark ) sawentry = true;
1209 0 : else if ( ap->type== at_basemark ) sawexit = true;
1210 : } else {
1211 0 : if ( ap->type!=at_baselig )
1212 0 : break;
1213 0 : if ( ap->lig_index==ci->ap->lig_index )
1214 0 : change = true;
1215 0 : else if ( ap->lig_index>max )
1216 0 : max = ap->lig_index;
1217 : }
1218 0 : } else if ( ap!=ci->ap && ap->anchor->subtable==an->subtable &&
1219 0 : ap->type==at_mark )
1220 0 : break;
1221 : }
1222 0 : if ( ap!=NULL || (sawentry && sawexit)) {
1223 0 : AI_SelectList(ci,ci->ap);
1224 0 : ff_post_error(_("Class already used"),_("This anchor class already is associated with a point in this character"));
1225 : } else {
1226 0 : ci->ap->anchor = an;
1227 0 : if ( an->type==act_curs ) {
1228 0 : if ( sawentry ) ntype = at_cexit;
1229 0 : else if ( sawexit ) ntype = at_centry;
1230 0 : } else if ( an->type==act_mkmk ) {
1231 0 : if ( sawentry ) ntype = at_basemark;
1232 0 : else if ( sawexit ) ntype = at_mark;
1233 : }
1234 0 : if ( ci->ap->type!=ntype ) {
1235 0 : ci->ap->type = ntype;
1236 0 : AI_DisplayRadio(ci,ntype);
1237 : }
1238 0 : if ( ci->ap->type!=at_baselig )
1239 0 : ci->ap->lig_index = 0;
1240 0 : else if ( change ) {
1241 0 : ci->ap->lig_index = max+1;
1242 0 : AI_DisplayIndex(ci,ci->ap);
1243 : }
1244 0 : AI_DisplayClass(ci,ci->ap);
1245 0 : AI_TestOrdering(ci,ci->ap->me.x);
1246 : }
1247 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1248 : }
1249 0 : return( true );
1250 : }
1251 :
1252 0 : static int AI_PosChanged(GGadget *g, GEvent *e) {
1253 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
1254 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1255 0 : real dx=0, dy=0;
1256 0 : int err=false;
1257 0 : AnchorPoint *ap = ci->ap;
1258 :
1259 0 : if ( GGadgetGetCid(g)==CID_X ) {
1260 0 : dx = GetCalmReal8(ci->gw,CID_X,_("_X"),&err)-ap->me.x;
1261 0 : AI_TestOrdering(ci,ap->me.x+dx);
1262 : } else
1263 0 : dy = GetCalmReal8(ci->gw,CID_Y,_("_Y"),&err)-ap->me.y;
1264 0 : if ( (dx==0 && dy==0) || err )
1265 0 : return( true );
1266 0 : ap->me.x += dx;
1267 0 : ap->me.y += dy;
1268 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1269 : }
1270 0 : return( true );
1271 : }
1272 :
1273 0 : static int AI_MatchChanged(GGadget *g, GEvent *e) {
1274 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
1275 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1276 0 : const unichar_t *t1 = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_MatchPt));
1277 : unichar_t *end;
1278 0 : AnchorPoint *ap = ci->ap;
1279 :
1280 0 : while ( *t1==' ' ) ++t1;
1281 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_X),*t1=='\0');
1282 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Y),*t1=='\0');
1283 0 : if ( isdigit(*t1)) {
1284 : BasePoint here;
1285 : int pt;
1286 0 : pt = u_strtol(t1,&end,10);
1287 0 : if ( *end=='\0' && ttfFindPointInSC(ci->cv->b.sc,CVLayer((CharViewBase *) ci->cv),pt,&here,NULL)==-1 ) {
1288 : char buffer[40];
1289 0 : sprintf(buffer,"%g",(double) here.x);
1290 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_X),buffer);
1291 0 : sprintf(buffer,"%g",(double) here.y);
1292 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_Y),buffer);
1293 0 : ap->me = here;
1294 0 : ap->has_ttf_pt = true;
1295 0 : ap->ttf_pt_index = pt;
1296 0 : _CVCharChangedUpdate(&ci->cv->b,2);
1297 : }
1298 : } else
1299 0 : ap->has_ttf_pt = false;
1300 : }
1301 0 : return( true );
1302 : }
1303 :
1304 0 : static void AI_DoCancel(GIData *ci) {
1305 0 : CharView *cv = ci->cv;
1306 0 : ci->done = true;
1307 0 : AnchorPointsFree(cv->b.sc->anchor);
1308 0 : cv->b.sc->anchor = ci->oldaps;
1309 0 : ci->oldaps = NULL;
1310 0 : CVRemoveTopUndo(&cv->b);
1311 0 : SCUpdateAll(cv->b.sc);
1312 0 : }
1313 :
1314 0 : static int ai_e_h(GWindow gw, GEvent *event) {
1315 0 : if ( event->type==et_close ) {
1316 0 : AI_DoCancel( GDrawGetUserData(gw));
1317 0 : } else if ( event->type==et_char ) {
1318 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
1319 0 : help("getinfo.html");
1320 0 : return( true );
1321 : }
1322 0 : return( false );
1323 0 : } else if ( event->type == et_map ) {
1324 : /* Above palettes */
1325 0 : GDrawRaise(gw);
1326 : }
1327 0 : return( true );
1328 : }
1329 :
1330 0 : static int AI_Cancel(GGadget *g, GEvent *e) {
1331 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1332 0 : AI_DoCancel( GDrawGetUserData(GGadgetGetWindow(g)));
1333 : }
1334 0 : return( true );
1335 : }
1336 :
1337 0 : static int AI_Ok(GGadget *g, GEvent *e) {
1338 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1339 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1340 0 : ci->done = true;
1341 : /* All the work has been done as we've gone along */
1342 : /* Well, we should reorder the list... */
1343 0 : SCOrderAP(ci->cv->b.sc);
1344 : }
1345 0 : return( true );
1346 : }
1347 :
1348 0 : void ApGetInfo(CharView *cv, AnchorPoint *ap) {
1349 : static GIData gi;
1350 : GRect pos;
1351 : GWindowAttrs wattrs;
1352 : GGadgetCreateData gcd[25], boxes[10], *varray[21], *harray1[5], *harray2[3],
1353 : *hvarray[13], *harray3[4], *harray4[6], *harray5[6], *harray6[7];
1354 : GTextInfo label[25];
1355 : int j;
1356 : SplineFont *sf;
1357 : GTextInfo **ti;
1358 :
1359 0 : memset(&gi,0,sizeof(gi));
1360 0 : gi.cv = cv;
1361 0 : gi.sc = cv->b.sc;
1362 0 : gi.oldaps = AnchorPointsCopy(cv->b.sc->anchor);
1363 0 : CVPreserveState(&cv->b);
1364 0 : if ( ap==NULL ) {
1365 0 : ap = AnchorPointNew(cv);
1366 0 : if ( ap==NULL )
1367 0 : return;
1368 : }
1369 :
1370 0 : gi.ap = ap;
1371 0 : gi.changed = false;
1372 0 : gi.done = false;
1373 :
1374 0 : memset(&wattrs,0,sizeof(wattrs));
1375 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
1376 0 : wattrs.event_masks = ~(1<<et_charup);
1377 0 : wattrs.restrict_input_to_me = 1;
1378 0 : wattrs.undercursor = 1;
1379 0 : wattrs.cursor = ct_pointer;
1380 0 : wattrs.utf8_window_title = _("Anchor Point Info");
1381 0 : wattrs.is_dlg = true;
1382 0 : pos.x = pos.y = 0;
1383 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,AI_Width));
1384 0 : pos.height = GDrawPointsToPixels(NULL,AI_Height);
1385 0 : gi.gw = GDrawCreateTopWindow(NULL,&pos,ai_e_h,&gi,&wattrs);
1386 :
1387 0 : memset(&gcd,0,sizeof(gcd));
1388 0 : memset(&label,0,sizeof(label));
1389 0 : memset(&boxes,0,sizeof(boxes));
1390 :
1391 0 : j=0;
1392 0 : label[j].text = (unichar_t *) ap->anchor->name;
1393 0 : label[j].text_is_1byte = true;
1394 0 : gcd[j].gd.label = &label[j];
1395 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = 5;
1396 0 : gcd[j].gd.pos.width = AI_Width-10;
1397 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1398 0 : gcd[j].gd.cid = CID_NameList;
1399 0 : sf = cv->b.sc->parent;
1400 0 : if ( sf->cidmaster ) sf = sf->cidmaster;
1401 0 : gcd[j].gd.handle_controlevent = AI_ANameChanged;
1402 0 : gcd[j].creator = GListButtonCreate;
1403 0 : varray[0] = &gcd[j]; varray[1] = NULL;
1404 0 : ++j;
1405 :
1406 0 : label[j].text = (unichar_t *) _("_X:");
1407 0 : label[j].text_is_1byte = true;
1408 0 : label[j].text_in_resource = true;
1409 0 : gcd[j].gd.label = &label[j];
1410 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+34;
1411 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1412 0 : gcd[j].creator = GLabelCreate;
1413 0 : harray1[0] = &gcd[j];
1414 0 : ++j;
1415 :
1416 0 : gcd[j].gd.pos.x = 23; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4;
1417 0 : gcd[j].gd.pos.width = 50;
1418 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1419 0 : gcd[j].gd.cid = CID_X;
1420 0 : gcd[j].gd.handle_controlevent = AI_PosChanged;
1421 0 : gcd[j].creator = GNumericFieldCreate;
1422 0 : harray1[1] = &gcd[j];
1423 0 : ++j;
1424 :
1425 0 : label[j].text = (unichar_t *) _("_Y:");
1426 0 : label[j].text_is_1byte = true;
1427 0 : label[j].text_in_resource = true;
1428 0 : gcd[j].gd.label = &label[j];
1429 0 : gcd[j].gd.pos.x = 85; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y;
1430 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1431 0 : gcd[j].creator = GLabelCreate;
1432 0 : harray1[2] = &gcd[j];
1433 0 : ++j;
1434 :
1435 0 : gcd[j].gd.pos.x = 103; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y;
1436 0 : gcd[j].gd.pos.width = 50;
1437 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1438 0 : gcd[j].gd.cid = CID_Y;
1439 0 : gcd[j].gd.handle_controlevent = AI_PosChanged;
1440 0 : gcd[j].creator = GNumericFieldCreate;
1441 0 : harray1[3] = &gcd[j]; harray1[4] = NULL;
1442 0 : ++j;
1443 :
1444 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
1445 0 : boxes[2].gd.u.boxelements = harray1;
1446 0 : boxes[2].creator = GHBoxCreate;
1447 0 : varray[2] = &boxes[2]; varray[3] = NULL;
1448 :
1449 0 : label[j].text = (unichar_t *) _("Matching TTF Point:");
1450 0 : label[j].text_is_1byte = true;
1451 0 : gcd[j].gd.label = &label[j];
1452 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-2].gd.pos.y+24;
1453 0 : gcd[j].gd.flags = cv->b.sc->layers[ly_fore].order2 ? (gg_enabled|gg_visible) : gg_visible;
1454 0 : gcd[j].creator = GLabelCreate;
1455 0 : harray2[0] = &gcd[j];
1456 0 : ++j;
1457 :
1458 0 : gcd[j].gd.pos.x = 103; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
1459 0 : gcd[j].gd.pos.width = 50;
1460 0 : gcd[j].gd.flags = gcd[j-1].gd.flags;
1461 0 : gcd[j].gd.cid = CID_MatchPt;
1462 0 : gcd[j].gd.handle_controlevent = AI_MatchChanged;
1463 0 : gcd[j].creator = GTextFieldCreate;
1464 0 : harray2[1] = &gcd[j]; harray2[2] = NULL;
1465 0 : ++j;
1466 :
1467 0 : boxes[3].gd.flags = gg_enabled|gg_visible;
1468 0 : boxes[3].gd.u.boxelements = harray2;
1469 0 : boxes[3].creator = GHBoxCreate;
1470 0 : varray[4] = &boxes[3]; varray[5] = NULL;
1471 :
1472 0 : label[j].text = (unichar_t *) _("Mark");
1473 0 : label[j].text_is_1byte = true;
1474 0 : gcd[j].gd.label = &label[j];
1475 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
1476 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1477 0 : gcd[j].gd.cid = CID_Mark;
1478 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1479 0 : gcd[j].creator = GRadioCreate;
1480 0 : hvarray[0] = &gcd[j];
1481 0 : ++j;
1482 :
1483 0 : label[j].text = (unichar_t *) _("Base Glyph");
1484 0 : label[j].text_is_1byte = true;
1485 0 : gcd[j].gd.label = &label[j];
1486 0 : gcd[j].gd.pos.x = 70; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1487 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1488 0 : gcd[j].gd.cid = CID_BaseChar;
1489 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1490 0 : gcd[j].creator = GRadioCreate;
1491 0 : hvarray[1] = &gcd[j]; hvarray[2] = NULL;
1492 0 : ++j;
1493 :
1494 0 : label[j].text = (unichar_t *) _("Base Lig");
1495 0 : label[j].text_is_1byte = true;
1496 0 : gcd[j].gd.label = &label[j];
1497 0 : gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
1498 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1499 0 : gcd[j].gd.cid = CID_BaseLig;
1500 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1501 0 : gcd[j].creator = GRadioCreate;
1502 0 : hvarray[3] = &gcd[j];
1503 0 : ++j;
1504 :
1505 0 : label[j].text = (unichar_t *) _("Base Mark");
1506 0 : label[j].text_is_1byte = true;
1507 0 : gcd[j].gd.label = &label[j];
1508 0 : gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1509 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1510 0 : gcd[j].gd.cid = CID_BaseMark;
1511 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1512 0 : gcd[j].creator = GRadioCreate;
1513 0 : hvarray[4] = &gcd[j]; hvarray[5] = NULL;
1514 0 : ++j;
1515 :
1516 : /* GT: Cursive Entry. This defines a point on the glyph that should be matched */
1517 : /* GT: with the "Cursive Exit" point of the preceding glyph. */
1518 : /* GT: This is a special way of joining letters which was developed for Urdu */
1519 : /* GT: fonts. Essentially every glyph has an entry point and an exit point. */
1520 : /* GT: When written the glyphs in sequence are aligned so that the exit point */
1521 : /* GT: of each glyph matches the entry point of the following. It means you */
1522 : /* GT: get a join such as might be expected for script. Urdu is odd because */
1523 : /* GT: letters within a word crawl diagonally up the page, but with each word */
1524 : /* GT: the writing point starts at the baseline. */
1525 0 : label[j].text = (unichar_t *) _("CursEntry");
1526 0 : label[j].text_is_1byte = true;
1527 0 : gcd[j].gd.label = &label[j];
1528 0 : gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14;
1529 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1530 0 : gcd[j].gd.cid = CID_CursEntry;
1531 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1532 0 : gcd[j].creator = GRadioCreate;
1533 0 : hvarray[6] = &gcd[j];
1534 0 : ++j;
1535 :
1536 : /* GT: Cursive Exit. This defines a point on the glyph that should be matched */
1537 : /* GT: with the "Cursive Entry" point of the following glyph. This allows */
1538 : /* GT: scripts such as Urdu to work */
1539 0 : label[j].text = (unichar_t *) _("CursExit");
1540 0 : label[j].text_is_1byte = true;
1541 0 : gcd[j].gd.label = &label[j];
1542 0 : gcd[j].gd.pos.x = gcd[j-2].gd.pos.x; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1543 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1544 0 : gcd[j].gd.cid = CID_CursExit;
1545 0 : gcd[j].gd.handle_controlevent = AI_TypeChanged;
1546 0 : gcd[j].creator = GRadioCreate;
1547 0 : hvarray[7] = &gcd[j]; hvarray[8] = NULL; hvarray[9] = NULL;
1548 0 : ++j;
1549 :
1550 0 : boxes[4].gd.flags = gg_enabled|gg_visible;
1551 0 : boxes[4].gd.u.boxelements = hvarray;
1552 0 : boxes[4].creator = GHVBoxCreate;
1553 0 : varray[6] = &boxes[4]; varray[7] = NULL;
1554 :
1555 0 : label[j].text = (unichar_t *) _("Lig Index:");
1556 0 : label[j].text_is_1byte = true;
1557 0 : gcd[j].gd.label = &label[j];
1558 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+26;
1559 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1560 0 : gcd[j].creator = GLabelCreate;
1561 0 : harray3[0] = &gcd[j];
1562 0 : ++j;
1563 :
1564 0 : gcd[j].gd.pos.x = 65; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4;
1565 0 : gcd[j].gd.pos.width = 50;
1566 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1567 0 : gcd[j].gd.cid = CID_LigIndex;
1568 0 : gcd[j].gd.handle_controlevent = AI_LigIndexChanged;
1569 0 : gcd[j].creator = GNumericFieldCreate;
1570 0 : harray3[1] = &gcd[j]; harray3[2] = NULL;
1571 0 : ++j;
1572 :
1573 0 : boxes[5].gd.flags = gg_enabled|gg_visible;
1574 0 : boxes[5].gd.u.boxelements = harray3;
1575 0 : boxes[5].creator = GHBoxCreate;
1576 0 : varray[8] = &boxes[5]; varray[9] = NULL;
1577 :
1578 0 : label[j].text = (unichar_t *) S_("AnchorPoint|_New");
1579 0 : label[j].text_is_1byte = true;
1580 0 : label[j].text_in_resource = true;
1581 0 : gcd[j].gd.label = &label[j];
1582 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+30;
1583 0 : gcd[j].gd.pos.width = -1;
1584 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1585 0 : gcd[j].gd.cid = CID_New;
1586 0 : gcd[j].gd.handle_controlevent = AI_New;
1587 0 : gcd[j].creator = GButtonCreate;
1588 0 : harray4[0] = &gcd[j]; harray4[1] = GCD_Glue;
1589 0 : ++j;
1590 :
1591 0 : label[j].text = (unichar_t *) S_("AnchorClass|New _Class");
1592 0 : label[j].text_is_1byte = true;
1593 0 : label[j].text_in_resource = true;
1594 0 : gcd[j].gd.label = &label[j];
1595 0 : gcd[j].gd.pos.x = 30; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1596 0 : gcd[j].gd.pos.width = -1;
1597 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1598 0 : gcd[j].gd.cid = CID_New;
1599 0 : gcd[j].gd.handle_controlevent = AI_NewClass;
1600 0 : gcd[j].creator = GButtonCreate;
1601 0 : harray4[2] = &gcd[j]; harray4[3] = GCD_Glue;
1602 0 : ++j;
1603 :
1604 0 : label[j].text = (unichar_t *) _("_Delete");
1605 0 : label[j].text_is_1byte = true;
1606 0 : label[j].text_in_resource = true;
1607 0 : gcd[j].gd.label = &label[j];
1608 0 : gcd[j].gd.pos.x = -5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1609 0 : gcd[j].gd.pos.width = -1;
1610 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1611 0 : gcd[j].gd.cid = CID_Delete;
1612 0 : gcd[j].gd.handle_controlevent = AI_Delete;
1613 0 : gcd[j].creator = GButtonCreate;
1614 0 : harray4[4] = &gcd[j]; harray4[5] = NULL;
1615 0 : ++j;
1616 :
1617 0 : boxes[6].gd.flags = gg_enabled|gg_visible;
1618 0 : boxes[6].gd.u.boxelements = harray4;
1619 0 : boxes[6].creator = GHBoxCreate;
1620 0 : varray[10] = &boxes[6]; varray[11] = NULL;
1621 :
1622 0 : label[j].text = (unichar_t *) _("< _Prev");
1623 0 : label[j].text_is_1byte = true;
1624 0 : label[j].text_in_resource = true;
1625 0 : gcd[j].gd.label = &label[j];
1626 0 : gcd[j].gd.pos.x = 15; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
1627 0 : gcd[j].gd.pos.width = -1;
1628 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1629 0 : gcd[j].gd.cid = CID_Prev;
1630 0 : gcd[j].gd.handle_controlevent = AI_Prev;
1631 0 : gcd[j].creator = GButtonCreate;
1632 0 : harray5[0] = GCD_Glue; harray5[1] = &gcd[j]; harray5[2] = GCD_Glue;
1633 0 : ++j;
1634 :
1635 0 : label[j].text = (unichar_t *) _("_Next >");
1636 0 : label[j].text_is_1byte = true;
1637 0 : label[j].text_in_resource = true;
1638 0 : gcd[j].gd.label = &label[j];
1639 0 : gcd[j].gd.pos.x = -15; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
1640 0 : gcd[j].gd.pos.width = -1;
1641 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1642 0 : gcd[j].gd.cid = CID_Next;
1643 0 : gcd[j].gd.handle_controlevent = AI_Next;
1644 0 : gcd[j].creator = GButtonCreate;
1645 0 : harray5[3] = &gcd[j]; harray5[4] = GCD_Glue; harray5[5] = NULL;
1646 0 : ++j;
1647 :
1648 0 : boxes[7].gd.flags = gg_enabled|gg_visible;
1649 0 : boxes[7].gd.u.boxelements = harray5;
1650 0 : boxes[7].creator = GHBoxCreate;
1651 0 : varray[12] = &boxes[7]; varray[13] = NULL;
1652 :
1653 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+26;
1654 0 : gcd[j].gd.pos.width = AI_Width-10;
1655 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
1656 0 : gcd[j].creator = GLineCreate;
1657 0 : varray[14] = GCD_Glue; varray[15] = NULL;
1658 0 : varray[16] = &gcd[j]; varray[17] = NULL;
1659 0 : ++j;
1660 :
1661 0 : label[j].text = (unichar_t *) _("_OK");
1662 0 : label[j].text_is_1byte = true;
1663 0 : label[j].text_in_resource = true;
1664 0 : gcd[j].gd.label = &label[j];
1665 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+4;
1666 0 : gcd[j].gd.pos.width = -1;
1667 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_but_default;
1668 0 : gcd[j].gd.handle_controlevent = AI_Ok;
1669 0 : gcd[j].creator = GButtonCreate;
1670 0 : harray6[0] = &gcd[j]; harray6[1] = GCD_Glue;
1671 0 : ++j;
1672 :
1673 0 : label[j].text = (unichar_t *) _("_Cancel");
1674 0 : label[j].text_is_1byte = true;
1675 0 : label[j].text_in_resource = true;
1676 0 : gcd[j].gd.label = &label[j];
1677 0 : gcd[j].gd.pos.x = -5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+3;
1678 0 : gcd[j].gd.pos.width = -1;
1679 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_but_cancel;
1680 0 : gcd[j].gd.handle_controlevent = AI_Cancel;
1681 0 : gcd[j].creator = GButtonCreate;
1682 0 : harray6[2] = &gcd[j]; harray6[3] = NULL;
1683 0 : ++j;
1684 :
1685 0 : boxes[8].gd.flags = gg_enabled|gg_visible;
1686 0 : boxes[8].gd.u.boxelements = harray6;
1687 0 : boxes[8].creator = GHBoxCreate;
1688 0 : varray[18] = &boxes[8]; varray[19] = NULL;
1689 0 : varray[20] = NULL;
1690 :
1691 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
1692 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
1693 0 : boxes[0].gd.u.boxelements = varray;
1694 0 : boxes[0].creator = GHVGroupCreate;
1695 :
1696 0 : GGadgetsCreate(gi.gw,boxes);
1697 0 : GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
1698 0 : GHVBoxSetExpandableCol(boxes[8].ret,gb_expandgluesame);
1699 0 : GHVBoxSetExpandableCol(boxes[7].ret,gb_expandgluesame);
1700 0 : GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
1701 0 : GHVBoxFitWindow(boxes[0].ret);
1702 :
1703 0 : GGadgetSetList(GWidgetGetControl(gi.gw,CID_NameList),
1704 0 : ti = AnchorClassesLList(gi.sc->parent),false);
1705 0 : for ( j=0; ti[j]->text!=NULL && ti[j]->userdata!=ap->anchor; ++j )
1706 0 : GGadgetSelectOneListItem(GWidgetGetControl(gi.gw,CID_NameList),j);
1707 :
1708 0 : AI_Display(&gi,ap);
1709 0 : GWidgetIndicateFocusGadget(GWidgetGetControl(gi.gw,CID_X));
1710 :
1711 0 : GWidgetHidePalettes();
1712 0 : GDrawSetVisible(gi.gw,true);
1713 0 : while ( !gi.done )
1714 0 : GDrawProcessOneEvent(NULL);
1715 0 : GDrawDestroyWindow(gi.gw);
1716 0 : AnchorPointsFree(gi.oldaps);
1717 : }
1718 :
1719 0 : void PI_ShowHints(SplineChar *sc, GGadget *list, int set) {
1720 : StemInfo *h;
1721 : int32 i, len;
1722 :
1723 0 : if ( !set ) {
1724 0 : for ( h = sc->hstem; h!=NULL; h=h->next )
1725 0 : h->active = false;
1726 0 : for ( h = sc->vstem; h!=NULL; h=h->next )
1727 0 : h->active = false;
1728 : } else {
1729 0 : GTextInfo **ti = GGadgetGetList(list,&len);
1730 0 : for ( h = sc->hstem, i=0; h!=NULL && i<len; h=h->next, ++i )
1731 0 : h->active = ti[i]->selected;
1732 0 : for ( h = sc->vstem; h!=NULL && i<len; h=h->next, ++i )
1733 0 : h->active = ti[i]->selected;
1734 : }
1735 0 : SCOutOfDateBackground(sc);
1736 0 : SCUpdateAll(sc);
1737 0 : }
1738 :
1739 0 : static void _PI_ShowHints(GIData *ci,int set) {
1740 0 : PI_ShowHints(ci->cv->b.sc,GWidgetGetControl(ci->gw,CID_HintMask),set);
1741 0 : }
1742 :
1743 0 : static void PI_DoCancel(GIData *ci) {
1744 0 : CharView *cv = ci->cv;
1745 0 : ci->done = true;
1746 0 : if ( cv->b.drawmode==dm_fore )
1747 0 : MDReplace(cv->b.sc->md,cv->b.sc->layers[ly_fore].splines,ci->oldstate);
1748 0 : SplinePointListsFree(cv->b.layerheads[cv->b.drawmode]->splines);
1749 0 : cv->b.layerheads[cv->b.drawmode]->splines = ci->oldstate;
1750 0 : CVRemoveTopUndo(&cv->b);
1751 0 : SCClearSelPt(cv->b.sc);
1752 0 : _PI_ShowHints(ci,false);
1753 0 : SCUpdateAll(cv->b.sc);
1754 0 : }
1755 :
1756 0 : static int pi_e_h(GWindow gw, GEvent *event) {
1757 0 : if ( event->type==et_close ) {
1758 0 : GIData *d = GDrawGetUserData(gw);
1759 0 : if( d->nonmodal ) {
1760 0 : PI_Destroy((struct dlistnode *)d);
1761 : } else {
1762 0 : PI_DoCancel( GDrawGetUserData(gw));
1763 : }
1764 0 : } else if ( event->type==et_char ) {
1765 0 : if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
1766 0 : help("getinfo.html");
1767 0 : return( true );
1768 : }
1769 0 : return( false );
1770 0 : } else if ( event->type == et_map ) {
1771 : /* Above palettes */
1772 0 : GDrawRaise(gw);
1773 : }
1774 0 : return( true );
1775 : }
1776 :
1777 : static void PIFillup(GIData *ci, int except_cid);
1778 :
1779 0 : static void PI_FigureNext(GIData *ci) {
1780 0 : if ( ci->prevchanged ) {
1781 0 : SplinePoint *cursp = ci->cursp;
1782 0 : if ( !ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 && (cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve)) {
1783 : double dx, dy, len, len2;
1784 0 : dx = cursp->prevcp.x - cursp->me.x;
1785 0 : dy = cursp->prevcp.y - cursp->me.y;
1786 0 : len = sqrt(dx*dx+dy*dy);
1787 0 : if ( len!=0 ) {
1788 0 : len2 = sqrt((cursp->nextcp.x-cursp->me.x)*(cursp->nextcp.x-cursp->me.x)+
1789 0 : (cursp->nextcp.y-cursp->me.y)*(cursp->nextcp.y-cursp->me.y));
1790 0 : cursp->nextcp.x=cursp->me.x-dx*len2/len;
1791 0 : cursp->nextcp.y=cursp->me.y-dy*len2/len;
1792 0 : if ( cursp->next!=NULL )
1793 0 : SplineRefigure(cursp->next);
1794 0 : CVCharChangedUpdate(&ci->cv->b);
1795 0 : PIFillup(ci,-1);
1796 : }
1797 : }
1798 : }
1799 0 : ci->prevchanged = false;
1800 0 : }
1801 :
1802 0 : static void PI_FigurePrev(GIData *ci) {
1803 0 : if ( ci->nextchanged ) {
1804 0 : SplinePoint *cursp = ci->cursp;
1805 0 : if ( !ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 && (cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve)) {
1806 : double dx, dy, len, len2;
1807 0 : dx = cursp->nextcp.x - cursp->me.x;
1808 0 : dy = cursp->nextcp.y - cursp->me.y;
1809 0 : len = sqrt(dx*dx+dy*dy);
1810 0 : if ( len!=0 ) {
1811 0 : len2 = sqrt((cursp->prevcp.x-cursp->me.x)*(cursp->prevcp.x-cursp->me.x)+
1812 0 : (cursp->prevcp.y-cursp->me.y)*(cursp->prevcp.y-cursp->me.y));
1813 0 : cursp->prevcp.x=cursp->me.x-dx*len2/len;
1814 0 : cursp->prevcp.y=cursp->me.y-dy*len2/len;
1815 0 : if ( cursp->prev!=NULL )
1816 0 : SplineRefigure(cursp->prev);
1817 0 : CVCharChangedUpdate(&ci->cv->b);
1818 0 : PIFillup(ci,-1);
1819 : }
1820 : }
1821 : }
1822 0 : ci->nextchanged = false;
1823 0 : }
1824 :
1825 0 : static void PI_FigureHintMask(GIData *ci) {
1826 : int32 i, len;
1827 0 : GTextInfo **ti = GGadgetGetList(GWidgetGetControl(ci->gw,CID_HintMask),&len);
1828 :
1829 0 : for ( i=0; i<len; ++i )
1830 0 : if ( ti[i]->selected )
1831 0 : break;
1832 :
1833 0 : if ( i==len ) {
1834 0 : chunkfree(ci->cursp->hintmask,sizeof(HintMask));
1835 0 : ci->cursp->hintmask = NULL;
1836 : } else {
1837 0 : if ( ci->cursp->hintmask==NULL )
1838 0 : ci->cursp->hintmask = chunkalloc(sizeof(HintMask));
1839 : else
1840 0 : memset(ci->cursp->hintmask,0,sizeof(HintMask));
1841 0 : for ( i=0; i<len; ++i )
1842 0 : if ( ti[i]->selected )
1843 0 : (*ci->cursp->hintmask)[i>>3] |= (0x80>>(i&7));
1844 : }
1845 0 : }
1846 :
1847 0 : static void PI_FixStuff(GIData *ci) {
1848 0 : SplinePoint *sp = ci->cursp;
1849 :
1850 0 : PI_FigureHintMask(ci);
1851 0 : PI_FigureNext(ci);
1852 0 : PI_FigurePrev(ci);
1853 :
1854 0 : if ( sp->pointtype == pt_hvcurve ) {
1855 0 : if (
1856 0 : ((sp->nextcp.x==sp->me.x && sp->prevcp.x==sp->me.x && sp->nextcp.y!=sp->me.y) ||
1857 0 : (sp->nextcp.y==sp->me.y && sp->prevcp.y==sp->me.y && sp->nextcp.x!=sp->me.x)))
1858 : /* Do Nothing */;
1859 : else
1860 0 : sp->pointtype = pt_curve;
1861 0 : } else if ( sp->pointtype == pt_tangent )
1862 0 : SplinePointCategorize(sp); /* Users can change cps so it isn't a tangent, so check */
1863 0 : }
1864 :
1865 0 : void PI_Destroy(struct dlistnode *node) {
1866 0 : GIData *d = (GIData *)node;
1867 0 : GDrawDestroyWindow(d->gw);
1868 0 : dlist_erase(&d->cv->pointInfoDialogs,(struct dlistnode *)d);
1869 0 : free(d);
1870 0 : }
1871 :
1872 0 : static void PI_Close(GGadget *g) {
1873 0 : GWindow gw = GGadgetGetWindow(g);
1874 0 : GIData *d = GDrawGetUserData(gw);
1875 0 : PI_Destroy((struct dlistnode *)d);
1876 0 : }
1877 :
1878 0 : static int PI_Cancel(GGadget *g, GEvent *e) {
1879 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1880 0 : PI_DoCancel( GDrawGetUserData(GGadgetGetWindow(g)));
1881 0 : PI_Close(g);
1882 : }
1883 0 : return( true );
1884 : }
1885 :
1886 0 : static int PI_Ok(GGadget *g, GEvent *e) {
1887 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
1888 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
1889 :
1890 0 : PI_FixStuff(ci);
1891 0 : _PI_ShowHints(ci,false);
1892 :
1893 0 : ci->done = true;
1894 : /* All the work has been done as we've gone along */
1895 0 : PI_Close(g);
1896 : }
1897 :
1898 0 : return( true );
1899 : }
1900 :
1901 0 : static void mysprintf( char *buffer, char *format, real v) {
1902 : char *pt;
1903 :
1904 0 : if ( v<.0001 && v>-.0001 && v!=0 )
1905 0 : sprintf( buffer, "%e", (double) v );
1906 0 : else if ( v<1 && v>0 )
1907 0 : sprintf( buffer, "%f", (double) v );
1908 0 : else if ( v<0 && v>-1 )
1909 0 : sprintf( buffer, "%.5f", (double) v );
1910 : else
1911 0 : sprintf( buffer, format, (double) v );
1912 0 : pt = buffer + strlen(buffer);
1913 0 : while ( pt>buffer && pt[-1]=='0' )
1914 0 : *--pt = '\0';
1915 0 : if ( pt>buffer && pt[-1]=='.' )
1916 0 : pt[-1] = '\0';
1917 0 : }
1918 :
1919 0 : static void mysprintf2( char *buffer, real v1, real v2) {
1920 : char *pt;
1921 :
1922 0 : mysprintf(buffer,"%.2f", v1);
1923 0 : pt = buffer+strlen(buffer);
1924 0 : *pt++ = ',';
1925 0 : mysprintf(pt,"%.2f", v2);
1926 0 : }
1927 :
1928 0 : static void PIFillup(GIData *ci, int except_cid) {
1929 : char buffer[51];
1930 : double dx, dy;
1931 : double kappa, kappa2;
1932 : int emsize;
1933 :
1934 0 : mysprintf(buffer, "%.2f", ci->cursp->me.x );
1935 0 : if ( except_cid!=CID_BaseX )
1936 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseX),buffer);
1937 :
1938 0 : mysprintf(buffer, "%.2f", ci->cursp->me.y );
1939 0 : if ( except_cid!=CID_BaseY )
1940 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseY),buffer);
1941 :
1942 0 : dx = ci->cursp->nextcp.x-ci->cursp->me.x;
1943 0 : dy = ci->cursp->nextcp.y-ci->cursp->me.y;
1944 0 : mysprintf(buffer, "%.2f", dx );
1945 0 : if ( except_cid!=CID_NextXOff )
1946 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextXOff),buffer);
1947 :
1948 0 : mysprintf(buffer, "%.2f", dy );
1949 0 : if ( except_cid!=CID_NextYOff )
1950 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextYOff),buffer);
1951 :
1952 0 : if ( except_cid!=CID_NextR ) {
1953 0 : mysprintf(buffer, "%.2f", sqrt( dx*dx+dy*dy ));
1954 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextR),buffer);
1955 : }
1956 :
1957 0 : if ( except_cid!=CID_NextTheta ) {
1958 0 : if ( ci->cursp->pointtype==pt_tangent && ci->cursp->prev!=NULL ) {
1959 0 : dx = ci->cursp->me.x-ci->cursp->prev->from->me.x;
1960 0 : dy = ci->cursp->me.y-ci->cursp->prev->from->me.y;
1961 : }
1962 0 : mysprintf(buffer, "%.1f", atan2(dy,dx)*RAD2DEG);
1963 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextTheta),buffer);
1964 : }
1965 :
1966 0 : mysprintf2(buffer, ci->cursp->nextcp.x,ci->cursp->nextcp.y );
1967 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextPos),buffer);
1968 :
1969 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NextDef), ci->cursp->nextcpdef );
1970 :
1971 0 : dx = ci->cursp->prevcp.x-ci->cursp->me.x;
1972 0 : dy = ci->cursp->prevcp.y-ci->cursp->me.y;
1973 0 : mysprintf(buffer, "%.2f", dx );
1974 0 : if ( except_cid!=CID_PrevXOff )
1975 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevXOff),buffer);
1976 :
1977 0 : mysprintf(buffer, "%.2f", dy );
1978 0 : if ( except_cid!=CID_PrevYOff )
1979 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevYOff),buffer);
1980 :
1981 0 : if ( except_cid!=CID_PrevR ) {
1982 0 : mysprintf(buffer, "%.2f", sqrt( dx*dx+dy*dy ));
1983 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevR),buffer);
1984 : }
1985 :
1986 0 : if ( except_cid!=CID_PrevTheta ) {
1987 0 : if ( ci->cursp->pointtype==pt_tangent && ci->cursp->next!=NULL ) {
1988 0 : dx = ci->cursp->me.x-ci->cursp->next->to->me.x;
1989 0 : dy = ci->cursp->me.y-ci->cursp->next->to->me.y;
1990 : }
1991 0 : mysprintf(buffer, "%.1f", atan2(dy,dx)*RAD2DEG);
1992 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevTheta),buffer);
1993 : }
1994 :
1995 0 : mysprintf2(buffer, ci->cursp->prevcp.x,ci->cursp->prevcp.y );
1996 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevPos),buffer);
1997 :
1998 :
1999 0 : mysprintf2(buffer, ci->cursp->me.x,ci->cursp->me.y );
2000 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BasePos),buffer);
2001 :
2002 0 : mysprintf(buffer, "%.2f", ci->cursp->nextcp.x );
2003 0 : if ( except_cid!=CID_NextX )
2004 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextX),buffer);
2005 :
2006 0 : mysprintf(buffer, "%.2f", ci->cursp->nextcp.y );
2007 0 : if ( except_cid!=CID_NextY )
2008 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextY),buffer);
2009 :
2010 0 : mysprintf(buffer, "%.2f", ci->cursp->prevcp.x );
2011 0 : if ( except_cid!=CID_PrevX )
2012 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevX),buffer);
2013 :
2014 0 : mysprintf(buffer, "%.2f", ci->cursp->prevcp.y );
2015 0 : if ( except_cid!=CID_PrevY )
2016 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevY),buffer);
2017 :
2018 :
2019 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_PrevDef), ci->cursp->prevcpdef );
2020 :
2021 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve), ci->cursp->pointtype==pt_curve );
2022 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_HVCurve), ci->cursp->pointtype==pt_hvcurve );
2023 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Corner), ci->cursp->pointtype==pt_corner );
2024 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Tangent), ci->cursp->pointtype==pt_tangent );
2025 :
2026 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevTheta), ci->cursp->pointtype!=pt_tangent );
2027 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextTheta), ci->cursp->pointtype!=pt_tangent );
2028 :
2029 0 : kappa = SplineCurvature(ci->cursp->next,0);
2030 0 : kappa2 = SplineCurvature(ci->cursp->prev,1);
2031 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevCurvature), kappa2!=CURVATURE_ERROR );
2032 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextCurvature), kappa!=CURVATURE_ERROR );
2033 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_DeltaCurvature),
2034 : kappa!=CURVATURE_ERROR && kappa2!=CURVATURE_ERROR );
2035 0 : emsize = ci->cv->b.sc->parent->ascent + ci->cv->b.sc->parent->descent;
2036 : /* If we normalize by the em-size, the curvature is often more */
2037 : /* readable */
2038 0 : if ( kappa!=CURVATURE_ERROR )
2039 0 : sprintf( buffer, _("Curvature: %g"), kappa*emsize );
2040 : else
2041 0 : strcpy( buffer, _("Curvature: ?"));
2042 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_NextCurvature),buffer);
2043 0 : if ( kappa2!=CURVATURE_ERROR )
2044 0 : sprintf( buffer, _("Curvature: %g"), kappa2*emsize );
2045 : else
2046 0 : strncpy( buffer, _("Curvature: ?"),sizeof(buffer)-1 );
2047 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_PrevCurvature),buffer);
2048 0 : if ( kappa!=CURVATURE_ERROR && kappa2!=CURVATURE_ERROR )
2049 0 : sprintf( buffer, "∆: %g", (kappa-kappa2)*emsize );
2050 : else
2051 0 : strcpy( buffer, "∆: ?");
2052 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_DeltaCurvature),buffer);
2053 0 : }
2054 :
2055 0 : static void PIShowHide(GIData *ci) {
2056 0 : int normal = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Normal));
2057 : int i;
2058 :
2059 0 : for ( i=ci->normal_start; i<ci->normal_end; ++i )
2060 0 : if ( ci->gcd[i].ret!=NULL )
2061 0 : GGadgetSetVisible(ci->gcd[i].ret,normal);
2062 0 : GGadgetSetVisible(ci->group1ret,normal);
2063 0 : GGadgetSetVisible(ci->group2ret,normal);
2064 0 : for ( i=ci->interp_start; i<ci->interp_end; ++i )
2065 0 : if ( ci->gcd[i].ret!=NULL )
2066 0 : GGadgetSetVisible(ci->gcd[i].ret,!normal);
2067 0 : GWidgetFlowGadgets(GGadgetGetWindow(GWidgetGetControl(ci->gw,CID_Normal)));
2068 0 : }
2069 :
2070 0 : void PIChangePoint(GIData *ci) {
2071 0 : int aspect = GTabSetGetSel(GWidgetGetControl(ci->gw,CID_TabSet));
2072 0 : GGadget *list = GWidgetGetControl(ci->gw,CID_HintMask);
2073 : int32 i, len;
2074 : HintMask *hm;
2075 : SplinePoint *sp;
2076 : SplineSet *spl;
2077 : int interpolate;
2078 :
2079 0 : GGadgetGetList(list,&len);
2080 :
2081 0 : PIFillup(ci,0);
2082 :
2083 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Interpolated),
2084 0 : !ci->cursp->dontinterpolate && !(ci->cursp->nonextcp && ci->cursp->noprevcp) );
2085 0 : interpolate = SPInterpolate(ci->cursp) && ci->cv->b.layerheads[ci->cv->b.drawmode]->order2;
2086 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Normal), !interpolate );
2087 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Interpolated), interpolate );
2088 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NeverInterpolate), ci->cursp->dontinterpolate );
2089 0 : PIShowHide(ci);
2090 :
2091 0 : if ( ci->cursp->hintmask==NULL ) {
2092 0 : for ( i=0; i<len; ++i )
2093 0 : GGadgetSelectListItem(list,i,false);
2094 : } else {
2095 0 : for ( i=0; i<len && i<HntMax; ++i )
2096 0 : GGadgetSelectListItem(list,i, (*ci->cursp->hintmask)[i>>3]&(0x80>>(i&7))?true:false );
2097 : }
2098 0 : _PI_ShowHints(ci,aspect==1);
2099 :
2100 0 : list = GWidgetGetControl(ci->gw,CID_ActiveHints);
2101 0 : hm = NULL;
2102 : /* Figure out what hintmask is active at the current point */
2103 : /* Note: we must walk each ss backwards because we reverse the splineset */
2104 : /* when we output postscript */
2105 0 : for ( spl = ci->sc->layers[ly_fore].splines; spl!=NULL; spl=spl->next ) {
2106 0 : for ( sp=spl->first; ; ) {
2107 0 : if ( sp->hintmask )
2108 0 : hm = sp->hintmask;
2109 0 : if ( sp==ci->cursp )
2110 0 : break;
2111 0 : if ( sp->prev==NULL )
2112 0 : break;
2113 0 : sp = sp->prev->from;
2114 0 : if ( sp==spl->first )
2115 0 : break;
2116 0 : }
2117 0 : if ( sp==ci->cursp )
2118 0 : break;
2119 : }
2120 0 : if ( hm==NULL ) {
2121 0 : for ( i=0; i<len; ++i )
2122 0 : GGadgetSelectListItem(list,i,false);
2123 : } else {
2124 0 : for ( i=0; i<len && i<HntMax; ++i )
2125 0 : GGadgetSelectListItem(list,i, (*hm)[i>>3]&(0x80>>(i&7))?true:false );
2126 : }
2127 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_NextDef),ci->cursp->next!=NULL);
2128 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_PrevDef),ci->cursp->prev!=NULL);
2129 0 : }
2130 :
2131 0 : static int PI_NextPrev(GGadget *g, GEvent *e) {
2132 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2133 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2134 0 : CharView *cv = ci->cv;
2135 0 : int cid = GGadgetGetCid(g);
2136 : SplinePointList *spl;
2137 :
2138 0 : PI_FixStuff(ci);
2139 :
2140 0 : ci->cursp->selected = false;
2141 0 : if ( cid == CID_Next ) {
2142 0 : if ( ci->cursp->next!=NULL && ci->cursp->next->to!=ci->curspl->first )
2143 0 : ci->cursp = ci->cursp->next->to;
2144 : else {
2145 0 : if ( ci->curspl->next == NULL ) {
2146 0 : ci->curspl = cv->b.layerheads[cv->b.drawmode]->splines;
2147 0 : GDrawBeep(NULL);
2148 : } else
2149 0 : ci->curspl = ci->curspl->next;
2150 0 : ci->cursp = ci->curspl->first;
2151 : }
2152 0 : } else if ( cid == CID_Prev ) {
2153 0 : if ( ci->cursp!=ci->curspl->first ) {
2154 0 : ci->cursp = ci->cursp->prev->from;
2155 : } else {
2156 0 : if ( ci->curspl==cv->b.layerheads[cv->b.drawmode]->splines ) {
2157 0 : for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=NULL; spl=spl->next );
2158 0 : GDrawBeep(NULL);
2159 : } else {
2160 0 : for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=ci->curspl; spl=spl->next );
2161 : }
2162 0 : ci->curspl = spl;
2163 0 : ci->cursp = spl->last;
2164 0 : if ( spl->last==spl->first && spl->last->prev!=NULL )
2165 0 : ci->cursp = ci->cursp->prev->from;
2166 : }
2167 0 : } else if ( cid==CID_NextC ) {
2168 0 : if ( ci->cursp->next!=NULL )
2169 0 : ci->cursp = ci->cursp->next->to;
2170 : else {
2171 0 : ci->cursp = ci->curspl->first;
2172 0 : GDrawBeep(NULL);
2173 : }
2174 : } else /* CID_PrevC */ {
2175 0 : if ( ci->cursp->prev!=NULL )
2176 0 : ci->cursp = ci->cursp->prev->from;
2177 : else {
2178 0 : ci->cursp = ci->curspl->last;
2179 0 : GDrawBeep(NULL);
2180 : }
2181 : }
2182 0 : ci->cursp->selected = true;
2183 0 : PIChangePoint(ci);
2184 0 : CVShowPoint(cv,&ci->cursp->me);
2185 0 : SCUpdateAll(cv->b.sc);
2186 : }
2187 0 : return( true );
2188 : }
2189 :
2190 0 : static int PI_InterpChanged(GGadget *g, GEvent *e) {
2191 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2192 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2193 0 : SplinePoint *cursp = ci->cursp;
2194 :
2195 0 : if ( GGadgetGetCid(g)==CID_Interpolated ) {
2196 0 : if ( cursp->nonextcp && cursp->noprevcp )
2197 : /* Do Nothing */;
2198 : else {
2199 0 : if ( cursp->nonextcp && cursp->next ) {
2200 0 : SplinePoint *n = cursp->next->to;
2201 0 : cursp->nextcp.x = rint((n->me.x+cursp->me.x)/2);
2202 0 : cursp->nextcp.y = rint((n->me.y+cursp->me.y)/2);
2203 0 : n->prevcp = cursp->nextcp;
2204 0 : cursp->nonextcp = n->noprevcp = false;
2205 : }
2206 0 : if ( cursp->noprevcp && cursp->prev ) {
2207 0 : SplinePoint *p = cursp->prev->from;
2208 0 : cursp->prevcp.x = rint((p->me.x+cursp->me.x)/2);
2209 0 : cursp->prevcp.y = rint((p->me.y+cursp->me.y)/2);
2210 0 : p->nextcp = cursp->prevcp;
2211 0 : cursp->noprevcp = p->nonextcp = false;
2212 : }
2213 0 : cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
2214 0 : cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
2215 0 : if ( cursp->pointtype==pt_tangent ) {
2216 0 : cursp->pointtype = pt_curve;
2217 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve),true);
2218 : }
2219 0 : if ( cursp->next!=NULL )
2220 0 : SplineRefigure(cursp->next);
2221 0 : if ( cursp->prev!=NULL )
2222 0 : SplineRefigure(cursp->prev);
2223 0 : SplineSetSpirosClear(ci->curspl);
2224 0 : CVCharChangedUpdate(&ci->cv->b);
2225 : }
2226 0 : PIFillup(ci,0);
2227 : }
2228 0 : PIShowHide(ci);
2229 : }
2230 0 : return( true );
2231 : }
2232 :
2233 0 : static int PI_NeverInterpChanged(GGadget *g, GEvent *e) {
2234 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2235 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2236 0 : int never = GGadgetIsChecked(g);
2237 :
2238 0 : GGadgetSetEnabled(GWidgetGetControl(ci->gw,CID_Interpolated),!never);
2239 :
2240 0 : if ( never )
2241 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Normal),true);
2242 0 : ci->cursp->dontinterpolate = never;
2243 0 : PIShowHide(ci);
2244 : }
2245 0 : return( true );
2246 : }
2247 :
2248 0 : static int PI_BaseChanged(GGadget *g, GEvent *e) {
2249 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2250 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2251 0 : real dx=0, dy=0;
2252 0 : int err=false;
2253 0 : SplinePoint *cursp = ci->cursp;
2254 :
2255 0 : if ( GGadgetGetCid(g)==CID_BaseX )
2256 0 : dx = GetCalmReal8(ci->gw,CID_BaseX,_("Base X"),&err)-cursp->me.x;
2257 : else
2258 0 : dy = GetCalmReal8(ci->gw,CID_BaseY,_("Base Y"),&err)-cursp->me.y;
2259 0 : if ( (dx==0 && dy==0) || err )
2260 0 : return( true );
2261 0 : cursp->me.x += dx;
2262 0 : cursp->nextcp.x += dx;
2263 0 : cursp->prevcp.x += dx;
2264 0 : cursp->me.y += dy;
2265 0 : cursp->nextcp.y += dy;
2266 0 : cursp->prevcp.y += dy;
2267 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 ) {
2268 0 : SplinePointNextCPChanged2(cursp);
2269 0 : SplinePointPrevCPChanged2(cursp);
2270 : }
2271 0 : if ( cursp->next!=NULL )
2272 0 : SplineRefigure(cursp->next);
2273 0 : if ( cursp->prev!=NULL )
2274 0 : SplineRefigure(cursp->prev);
2275 0 : SplineSetSpirosClear(ci->curspl);
2276 0 : CVCharChangedUpdate(&ci->cv->b);
2277 0 : PIFillup(ci,GGadgetGetCid(g));
2278 0 : } else if ( e->type==et_controlevent &&
2279 0 : e->u.control.subtype == et_textfocuschanged &&
2280 0 : e->u.control.u.tf_focus.gained_focus ) {
2281 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2282 0 : PI_FigureNext(ci);
2283 0 : PI_FigurePrev(ci);
2284 : }
2285 0 : return( true );
2286 : }
2287 :
2288 0 : static int PI_NextChanged(GGadget *g, GEvent *e) {
2289 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2290 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2291 0 : real dx=0, dy=0;
2292 0 : int err=false;
2293 0 : SplinePoint *cursp = ci->cursp;
2294 :
2295 0 : if ( GGadgetGetCid(g)==CID_NextXOff ) {
2296 0 : dx = GetCalmReal8(ci->gw,CID_NextXOff,_("Next CP X"),&err)-(cursp->nextcp.x-cursp->me.x);
2297 0 : if ( cursp->pointtype==pt_tangent && cursp->prev!=NULL ) {
2298 0 : if ( cursp->prev->from->me.x==cursp->me.x ) {
2299 0 : dy = dx; dx = 0; /* They should be constrained not to change in the x direction */
2300 : } else
2301 0 : dy = dx*(cursp->prev->from->me.y-cursp->me.y)/(cursp->prev->from->me.x-cursp->me.x);
2302 : }
2303 0 : } else if ( GGadgetGetCid(g)==CID_NextYOff ) {
2304 0 : dy = GetCalmReal8(ci->gw,CID_NextYOff,_("Next CP Y"),&err)-(cursp->nextcp.y-cursp->me.y);
2305 0 : if ( cursp->pointtype==pt_tangent && cursp->prev!=NULL ) {
2306 0 : if ( cursp->prev->from->me.y==cursp->me.y ) {
2307 0 : dx = dy; dy = 0; /* They should be constrained not to change in the y direction */
2308 : } else
2309 0 : dx = dy*(cursp->prev->from->me.x-cursp->me.x)/(cursp->prev->from->me.y-cursp->me.y);
2310 : }
2311 : } else {
2312 : double len, theta;
2313 0 : len = GetCalmReal8(ci->gw,CID_NextR,_("Next CP Dist"),&err);
2314 0 : theta = GetCalmReal8(ci->gw,CID_NextTheta,_("Next CP Angle"),&err)/RAD2DEG;
2315 0 : dx = len*cos(theta) - (cursp->nextcp.x-cursp->me.x);
2316 0 : dy = len*sin(theta) - (cursp->nextcp.y-cursp->me.y);
2317 : }
2318 0 : if ( (dx==0 && dy==0) || err )
2319 0 : return( true );
2320 0 : if ( cursp->pointtype==pt_hvcurve ) {
2321 : BasePoint diff;
2322 0 : diff.x = cursp->nextcp.x+dx - cursp->me.x;
2323 0 : diff.y = cursp->nextcp.y+dy - cursp->me.y;
2324 0 : BP_HVForce(&diff);
2325 0 : dx = diff.x + (cursp->me.x - cursp->nextcp.x);
2326 0 : dy = diff.y + (cursp->me.y - cursp->nextcp.y);
2327 : }
2328 0 : cursp->nextcp.x += dx;
2329 0 : cursp->nextcp.y += dy;
2330 0 : cursp->nonextcp = false;
2331 0 : SplineSetSpirosClear(ci->curspl);
2332 0 : ci->nextchanged = true;
2333 0 : if (( dx>.1 || dx<-.1 || dy>.1 || dy<-.1 ) && cursp->nextcpdef ) {
2334 0 : cursp->nextcpdef = false;
2335 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_NextDef), false );
2336 : }
2337 0 : if (( cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve) && cursp->prev!=NULL ) {
2338 : double plen, ntheta;
2339 : double ndx, ndy;
2340 0 : ndx = ci->cursp->nextcp.x-ci->cursp->me.x;
2341 0 : ndy = ci->cursp->nextcp.y-ci->cursp->me.y;
2342 0 : ntheta = atan2(ndy,ndx);
2343 0 : plen = GetCalmReal8(ci->gw,CID_PrevR,_("Prev CP Dist"),&err);
2344 0 : ci->cursp->prevcp.x = ci->cursp->me.x - plen*cos(ntheta);
2345 0 : ci->cursp->prevcp.y = ci->cursp->me.y - plen*sin(ntheta);
2346 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2347 0 : SplinePointPrevCPChanged2(cursp);
2348 0 : SplineRefigure(cursp->prev);
2349 : }
2350 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2351 0 : SplinePointNextCPChanged2(cursp);
2352 0 : if ( cursp->next!=NULL )
2353 0 : SplineRefigure(cursp->next);
2354 0 : CVCharChangedUpdate(&ci->cv->b);
2355 0 : PIFillup(ci,GGadgetGetCid(g));
2356 0 : } else if ( e->type==et_controlevent &&
2357 0 : e->u.control.subtype == et_textfocuschanged &&
2358 0 : e->u.control.u.tf_focus.gained_focus ) {
2359 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2360 0 : PI_FigureNext(ci);
2361 : }
2362 0 : return( true );
2363 : }
2364 :
2365 0 : static int PI_PrevChanged(GGadget *g, GEvent *e) {
2366 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2367 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2368 0 : real dx=0, dy=0;
2369 0 : int err=false;
2370 0 : SplinePoint *cursp = ci->cursp;
2371 :
2372 0 : if ( GGadgetGetCid(g)==CID_PrevXOff ) {
2373 0 : dx = GetCalmReal8(ci->gw,CID_PrevXOff,_("Prev CP X"),&err)-(cursp->prevcp.x-cursp->me.x);
2374 0 : if ( cursp->pointtype==pt_tangent && cursp->next!=NULL ) {
2375 0 : if ( cursp->next->to->me.x==cursp->me.x ) {
2376 0 : dy = dx; dx = 0; /* They should be constrained not to change in the x direction */
2377 : } else
2378 0 : dy = dx*(cursp->next->to->me.y-cursp->me.y)/(cursp->next->to->me.x-cursp->me.x);
2379 : }
2380 0 : } else if ( GGadgetGetCid(g)==CID_PrevYOff ) {
2381 0 : dy = GetCalmReal8(ci->gw,CID_PrevYOff,_("Prev CP Y"),&err)-(cursp->prevcp.y-cursp->me.y);
2382 0 : if ( cursp->pointtype==pt_tangent && cursp->next!=NULL ) {
2383 0 : if ( cursp->next->to->me.y==cursp->me.y ) {
2384 0 : dx = dy; dy = 0; /* They should be constrained not to change in the y direction */
2385 : } else
2386 0 : dx = dy*(cursp->next->to->me.x-cursp->me.x)/(cursp->next->to->me.y-cursp->me.y);
2387 : }
2388 : } else {
2389 : double len, theta;
2390 0 : len = GetCalmReal8(ci->gw,CID_PrevR,_("Prev CP Dist"),&err);
2391 0 : theta = GetCalmReal8(ci->gw,CID_PrevTheta,_("Prev CP Angle"),&err)/RAD2DEG;
2392 0 : dx = len*cos(theta) - (cursp->prevcp.x-cursp->me.x);
2393 0 : dy = len*sin(theta) - (cursp->prevcp.y-cursp->me.y);
2394 : }
2395 0 : if ( (dx==0 && dy==0) || err )
2396 0 : return( true );
2397 0 : if ( cursp->pointtype==pt_hvcurve ) {
2398 : BasePoint diff;
2399 0 : diff.x = cursp->prevcp.x+dx - cursp->me.x;
2400 0 : diff.y = cursp->prevcp.y+dy - cursp->me.y;
2401 0 : BP_HVForce(&diff);
2402 0 : dx = diff.x - (cursp->prevcp.x - cursp->me.x);
2403 0 : dy = diff.y - (cursp->prevcp.y - cursp->me.y);
2404 : }
2405 0 : cursp->prevcp.x += dx;
2406 0 : cursp->prevcp.y += dy;
2407 0 : cursp->noprevcp = false;
2408 0 : ci->prevchanged = true;
2409 0 : SplineSetSpirosClear(ci->curspl);
2410 0 : if (( dx>.1 || dx<-.1 || dy>.1 || dy<-.1 ) && cursp->prevcpdef ) {
2411 0 : cursp->prevcpdef = false;
2412 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_PrevDef), false );
2413 : }
2414 0 : if (( cursp->pointtype==pt_curve || cursp->pointtype==pt_hvcurve) && cursp->next!=NULL ) {
2415 : double nlen, ptheta;
2416 : double pdx, pdy;
2417 0 : pdx = ci->cursp->prevcp.x-ci->cursp->me.x;
2418 0 : pdy = ci->cursp->prevcp.y-ci->cursp->me.y;
2419 0 : ptheta = atan2(pdy,pdx);
2420 0 : nlen = GetCalmReal8(ci->gw,CID_NextR,_("Next CP Dist"),&err);
2421 0 : ci->cursp->nextcp.x = ci->cursp->me.x - nlen*cos(ptheta);
2422 0 : ci->cursp->nextcp.y = ci->cursp->me.y - nlen*sin(ptheta);
2423 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2424 0 : SplinePointNextCPChanged2(cursp);
2425 0 : SplineRefigure(cursp->next);
2426 : }
2427 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2428 0 : SplinePointPrevCPChanged2(cursp);
2429 0 : if ( cursp->prev!=NULL )
2430 0 : SplineRefigure(cursp->prev);
2431 0 : CVCharChangedUpdate(&ci->cv->b);
2432 0 : PIFillup(ci,GGadgetGetCid(g));
2433 0 : } else if ( e->type==et_controlevent &&
2434 0 : e->u.control.subtype == et_textfocuschanged &&
2435 0 : e->u.control.u.tf_focus.gained_focus ) {
2436 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2437 0 : PI_FigurePrev(ci);
2438 : }
2439 0 : return( true );
2440 : }
2441 :
2442 0 : static int PI_NextIntChanged(GGadget *g, GEvent *e) {
2443 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2444 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2445 0 : real x=0, y=0;
2446 0 : int err=false;
2447 0 : SplinePoint *cursp = ci->cursp;
2448 :
2449 0 : x = GetCalmReal8(ci->gw,CID_NextX,_("Next CP X"),&err);
2450 0 : y = GetCalmReal8(ci->gw,CID_NextY,_("Next CP Y"),&err);
2451 0 : if ( err || (x==cursp->nextcp.x && y==cursp->nextcp.y) )
2452 0 : return( true );
2453 0 : cursp->nextcp.x = x;
2454 0 : cursp->nextcp.y = y;
2455 0 : cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
2456 0 : cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
2457 0 : SplineSetSpirosClear(ci->curspl);
2458 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2459 0 : SplinePointNextCPChanged2(cursp);
2460 0 : if ( cursp->next!=NULL )
2461 0 : SplineRefigure(cursp->next);
2462 0 : CVCharChangedUpdate(&ci->cv->b);
2463 0 : PIFillup(ci,GGadgetGetCid(g));
2464 0 : } else if ( e->type==et_controlevent &&
2465 0 : e->u.control.subtype == et_textfocuschanged &&
2466 0 : e->u.control.u.tf_focus.gained_focus ) {
2467 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2468 0 : PI_FigureNext(ci);
2469 : }
2470 0 : return( true );
2471 : }
2472 :
2473 0 : static int PI_PrevIntChanged(GGadget *g, GEvent *e) {
2474 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2475 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2476 0 : real x=0, y=0;
2477 0 : int err=false;
2478 0 : SplinePoint *cursp = ci->cursp;
2479 :
2480 0 : x = GetCalmReal8(ci->gw,CID_PrevX,_("Prev CP X"),&err);
2481 0 : y = GetCalmReal8(ci->gw,CID_PrevY,_("Prev CP Y"),&err);
2482 0 : if ( err || (x==cursp->prevcp.x && y==cursp->prevcp.y) )
2483 0 : return( true );
2484 0 : cursp->prevcp.x = x;
2485 0 : cursp->prevcp.y = y;
2486 0 : cursp->me.x = (cursp->nextcp.x + cursp->prevcp.x)/2;
2487 0 : cursp->me.y = (cursp->nextcp.y + cursp->prevcp.y)/2;
2488 0 : SplineSetSpirosClear(ci->curspl);
2489 0 : if ( ci->cv->b.layerheads[ci->cv->b.drawmode]->order2 )
2490 0 : SplinePointPrevCPChanged2(cursp);
2491 0 : if ( cursp->prev!=NULL )
2492 0 : SplineRefigure(cursp->prev);
2493 0 : CVCharChangedUpdate(&ci->cv->b);
2494 0 : PIFillup(ci,GGadgetGetCid(g));
2495 0 : } else if ( e->type==et_controlevent &&
2496 0 : e->u.control.subtype == et_textfocuschanged &&
2497 0 : e->u.control.u.tf_focus.gained_focus ) {
2498 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2499 0 : PI_FigureNext(ci);
2500 : }
2501 0 : return( true );
2502 : }
2503 :
2504 0 : static int PI_NextDefChanged(GGadget *g, GEvent *e) {
2505 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2506 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2507 0 : SplinePoint *cursp = ci->cursp;
2508 :
2509 0 : cursp->nextcpdef = GGadgetIsChecked(g);
2510 : /* If they turned def off, that's a noop, but if they turned it on... */
2511 : /* then set things to the default */
2512 0 : if ( cursp->nextcpdef ) {
2513 0 : BasePoint temp = cursp->prevcp;
2514 0 : SplineCharDefaultNextCP(cursp);
2515 0 : if ( !cursp->prevcpdef ) {
2516 0 : cursp->prevcp = temp;
2517 0 : SplineSetSpirosClear(ci->curspl);
2518 : }
2519 0 : CVCharChangedUpdate(&ci->cv->b);
2520 0 : PIFillup(ci,GGadgetGetCid(g));
2521 : }
2522 : }
2523 0 : return( true );
2524 : }
2525 :
2526 0 : static int PI_PrevDefChanged(GGadget *g, GEvent *e) {
2527 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2528 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2529 0 : SplinePoint *cursp = ci->cursp;
2530 :
2531 0 : cursp->prevcpdef = GGadgetIsChecked(g);
2532 : /* If they turned def off, that's a noop, but if they turned it on... */
2533 : /* then set things to the default */
2534 0 : if ( cursp->prevcpdef ) {
2535 0 : BasePoint temp = cursp->nextcp;
2536 0 : SplineCharDefaultPrevCP(cursp);
2537 0 : if ( !cursp->nextcpdef ) {
2538 0 : cursp->nextcp = temp;
2539 0 : SplineSetSpirosClear(ci->curspl);
2540 : }
2541 0 : CVCharChangedUpdate(&ci->cv->b);
2542 0 : PIFillup(ci,GGadgetGetCid(g));
2543 : }
2544 : }
2545 0 : return( true );
2546 : }
2547 :
2548 0 : static int PI_PTypeChanged(GGadget *g, GEvent *e) {
2549 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2550 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2551 0 : SplinePoint *cursp = ci->cursp;
2552 0 : enum pointtype pt = GGadgetGetCid(g)-CID_Curve + pt_curve;
2553 :
2554 0 : if ( pt==cursp->pointtype ) {
2555 : /* Can't happen */
2556 0 : } else if ( pt==pt_corner ) {
2557 0 : cursp->pointtype = pt_corner;
2558 0 : CVCharChangedUpdate(&ci->cv->b);
2559 : } else {
2560 0 : SPChangePointType(cursp,pt);
2561 0 : SplineSetSpirosClear(ci->curspl);
2562 0 : CVCharChangedUpdate(&ci->cv->b);
2563 0 : PIFillup(ci,GGadgetGetCid(g));
2564 : }
2565 : }
2566 0 : return( true );
2567 : }
2568 :
2569 0 : static int PI_AspectChange(GGadget *g, GEvent *e) {
2570 0 : if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_radiochanged )) {
2571 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2572 0 : int aspect = GTabSetGetSel(g);
2573 :
2574 0 : _PI_ShowHints(ci,aspect==1);
2575 : }
2576 0 : return( true );
2577 : }
2578 :
2579 0 : static int PI_HintSel(GGadget *g, GEvent *e) {
2580 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
2581 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
2582 :
2583 0 : _PI_ShowHints(ci,true);
2584 :
2585 0 : if ( GGadgetIsListItemSelected(g,e->u.control.u.list.changed_index)) {
2586 : /* If we just selected something, check to make sure it doesn't */
2587 : /* conflict with any other hints. */
2588 : /* Adobe says this is an error, but in "three" in AdobeSansMM */
2589 : /* (in black,extended) we have a hintmask which contains two */
2590 : /* overlapping hints */
2591 : /* So just make it a warning */
2592 : int i,j;
2593 0 : StemInfo *h, *h2=NULL;
2594 0 : for ( i=0, h=ci->cv->b.sc->hstem; h!=NULL && i!=e->u.control.u.list.changed_index; h=h->next, ++i );
2595 0 : if ( h!=NULL ) {
2596 0 : for ( h2 = ci->cv->b.sc->hstem, i=0 ; h2!=NULL; h2=h2->next, ++i ) {
2597 0 : if ( h2!=h && GGadgetIsListItemSelected(g,i)) {
2598 0 : if (( h2->start<h->start && h2->start+h2->width>h->start ) ||
2599 0 : ( h2->start>=h->start && h->start+h->width>h2->start ))
2600 : break;
2601 : }
2602 : }
2603 : } else {
2604 0 : j = i;
2605 0 : for ( h=ci->cv->b.sc->vstem; h!=NULL && i!=e->u.control.u.list.changed_index; h=h->next, ++i );
2606 0 : if ( h==NULL )
2607 0 : IError("Failed to find hint");
2608 : else {
2609 0 : for ( h2 = ci->cv->b.sc->vstem, i=j ; h2!=NULL; h2=h2->next, ++i ) {
2610 0 : if ( h2!=h && GGadgetIsListItemSelected(g,i)) {
2611 0 : if (( h2->start<h->start && h2->start+h2->width>h->start ) ||
2612 0 : ( h2->start>=h->start && h->start+h->width>h2->start ))
2613 : break;
2614 : }
2615 : }
2616 : }
2617 : }
2618 0 : if ( h2!=NULL )
2619 0 : ff_post_error(_("Overlapped Hints"),_("The hint you have just selected overlaps with <%.2f,%.2f>. You should deselect one of the two."),
2620 : h2->start,h2->width);
2621 : }
2622 : }
2623 0 : return( true );
2624 : }
2625 :
2626 0 : GTextInfo *SCHintList(SplineChar *sc,HintMask *hm) {
2627 : StemInfo *h;
2628 : int i;
2629 : GTextInfo *ti;
2630 : char buffer[100];
2631 :
2632 0 : for ( h=sc->hstem, i=0; h!=NULL; h=h->next, ++i );
2633 0 : for ( h=sc->vstem ; h!=NULL; h=h->next, ++i );
2634 0 : ti = calloc(i+1,sizeof(GTextInfo));
2635 :
2636 0 : for ( h=sc->hstem, i=0; h!=NULL; h=h->next, ++i ) {
2637 0 : ti[i].fg = ti[i].bg = COLOR_DEFAULT;
2638 0 : ti[i].userdata = h;
2639 0 : if ( h->ghost && h->width>0 )
2640 0 : sprintf( buffer, "H<%g,%g>",
2641 0 : rint(h->start*100)/100+rint(h->width*100)/100, -rint(h->width*100)/100 );
2642 : else
2643 0 : sprintf( buffer, "H<%g,%g>",
2644 0 : rint(h->start*100)/100, rint(h->width*100)/100 );
2645 0 : ti[i].text = uc_copy(buffer);
2646 0 : if ( hm!=NULL && ((*hm)[i>>3]&(0x80>>(i&7))))
2647 0 : ti[i].selected = true;
2648 : }
2649 :
2650 0 : for ( h=sc->vstem ; h!=NULL; h=h->next, ++i ) {
2651 0 : ti[i].fg = ti[i].bg = COLOR_DEFAULT;
2652 0 : ti[i].userdata = h;
2653 0 : if ( h->ghost && h->width>0 )
2654 0 : sprintf( buffer, "V<%g,%g>",
2655 0 : rint(h->start*100)/100+rint(h->width*100)/100, -rint(h->width*100)/100 );
2656 : else
2657 0 : sprintf( buffer, "V<%g,%g>",
2658 0 : rint(h->start*100)/100, rint(h->width*100)/100 );
2659 0 : ti[i].text = uc_copy(buffer);
2660 0 : if ( hm!=NULL && ((*hm)[i>>3]&(0x80>>(i&7))))
2661 0 : ti[i].selected = true;
2662 : }
2663 0 : return( ti );
2664 : }
2665 :
2666 0 : static void PointGetInfo(CharView *cv, SplinePoint *sp, SplinePointList *spl) {
2667 0 : GIData* gi = 0;
2668 : GRect pos;
2669 : GWindowAttrs wattrs;
2670 0 : const int gcdcount = 54;
2671 0 : GGadgetCreateData gcd[gcdcount], hgcd[2], h2gcd[2], mgcd[11];
2672 : GGadgetCreateData mb[5], pb[9];
2673 : GGadgetCreateData *marray[11], *marray2[5], *marray3[5], *marray4[7],
2674 : *varray[11], *harray1[4], *harray2[6], *hvarray1[25], *hvarray2[25],
2675 : *hvarray3[16], *harray3[13];
2676 : GTextInfo label[54], mlabel[11];
2677 : GTabInfo aspects[4];
2678 : static GBox cur, nextcp, prevcp;
2679 : extern Color nextcpcol, prevcpcol;
2680 : GWindow root;
2681 : GRect screensize;
2682 : GPoint pt;
2683 : int j, defxpos, nextstarty, k, l;
2684 :
2685 0 : gi = calloc(1,sizeof(GIData));
2686 :
2687 0 : cur.main_background = nextcp.main_background = prevcp.main_background = COLOR_DEFAULT;
2688 0 : cur.main_foreground = 0xff0000;
2689 0 : nextcp.main_foreground = nextcpcol;
2690 0 : prevcp.main_foreground = prevcpcol;
2691 0 : gi->cv = cv;
2692 0 : gi->sc = cv->b.sc;
2693 0 : gi->cursp = sp;
2694 0 : gi->curspl = spl;
2695 0 : gi->oldstate = SplinePointListCopy(cv->b.layerheads[cv->b.drawmode]->splines);
2696 0 : gi->done = false;
2697 0 : CVPreserveState(&cv->b);
2698 :
2699 0 : root = GDrawGetRoot(NULL);
2700 0 : GDrawGetSize(root,&screensize);
2701 :
2702 0 : memset(&wattrs,0,sizeof(wattrs));
2703 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_positioned|wam_isdlg;
2704 0 : wattrs.event_masks = ~(1<<et_charup);
2705 0 : wattrs.restrict_input_to_me = 1;
2706 0 : wattrs.positioned = 1;
2707 0 : wattrs.cursor = ct_pointer;
2708 0 : wattrs.utf8_window_title = _("Point Info");
2709 0 : wattrs.is_dlg = true;
2710 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,PI_Width));
2711 0 : pos.height = GDrawPointsToPixels(NULL,PI_Height);
2712 0 : pt.x = cv->xoff + rint(sp->me.x*cv->scale);
2713 0 : pt.y = -cv->yoff + cv->height - rint(sp->me.y*cv->scale);
2714 0 : GDrawTranslateCoordinates(cv->v,root,&pt);
2715 0 : if ( pt.x+20+pos.width<=screensize.width )
2716 0 : pos.x = pt.x+20;
2717 0 : else if ( (pos.x = pt.x-10-screensize.width)<0 )
2718 0 : pos.x = 0;
2719 0 : pos.y = pt.y;
2720 0 : if ( pos.y+pos.height+20 > screensize.height )
2721 0 : pos.y = screensize.height - pos.height - 20;
2722 0 : if ( pos.y<0 ) pos.y = 0;
2723 0 : gi->gw = GDrawCreateTopWindow(NULL,&pos,pi_e_h,gi,&wattrs);
2724 :
2725 0 : memset(&gcd,0,sizeof(gcd));
2726 0 : memset(&label,0,sizeof(label));
2727 0 : memset(&hgcd,0,sizeof(hgcd));
2728 0 : memset(&h2gcd,0,sizeof(h2gcd));
2729 0 : memset(&mgcd,0,sizeof(mgcd));
2730 0 : memset(&mlabel,0,sizeof(mlabel));
2731 0 : memset(&aspects,0,sizeof(aspects));
2732 0 : memset(&pb,0,sizeof(pb));
2733 :
2734 0 : j=k=0;
2735 0 : gi->gcd = malloc( gcdcount*sizeof(GGadgetCreateData) );
2736 0 : memcpy( gi->gcd, gcd, gcdcount*sizeof(GGadgetCreateData) );
2737 :
2738 0 : label[j].text = (unichar_t *) _("_Normal");
2739 0 : label[j].text_is_1byte = true;
2740 0 : label[j].text_in_resource = true;
2741 0 : gcd[j].gd.label = &label[j];
2742 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = 5;
2743 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_cb_on;
2744 0 : gcd[j].gd.cid = CID_Normal;
2745 0 : gcd[j].gd.handle_controlevent = PI_InterpChanged;
2746 0 : gcd[j].creator = GRadioCreate;
2747 0 : harray1[0] = &gcd[j];
2748 0 : ++j;
2749 :
2750 0 : label[j].text = (unichar_t *) _("_Interpolated");
2751 0 : label[j].text_is_1byte = true;
2752 0 : label[j].text_in_resource = true;
2753 0 : gcd[j].gd.label = &label[j];
2754 0 : gcd[j].gd.pos.x = 70; gcd[j].gd.pos.y = 5;
2755 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
2756 0 : gcd[j].gd.cid = CID_Interpolated;
2757 0 : gcd[j].gd.handle_controlevent = PI_InterpChanged;
2758 0 : gcd[j].creator = GRadioCreate;
2759 0 : harray1[1] = &gcd[j]; harray1[2] = GCD_Glue; harray1[3] = NULL;
2760 0 : ++j;
2761 :
2762 0 : pb[2].gd.flags = gg_enabled|gg_visible;
2763 0 : pb[2].gd.u.boxelements = harray1;
2764 0 : pb[2].creator = GHBoxCreate;
2765 0 : varray[k++] = &pb[2];
2766 :
2767 0 : label[j].text = (unichar_t *) _("N_ever Interpolate");
2768 0 : label[j].text_is_1byte = true;
2769 0 : label[j].text_in_resource = true;
2770 0 : gcd[j].gd.label = &label[j];
2771 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+16;
2772 0 : gcd[j].gd.flags = cv->b.layerheads[cv->b.drawmode]->order2 ? (gg_enabled|gg_visible) : gg_visible;
2773 0 : gcd[j].gd.cid = CID_NeverInterpolate;
2774 0 : gcd[j].gd.handle_controlevent = PI_NeverInterpChanged;
2775 0 : gcd[j].creator = GCheckBoxCreate;
2776 0 : varray[k++] = &gcd[j];
2777 0 : ++j;
2778 :
2779 0 : gi->normal_start = j;
2780 0 : label[j].text = (unichar_t *) _("_Base:");
2781 0 : label[j].text_is_1byte = true;
2782 0 : label[j].text_in_resource = true;
2783 0 : gcd[j].gd.label = &label[j];
2784 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+17+6;
2785 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
2786 0 : gcd[j].gd.box = &cur;
2787 0 : gcd[j].creator = GLabelCreate;
2788 0 : harray2[0] = &gcd[j]; harray2[1] = GCD_Glue;
2789 0 : ++j;
2790 :
2791 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-6; gcd[j].gd.pos.width = 70;
2792 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2793 0 : gcd[j].gd.cid = CID_BaseX;
2794 0 : gcd[j].gd.handle_controlevent = PI_BaseChanged;
2795 0 : gcd[j].creator = GNumericFieldCreate;
2796 0 : harray2[2] = &gcd[j];
2797 0 : ++j;
2798 :
2799 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
2800 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2801 0 : gcd[j].gd.cid = CID_BaseY;
2802 0 : gcd[j].gd.handle_controlevent = PI_BaseChanged;
2803 0 : gcd[j].creator = GNumericFieldCreate;
2804 0 : harray2[3] = &gcd[j]; harray2[4] = GCD_Glue; harray2[5] = NULL;
2805 0 : ++j;
2806 :
2807 0 : pb[3].gd.flags = gg_enabled|gg_visible;
2808 0 : pb[3].gd.u.boxelements = harray2;
2809 0 : pb[3].creator = GHBoxCreate;
2810 0 : varray[k++] = &pb[3];
2811 :
2812 0 : l = 0;
2813 0 : label[j].text = (unichar_t *) _("Prev CP:");
2814 0 : label[j].text_is_1byte = true;
2815 0 : gcd[j].gd.label = &label[j];
2816 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+24+4;
2817 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
2818 0 : gcd[j].gd.box = &prevcp;
2819 0 : gcd[j].creator = GLabelCreate;
2820 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
2821 0 : ++j;
2822 :
2823 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 65;
2824 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2825 0 : gcd[j].gd.cid = CID_PrevPos;
2826 0 : gcd[j].creator = GLabelCreate;
2827 0 : hvarray1[l++] = &gcd[j];
2828 0 : ++j;
2829 :
2830 0 : defxpos = 130;
2831 0 : label[j].text = (unichar_t *) S_("ControlPoint|Default");
2832 0 : label[j].text_is_1byte = true;
2833 0 : gcd[j].gd.label = &label[j];
2834 0 : gcd[j].gd.pos.x = defxpos; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-3;
2835 0 : gcd[j].gd.flags = (gg_enabled|gg_visible);
2836 0 : gcd[j].gd.cid = CID_PrevDef;
2837 0 : gcd[j].gd.handle_controlevent = PI_PrevDefChanged;
2838 0 : gcd[j].creator = GCheckBoxCreate;
2839 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = NULL;
2840 0 : ++j;
2841 :
2842 0 : label[j].text = (unichar_t *) _("Offset");
2843 0 : label[j].text_is_1byte = true;
2844 0 : gcd[j].gd.label = &label[j];
2845 0 : gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+18+4;
2846 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2847 0 : gcd[j].creator = GLabelCreate;
2848 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
2849 0 : ++j;
2850 :
2851 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
2852 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2853 0 : gcd[j].gd.cid = CID_PrevXOff;
2854 0 : gcd[j].gd.handle_controlevent = PI_PrevChanged;
2855 0 : gcd[j].creator = GNumericFieldCreate;
2856 0 : hvarray1[l++] = &gcd[j];
2857 0 : ++j;
2858 :
2859 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
2860 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2861 0 : gcd[j].gd.cid = CID_PrevYOff;
2862 0 : gcd[j].gd.handle_controlevent = PI_PrevChanged;
2863 0 : gcd[j].creator = GNumericFieldCreate;
2864 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = NULL;
2865 0 : ++j;
2866 :
2867 0 : label[j].text = (unichar_t *) _("Dist");
2868 0 : label[j].text_is_1byte = true;
2869 0 : gcd[j].gd.label = &label[j];
2870 0 : gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
2871 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2872 0 : gcd[j].creator = GLabelCreate;
2873 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_Glue;
2874 0 : ++j;
2875 :
2876 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
2877 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2878 0 : gcd[j].gd.cid = CID_PrevR;
2879 0 : gcd[j].gd.handle_controlevent = PI_PrevChanged;
2880 0 : gcd[j].creator = GNumericFieldCreate;
2881 0 : hvarray1[l++] = &gcd[j];
2882 0 : ++j;
2883 :
2884 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 60;
2885 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2886 0 : gcd[j].gd.cid = CID_PrevTheta;
2887 0 : gcd[j].gd.handle_controlevent = PI_PrevChanged;
2888 0 : gcd[j].creator = GTextFieldCreate;
2889 0 : hvarray1[l++] = &gcd[j];
2890 0 : ++j;
2891 :
2892 0 : label[j].text = (unichar_t *) U_("°");
2893 0 : label[j].text_is_1byte = true;
2894 0 : gcd[j].gd.label = &label[j];
2895 0 : gcd[j].gd.pos.x = gcd[j-1].gd.pos.x+gcd[j-1].gd.pos.width+2; gcd[j].gd.pos.y = gcd[j-3].gd.pos.y;
2896 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2897 0 : gcd[j].creator = GLabelCreate;
2898 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = NULL;
2899 0 : ++j;
2900 :
2901 0 : label[j].text = (unichar_t *) _("Curvature: -0.00000000");
2902 0 : label[j].text_is_1byte = true;
2903 0 : gcd[j].gd.label = &label[j];
2904 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+20;
2905 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2906 0 : gcd[j].gd.cid = CID_PrevCurvature;
2907 0 : gcd[j].creator = GLabelCreate;
2908 0 : hvarray1[l++] = &gcd[j]; hvarray1[l++] = GCD_ColSpan; hvarray1[l++] = GCD_ColSpan;
2909 0 : hvarray1[l++] = GCD_Glue; hvarray1[l++] = GCD_Glue; hvarray1[l++] = NULL;
2910 0 : hvarray1[l++] = NULL;
2911 0 : ++j;
2912 :
2913 0 : pb[4].gd.pos.x = pb[4].gd.pos.y = 2;
2914 0 : pb[4].gd.flags = gg_enabled|gg_visible;
2915 0 : pb[4].gd.u.boxelements = hvarray1;
2916 0 : pb[4].creator = GHVGroupCreate;
2917 0 : varray[k++] = &pb[4];
2918 :
2919 0 : l = 0;
2920 0 : nextstarty = gcd[j-2].gd.pos.y+28;
2921 0 : label[j].text = (unichar_t *) _("Next CP:");
2922 0 : label[j].text_is_1byte = true;
2923 0 : gcd[j].gd.label = &label[j];
2924 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = nextstarty;
2925 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
2926 0 : gcd[j].gd.box = &nextcp;
2927 0 : gcd[j].creator = GLabelCreate;
2928 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
2929 0 : ++j;
2930 :
2931 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = nextstarty; gcd[j].gd.pos.width = 65;
2932 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2933 0 : gcd[j].gd.cid = CID_NextPos;
2934 0 : gcd[j].creator = GLabelCreate;
2935 0 : hvarray2[l++] = &gcd[j];
2936 0 : ++j;
2937 :
2938 0 : label[j].text = (unichar_t *) S_("ControlPoint|Default");
2939 0 : label[j].text_is_1byte = true;
2940 0 : gcd[j].gd.label = &label[j];
2941 0 : gcd[j].gd.pos.x = defxpos; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-3;
2942 0 : gcd[j].gd.flags = (gg_enabled|gg_visible);
2943 0 : gcd[j].gd.cid = CID_NextDef;
2944 0 : gcd[j].gd.handle_controlevent = PI_NextDefChanged;
2945 0 : gcd[j].creator = GCheckBoxCreate;
2946 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
2947 0 : ++j;
2948 :
2949 0 : label[j].text = (unichar_t *) _("Offset");
2950 0 : label[j].text_is_1byte = true;
2951 0 : gcd[j].gd.label = &label[j];
2952 0 : gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+18+4;
2953 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2954 0 : gcd[j].creator = GLabelCreate;
2955 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
2956 0 : ++j;
2957 :
2958 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
2959 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2960 0 : gcd[j].gd.cid = CID_NextXOff;
2961 0 : gcd[j].gd.handle_controlevent = PI_NextChanged;
2962 0 : gcd[j].creator = GNumericFieldCreate;
2963 0 : hvarray2[l++] = &gcd[j];
2964 0 : ++j;
2965 :
2966 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
2967 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2968 0 : gcd[j].gd.cid = CID_NextYOff;
2969 0 : gcd[j].gd.handle_controlevent = PI_NextChanged;
2970 0 : gcd[j].creator = GNumericFieldCreate;
2971 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
2972 0 : ++j;
2973 :
2974 0 : label[j].text = (unichar_t *) _("Dist");
2975 0 : label[j].text_is_1byte = true;
2976 0 : gcd[j].gd.label = &label[j];
2977 0 : gcd[j].gd.pos.x = gcd[3].gd.pos.x+10; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
2978 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2979 0 : gcd[j].creator = GLabelCreate;
2980 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_Glue;
2981 0 : ++j;
2982 :
2983 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
2984 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2985 0 : gcd[j].gd.cid = CID_NextR;
2986 0 : gcd[j].gd.handle_controlevent = PI_NextChanged;
2987 0 : gcd[j].creator = GNumericFieldCreate;
2988 0 : hvarray2[l++] = &gcd[j];
2989 0 : ++j;
2990 :
2991 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 60;
2992 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
2993 0 : gcd[j].gd.cid = CID_NextTheta;
2994 0 : gcd[j].gd.handle_controlevent = PI_NextChanged;
2995 0 : gcd[j].creator = GTextFieldCreate;
2996 0 : hvarray2[l++] = &gcd[j];
2997 0 : ++j;
2998 :
2999 0 : label[j].text = (unichar_t *) U_("°");
3000 0 : label[j].text_is_1byte = true;
3001 0 : gcd[j].gd.label = &label[j];
3002 0 : gcd[j].gd.pos.x = gcd[j-1].gd.pos.x+gcd[j-1].gd.pos.width+2; gcd[j].gd.pos.y = gcd[j-3].gd.pos.y;
3003 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3004 0 : gcd[j].creator = GLabelCreate;
3005 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = NULL;
3006 0 : ++j;
3007 :
3008 0 : label[j].text = (unichar_t *) _("Curvature: -0.00000000");
3009 0 : label[j].text_is_1byte = true;
3010 0 : gcd[j].gd.label = &label[j];
3011 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+20;
3012 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3013 0 : gcd[j].gd.cid = CID_NextCurvature;
3014 0 : gcd[j].creator = GLabelCreate;
3015 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = GCD_ColSpan;
3016 0 : ++j;
3017 :
3018 0 : label[j].text = (unichar_t *) "∆: -0.00000000";
3019 0 : label[j].text_is_1byte = true;
3020 0 : gcd[j].gd.label = &label[j];
3021 0 : gcd[j].gd.pos.x = 130; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3022 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
3023 0 : gcd[j].gd.popup_msg = (unichar_t *) _("This is the difference of the curvature between\nthe next and previous splines. Contours often\nlook nicer as this number approaches 0." );
3024 0 : gcd[j].gd.cid = CID_DeltaCurvature;
3025 0 : gcd[j].creator = GLabelCreate;
3026 0 : hvarray2[l++] = &gcd[j]; hvarray2[l++] = GCD_ColSpan; hvarray2[l++] = NULL;
3027 0 : hvarray2[l++] = NULL;
3028 0 : ++j;
3029 :
3030 0 : pb[5].gd.pos.x = pb[5].gd.pos.y = 2;
3031 0 : pb[5].gd.flags = gg_enabled|gg_visible;
3032 0 : pb[5].gd.u.boxelements = hvarray2;
3033 0 : pb[5].creator = GHVGroupCreate;
3034 0 : varray[k++] = &pb[5];
3035 0 : gi->normal_end = j;
3036 :
3037 0 : gi->interp_start = j;
3038 0 : l = 0;
3039 0 : label[j].text = (unichar_t *) _("_Base:");
3040 0 : label[j].text_is_1byte = true;
3041 0 : label[j].text_in_resource = true;
3042 0 : gcd[j].gd.label = &label[j];
3043 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[gi->normal_start].gd.pos.y;
3044 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
3045 0 : gcd[j].gd.box = &cur;
3046 0 : gcd[j].creator = GLabelCreate;
3047 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
3048 0 : ++j;
3049 :
3050 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 65;
3051 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3052 0 : gcd[j].gd.cid = CID_BasePos;
3053 0 : gcd[j].creator = GLabelCreate;
3054 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue; hvarray3[l++] = NULL;
3055 0 : ++j;
3056 :
3057 0 : label[j].text = (unichar_t *) _("Prev CP:");
3058 0 : label[j].text_is_1byte = true;
3059 0 : gcd[j].gd.label = &label[j];
3060 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+14+4;
3061 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
3062 0 : gcd[j].gd.box = &prevcp;
3063 0 : gcd[j].creator = GLabelCreate;
3064 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
3065 0 : ++j;
3066 :
3067 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
3068 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3069 0 : gcd[j].gd.cid = CID_PrevX;
3070 0 : gcd[j].gd.handle_controlevent = PI_PrevIntChanged;
3071 0 : gcd[j].creator = GNumericFieldCreate;
3072 0 : hvarray3[l++] = &gcd[j];
3073 0 : ++j;
3074 :
3075 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
3076 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3077 0 : gcd[j].gd.cid = CID_PrevY;
3078 0 : gcd[j].gd.handle_controlevent = PI_PrevIntChanged;
3079 0 : gcd[j].creator = GNumericFieldCreate;
3080 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = NULL;
3081 0 : ++j;
3082 :
3083 0 : label[j].text = (unichar_t *) _("Next CP:");
3084 0 : label[j].text_is_1byte = true;
3085 0 : gcd[j].gd.label = &label[j];
3086 0 : gcd[j].gd.pos.x = 9; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+24+4;
3087 0 : gcd[j].gd.flags = gg_enabled|gg_visible|gg_dontcopybox;
3088 0 : gcd[j].gd.box = &nextcp;
3089 0 : gcd[j].creator = GLabelCreate;
3090 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = GCD_Glue;
3091 0 : ++j;
3092 :
3093 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-4; gcd[j].gd.pos.width = 70;
3094 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3095 0 : gcd[j].gd.cid = CID_NextX;
3096 0 : gcd[j].gd.handle_controlevent = PI_NextIntChanged;
3097 0 : gcd[j].creator = GNumericFieldCreate;
3098 0 : hvarray3[l++] = &gcd[j];
3099 0 : ++j;
3100 :
3101 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
3102 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3103 0 : gcd[j].gd.cid = CID_NextY;
3104 0 : gcd[j].gd.handle_controlevent = PI_NextIntChanged;
3105 0 : gcd[j].creator = GNumericFieldCreate;
3106 0 : hvarray3[l++] = &gcd[j]; hvarray3[l++] = NULL; hvarray3[l++] = NULL;
3107 0 : ++j;
3108 0 : gi->interp_end = j;
3109 :
3110 0 : pb[6].gd.flags = gg_enabled|gg_visible;
3111 0 : pb[6].gd.u.boxelements = hvarray3;
3112 0 : pb[6].creator = GHVBoxCreate;
3113 0 : varray[k++] = &pb[6];
3114 0 : varray[k++] = GCD_Glue;
3115 :
3116 0 : label[j].text = (unichar_t *) _("Type:");
3117 0 : label[j].text_is_1byte = true;
3118 0 : gcd[j].gd.label = &label[j];
3119 0 : gcd[j].gd.pos.x = gcd[0].gd.pos.x; gcd[j].gd.pos.y = gcd[gi->normal_end-2].gd.pos.y+26;
3120 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3121 0 : gcd[j].creator = GLabelCreate;
3122 0 : harray3[0] = &gcd[j]; harray3[1] = GCD_Glue; harray3[2] = GCD_Glue;
3123 0 : ++j;
3124 :
3125 0 : label[j].image = &GIcon_midcurve;
3126 0 : gcd[j].gd.label = &label[j];
3127 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
3128 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3129 0 : gcd[j].gd.cid = CID_Curve;
3130 0 : gcd[j].gd.handle_controlevent = PI_PTypeChanged;
3131 0 : gcd[j].creator = GRadioCreate;
3132 0 : harray3[3] = &gcd[j]; harray3[4] = GCD_Glue;
3133 0 : ++j;
3134 :
3135 0 : label[j].image = &GIcon_midhvcurve;
3136 0 : gcd[j].gd.label = &label[j];
3137 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
3138 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3139 0 : gcd[j].gd.cid = CID_HVCurve;
3140 0 : gcd[j].gd.handle_controlevent = PI_PTypeChanged;
3141 0 : gcd[j].creator = GRadioCreate;
3142 0 : harray3[5] = &gcd[j]; harray3[6] = GCD_Glue;
3143 0 : ++j;
3144 :
3145 0 : label[j].image = &GIcon_midcorner;
3146 0 : gcd[j].gd.label = &label[j];
3147 0 : gcd[j].gd.pos.x = 100; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3148 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
3149 0 : gcd[j].gd.cid = CID_Corner;
3150 0 : gcd[j].gd.handle_controlevent = PI_PTypeChanged;
3151 0 : gcd[j].creator = GRadioCreate;
3152 0 : harray3[7] = &gcd[j]; harray3[8] = GCD_Glue;
3153 0 : ++j;
3154 :
3155 0 : label[j].image = &GIcon_midtangent;
3156 0 : gcd[j].gd.label = &label[j];
3157 0 : gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3158 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
3159 0 : gcd[j].gd.cid = CID_Tangent;
3160 0 : gcd[j].gd.handle_controlevent = PI_PTypeChanged;
3161 0 : gcd[j].creator = GRadioCreate;
3162 0 : harray3[9] = &gcd[j]; harray3[10] = GCD_Glue; harray3[11] = GCD_Glue;
3163 0 : harray3[12] = NULL;
3164 0 : ++j;
3165 :
3166 0 : pb[7].gd.flags = gg_enabled|gg_visible;
3167 0 : pb[7].gd.u.boxelements = harray3;
3168 0 : pb[7].creator = GHBoxCreate;
3169 0 : varray[k++] = &pb[7];
3170 0 : varray[k++] = NULL;
3171 :
3172 0 : pb[0].gd.flags = gg_enabled|gg_visible;
3173 0 : pb[0].gd.u.boxelements = varray;
3174 0 : pb[0].creator = GVBoxCreate;
3175 :
3176 0 : hgcd[0].gd.pos.x = 5; hgcd[0].gd.pos.y = 5;
3177 0 : hgcd[0].gd.pos.width = PI_Width-20; hgcd[0].gd.pos.height = gcd[j-1].gd.pos.y+10;
3178 0 : hgcd[0].gd.flags = gg_visible | gg_enabled | gg_list_multiplesel;
3179 0 : hgcd[0].gd.cid = CID_HintMask;
3180 0 : hgcd[0].gd.u.list = SCHintList(cv->b.sc,NULL);
3181 0 : hgcd[0].gd.handle_controlevent = PI_HintSel;
3182 0 : hgcd[0].creator = GListCreate;
3183 :
3184 0 : h2gcd[0].gd.pos.x = 5; h2gcd[0].gd.pos.y = 5;
3185 0 : h2gcd[0].gd.pos.width = PI_Width-20; h2gcd[0].gd.pos.height = gcd[j-1].gd.pos.y+10;
3186 0 : h2gcd[0].gd.flags = gg_visible | gg_list_multiplesel;
3187 0 : h2gcd[0].gd.cid = CID_ActiveHints;
3188 0 : h2gcd[0].gd.u.list = SCHintList(cv->b.sc,NULL);
3189 0 : h2gcd[0].creator = GListCreate;
3190 :
3191 0 : j = 0;
3192 :
3193 0 : aspects[j].text = (unichar_t *) _("Location");
3194 0 : aspects[j].text_is_1byte = true;
3195 0 : aspects[j++].gcd = pb;
3196 :
3197 0 : aspects[j].text = (unichar_t *) _("Hint Mask");
3198 0 : aspects[j].text_is_1byte = true;
3199 0 : aspects[j++].gcd = hgcd;
3200 :
3201 0 : aspects[j].text = (unichar_t *) _("Active Hints");
3202 0 : aspects[j].text_is_1byte = true;
3203 0 : aspects[j++].gcd = h2gcd;
3204 :
3205 0 : j = 0;
3206 :
3207 0 : mgcd[j].gd.pos.x = 4; mgcd[j].gd.pos.y = 6;
3208 0 : mgcd[j].gd.pos.width = PI_Width-8;
3209 0 : mgcd[j].gd.pos.height = hgcd[0].gd.pos.height+10+24;
3210 0 : mgcd[j].gd.u.tabs = aspects;
3211 0 : mgcd[j].gd.flags = gg_visible | gg_enabled;
3212 0 : mgcd[j].gd.handle_controlevent = PI_AspectChange;
3213 0 : mgcd[j].gd.cid = CID_TabSet;
3214 0 : mgcd[j++].creator = GTabSetCreate;
3215 :
3216 0 : mgcd[j].gd.pos.x = (PI_Width-2*50-10)/2; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+mgcd[j-1].gd.pos.height+5;
3217 0 : mgcd[j].gd.pos.width = 53; mgcd[j].gd.pos.height = 0;
3218 0 : mgcd[j].gd.flags = gg_visible | gg_enabled;
3219 0 : mlabel[j].text = (unichar_t *) _("< _Prev");
3220 0 : mlabel[j].text_is_1byte = true;
3221 0 : mlabel[j].text_in_resource = true;
3222 0 : mgcd[j].gd.label = &mlabel[j];
3223 0 : mgcd[j].gd.cid = CID_Prev;
3224 0 : mgcd[j].gd.handle_controlevent = PI_NextPrev;
3225 0 : mgcd[j].creator = GButtonCreate;
3226 0 : ++j;
3227 :
3228 0 : mgcd[j].gd.pos.x = PI_Width-50-(PI_Width-2*50-10)/2; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y;
3229 0 : mgcd[j].gd.pos.width = 53; mgcd[j].gd.pos.height = 0;
3230 0 : mgcd[j].gd.flags = gg_visible | gg_enabled;
3231 0 : mlabel[j].text = (unichar_t *) _("_Next >");
3232 0 : mlabel[j].text_is_1byte = true;
3233 0 : mlabel[j].text_in_resource = true;
3234 0 : mgcd[j].gd.label = &mlabel[j];
3235 0 : mgcd[j].gd.cid = CID_Next;
3236 0 : mgcd[j].gd.handle_controlevent = PI_NextPrev;
3237 0 : mgcd[j].creator = GButtonCreate;
3238 0 : ++j;
3239 :
3240 : /* Why 3? */
3241 0 : mgcd[j].gd.pos.x = mgcd[j-2].gd.pos.x-50+3; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+26;
3242 0 : mgcd[j].gd.flags = gg_visible | gg_enabled;
3243 0 : mlabel[j].text = (unichar_t *) _("Prev On Contour");
3244 0 : mlabel[j].text_is_1byte = true;
3245 0 : mgcd[j].gd.label = &mlabel[j];
3246 0 : mgcd[j].gd.cid = CID_PrevC;
3247 0 : mgcd[j].gd.handle_controlevent = PI_NextPrev;
3248 0 : mgcd[j].creator = GButtonCreate;
3249 0 : ++j;
3250 :
3251 0 : mgcd[j].gd.pos.x = mgcd[j-2].gd.pos.x; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y;
3252 0 : mgcd[j].gd.flags = gg_visible | gg_enabled;
3253 0 : mlabel[j].text = (unichar_t *) _("Next On Contour");
3254 0 : mlabel[j].text_is_1byte = true;
3255 0 : mgcd[j].gd.label = &mlabel[j];
3256 0 : mgcd[j].gd.cid = CID_NextC;
3257 0 : mgcd[j].gd.handle_controlevent = PI_NextPrev;
3258 0 : mgcd[j].creator = GButtonCreate;
3259 0 : ++j;
3260 :
3261 0 : mgcd[j].gd.pos.x = 5; mgcd[j].gd.pos.y = mgcd[j-1].gd.pos.y+28;
3262 0 : mgcd[j].gd.pos.width = PI_Width-10;
3263 0 : mgcd[j].gd.flags = gg_enabled|gg_visible;
3264 0 : mgcd[j].creator = GLineCreate;
3265 0 : ++j;
3266 :
3267 0 : mgcd[j].gd.pos.x = 20-3; mgcd[j].gd.pos.y = PI_Height-33-3;
3268 0 : mgcd[j].gd.pos.width = -1; mgcd[j].gd.pos.height = 0;
3269 0 : mgcd[j].gd.flags = gg_visible | gg_enabled | gg_but_default;
3270 0 : mlabel[j].text = (unichar_t *) _("_OK");
3271 0 : mlabel[j].text_is_1byte = true;
3272 0 : mlabel[j].text_in_resource = true;
3273 0 : mgcd[j].gd.mnemonic = 'O';
3274 0 : mgcd[j].gd.label = &mlabel[j];
3275 0 : mgcd[j].gd.handle_controlevent = PI_Ok;
3276 0 : mgcd[j].creator = GButtonCreate;
3277 0 : ++j;
3278 :
3279 0 : mgcd[j].gd.pos.x = -20; mgcd[j].gd.pos.y = PI_Height-33;
3280 0 : mgcd[j].gd.pos.width = -1; mgcd[j].gd.pos.height = 0;
3281 0 : mgcd[j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
3282 0 : mlabel[j].text = (unichar_t *) _("_Cancel");
3283 0 : mlabel[j].text_is_1byte = true;
3284 0 : mlabel[j].text_in_resource = true;
3285 0 : mgcd[j].gd.label = &mlabel[j];
3286 0 : mgcd[j].gd.mnemonic = 'C';
3287 0 : mgcd[j].gd.handle_controlevent = PI_Cancel;
3288 0 : mgcd[j].creator = GButtonCreate;
3289 0 : ++j;
3290 :
3291 0 : marray[0] = &mgcd[0]; marray[1] = NULL;
3292 0 : marray[2] = &mb[2]; marray[3] = NULL;
3293 0 : marray[4] = &mb[3]; marray[5] = NULL;
3294 0 : marray[6] = &mgcd[5]; marray[7] = NULL;
3295 0 : marray[8] = &mb[4]; marray[9] = NULL;
3296 0 : marray[10] = NULL;
3297 0 : marray2[0] = GCD_Glue; marray2[1] = &mgcd[1]; marray2[2] = &mgcd[2]; marray2[3] = GCD_Glue; marray2[4] = NULL;
3298 0 : marray3[0] = GCD_Glue; marray3[1] = &mgcd[3]; marray3[2] = &mgcd[4]; marray3[3] = GCD_Glue; marray3[4] = NULL;
3299 0 : marray4[0] = GCD_Glue; marray4[1] = &mgcd[6]; marray4[2] = GCD_Glue; marray4[3] = GCD_Glue; marray4[4] = &mgcd[7]; marray4[5] = GCD_Glue; marray4[6] = NULL;
3300 :
3301 0 : memset(mb,0,sizeof(mb));
3302 0 : mb[0].gd.pos.x = mb[0].gd.pos.y = 2;
3303 0 : mb[0].gd.flags = gg_enabled|gg_visible;
3304 0 : mb[0].gd.u.boxelements = marray;
3305 0 : mb[0].creator = GHVGroupCreate;
3306 :
3307 0 : mb[2].gd.flags = gg_enabled|gg_visible;
3308 0 : mb[2].gd.u.boxelements = marray2;
3309 0 : mb[2].creator = GHBoxCreate;
3310 :
3311 0 : mb[3].gd.flags = gg_enabled|gg_visible;
3312 0 : mb[3].gd.u.boxelements = marray3;
3313 0 : mb[3].creator = GHBoxCreate;
3314 :
3315 0 : mb[4].gd.flags = gg_enabled|gg_visible;
3316 0 : mb[4].gd.u.boxelements = marray4;
3317 0 : mb[4].creator = GHBoxCreate;
3318 :
3319 0 : GGadgetsCreate(gi->gw,mb);
3320 0 : gi->group1ret = pb[4].ret; gi->group2ret = pb[5].ret;
3321 0 : memcpy( gi->gcd, gcd, gcdcount*sizeof(GGadgetCreateData) ); // This copies pointers, but only to static things.
3322 0 : GTextInfoListFree(hgcd[0].gd.u.list);
3323 0 : GTextInfoListFree(h2gcd[0].gd.u.list);
3324 :
3325 0 : GHVBoxSetExpandableRow(mb[0].ret,0);
3326 0 : GHVBoxSetExpandableCol(mb[2].ret,gb_expandgluesame);
3327 0 : GHVBoxSetExpandableCol(mb[3].ret,gb_expandgluesame);
3328 0 : GHVBoxSetExpandableCol(mb[4].ret,gb_expandgluesame);
3329 0 : GHVBoxSetExpandableRow(pb[0].ret,gb_expandglue);
3330 0 : GHVBoxSetExpandableCol(pb[2].ret,gb_expandglue);
3331 0 : GHVBoxSetExpandableCol(pb[3].ret,gb_expandglue);
3332 0 : GHVBoxSetExpandableCol(pb[4].ret,gb_expandglue);
3333 0 : GHVBoxSetExpandableCol(pb[5].ret,gb_expandglue);
3334 0 : GHVBoxSetExpandableCol(pb[6].ret,gb_expandglue);
3335 0 : GHVBoxSetExpandableCol(pb[7].ret,gb_expandglue);
3336 :
3337 0 : PIChangePoint(gi);
3338 :
3339 0 : GHVBoxFitWindow(mb[0].ret);
3340 :
3341 0 : gi->nonmodal = 1;
3342 0 : dlist_pushfront( &cv->pointInfoDialogs, (struct dlistnode *)gi );
3343 0 : GWidgetHidePalettes();
3344 0 : GDrawResize(gi->gw,
3345 : GGadgetScale(GDrawPointsToPixels(NULL,PI_Width)),
3346 : GDrawPointsToPixels(NULL,PI_Height));
3347 0 : GDrawSetVisible(gi->gw,true);
3348 0 : }
3349 :
3350 : /* ************************************************************************** */
3351 : /* ****************************** Spiro Points ****************************** */
3352 : /* ************************************************************************** */
3353 :
3354 0 : static void SpiroFillup(GIData *ci, int except_cid) {
3355 : char buffer[50];
3356 : int ty;
3357 :
3358 0 : mysprintf(buffer, "%.2f", ci->curcp->x );
3359 0 : if ( except_cid!=CID_BaseX )
3360 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseX),buffer);
3361 :
3362 0 : mysprintf(buffer, "%.2f", ci->curcp->y );
3363 0 : if ( except_cid!=CID_BaseY )
3364 0 : GGadgetSetTitle8(GWidgetGetControl(ci->gw,CID_BaseY),buffer);
3365 :
3366 0 : ty = ci->curcp->ty&0x7f;
3367 0 : if ( ty == SPIRO_OPEN_CONTOUR )
3368 0 : ty = SPIRO_G4;
3369 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Curve), ty==SPIRO_G4 );
3370 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Tangent), ty==SPIRO_G2 );
3371 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_Corner), ty==SPIRO_CORNER );
3372 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_SpiroLeft), ty==SPIRO_LEFT );
3373 0 : GGadgetSetChecked(GWidgetGetControl(ci->gw,CID_SpiroRight), ty==SPIRO_RIGHT );
3374 0 : }
3375 :
3376 0 : static void SpiroChangePoint(GIData *ci) {
3377 :
3378 0 : SpiroFillup(ci,0);
3379 0 : }
3380 :
3381 0 : static int PI_SpiroNextPrev(GGadget *g, GEvent *e) {
3382 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
3383 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
3384 0 : CharView *cv = ci->cv;
3385 0 : int cid = GGadgetGetCid(g);
3386 : SplinePointList *spl;
3387 0 : int index = ci->curcp - ci->curspl->spiros;
3388 : BasePoint here;
3389 :
3390 0 : SPIRO_DESELECT(ci->curcp);
3391 0 : if ( cid == CID_Next ) {
3392 0 : if ( index < ci->curspl->spiro_cnt-2 )
3393 0 : ci->curcp = &ci->curspl->spiros[index+1];
3394 : else {
3395 0 : if ( ci->curspl->next == NULL ) {
3396 0 : ci->curspl = cv->b.layerheads[cv->b.drawmode]->splines;
3397 0 : GDrawBeep(NULL);
3398 : } else
3399 0 : ci->curspl = ci->curspl->next;
3400 0 : ci->curcp = &ci->curspl->spiros[0];
3401 : }
3402 0 : } else if ( cid == CID_Prev ) {
3403 0 : if ( index!=0 ) {
3404 0 : ci->curcp = &ci->curspl->spiros[index-1];
3405 : } else {
3406 0 : if ( ci->curspl==cv->b.layerheads[cv->b.drawmode]->splines ) {
3407 0 : for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=NULL; spl=spl->next );
3408 0 : GDrawBeep(NULL);
3409 : } else {
3410 0 : for ( spl = cv->b.layerheads[cv->b.drawmode]->splines; spl->next!=ci->curspl; spl=spl->next );
3411 : }
3412 0 : ci->curspl = spl;
3413 0 : ci->curcp = &ci->curspl->spiros[ci->curspl->spiro_cnt-2];
3414 : }
3415 0 : } else if ( cid==CID_NextC ) {
3416 0 : if ( index < ci->curspl->spiro_cnt-2 )
3417 0 : ci->curcp = &ci->curspl->spiros[index+1];
3418 : else {
3419 0 : ci->curcp = &ci->curspl->spiros[0];
3420 0 : GDrawBeep(NULL);
3421 : }
3422 : } else /* CID_PrevC */ {
3423 0 : if ( index!=0 )
3424 0 : ci->curcp = &ci->curspl->spiros[index-1];
3425 : else {
3426 0 : ci->curcp = &ci->curspl->spiros[ci->curspl->spiro_cnt-2];
3427 0 : GDrawBeep(NULL);
3428 : }
3429 : }
3430 0 : SPIRO_SELECT(ci->curcp);
3431 0 : SpiroChangePoint(ci);
3432 0 : here.x = ci->curcp->x; here.y = ci->curcp->y;
3433 0 : CVShowPoint(cv,&here);
3434 0 : SCUpdateAll(cv->b.sc);
3435 : }
3436 0 : return( true );
3437 : }
3438 :
3439 0 : static int PI_SpiroChanged(GGadget *g, GEvent *e) {
3440 0 : if ( e->type==et_controlevent &&
3441 0 : (e->u.control.subtype == et_textchanged ||
3442 0 : e->u.control.subtype == et_radiochanged)) {
3443 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
3444 : double x,y;
3445 : int ty;
3446 0 : int err=false;
3447 0 : spiro_cp *curcp = ci->curcp;
3448 :
3449 0 : x = GetCalmReal8(ci->gw,CID_BaseX,_("X"),&err);
3450 0 : y = GetCalmReal8(ci->gw,CID_BaseY,_("Y"),&err);
3451 0 : ty = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Curve))? SPIRO_G4 :
3452 0 : GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Tangent))? SPIRO_G2 :
3453 0 : GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_Corner))? SPIRO_CORNER :
3454 0 : GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_SpiroLeft))? SPIRO_LEFT :
3455 : SPIRO_RIGHT;
3456 0 : curcp->x = x;
3457 0 : curcp->y = y;
3458 0 : curcp->ty = ty | 0x80;
3459 0 : SSRegenerateFromSpiros(ci->curspl);
3460 0 : CVCharChangedUpdate(&ci->cv->b);
3461 : }
3462 0 : return( true );
3463 : }
3464 :
3465 0 : static int PI_SpiroOk(GGadget *g, GEvent *e) {
3466 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
3467 0 : GIData *ci = GDrawGetUserData(GGadgetGetWindow(g));
3468 :
3469 0 : ci->done = true;
3470 : /* All the work has been done as we've gone along */
3471 0 : PI_Close(g);
3472 : }
3473 0 : return( true );
3474 : }
3475 :
3476 0 : static void SpiroPointGetInfo(CharView *cv, spiro_cp *scp, SplinePointList *spl) {
3477 0 : GIData *gip = calloc(1, sizeof(GIData));
3478 : GRect pos;
3479 : GWindowAttrs wattrs;
3480 : GGadgetCreateData gcd[20];
3481 : GGadgetCreateData pb[9];
3482 : GGadgetCreateData *varray[20], *harray2[10], *harray3[15], *harray4[6],
3483 : *harray5[6], *harray6[9];
3484 : GTextInfo label[20];
3485 : GWindow root;
3486 : GRect screensize;
3487 : GPoint pt;
3488 : int j,k;
3489 :
3490 0 : gip->cv = cv;
3491 0 : gip->sc = cv->b.sc;
3492 0 : gip->curcp = scp;
3493 0 : gip->curspl = spl;
3494 0 : gip->oldstate = SplinePointListCopy(cv->b.layerheads[cv->b.drawmode]->splines);
3495 0 : gip->done = false;
3496 0 : CVPreserveState(&cv->b);
3497 :
3498 0 : root = GDrawGetRoot(NULL);
3499 0 : GDrawGetSize(root,&screensize);
3500 :
3501 0 : memset(&wattrs,0,sizeof(wattrs));
3502 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_positioned|wam_isdlg|wam_restrict;
3503 0 : wattrs.event_masks = ~(1<<et_charup);
3504 0 : wattrs.restrict_input_to_me = 1;
3505 0 : wattrs.positioned = 1;
3506 0 : wattrs.cursor = ct_pointer;
3507 0 : wattrs.utf8_window_title = _("Spiro Point Info");
3508 0 : wattrs.is_dlg = true;
3509 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,PI_Width));
3510 0 : pos.height = GDrawPointsToPixels(NULL,PI_Height);
3511 0 : pt.x = cv->xoff + rint(scp->x*cv->scale);
3512 0 : pt.y = -cv->yoff + cv->height - rint(scp->y*cv->scale);
3513 0 : GDrawTranslateCoordinates(cv->v,root,&pt);
3514 0 : if ( pt.x+20+pos.width<=screensize.width )
3515 0 : pos.x = pt.x+20;
3516 0 : else if ( (pos.x = pt.x-10-screensize.width)<0 )
3517 0 : pos.x = 0;
3518 0 : pos.y = pt.y;
3519 0 : if ( pos.y+pos.height+20 > screensize.height )
3520 0 : pos.y = screensize.height - pos.height - 20;
3521 0 : if ( pos.y<0 ) pos.y = 0;
3522 0 : gip->gw = GDrawCreateTopWindow(NULL,&pos,pi_e_h,gip,&wattrs);
3523 :
3524 0 : memset(&gcd,0,sizeof(gcd));
3525 0 : memset(&label,0,sizeof(label));
3526 0 : memset(&pb,0,sizeof(pb));
3527 :
3528 0 : j=k=0;
3529 0 : gip->gcd = gcd;
3530 :
3531 0 : label[j].text = (unichar_t *) _("_X:");
3532 0 : label[j].text_is_1byte = true;
3533 0 : label[j].text_in_resource = true;
3534 0 : gcd[j].gd.label = &label[j];
3535 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3536 0 : gcd[j].creator = GLabelCreate;
3537 0 : harray2[0] = &gcd[j]; harray2[1] = GCD_Glue;
3538 0 : ++j;
3539 :
3540 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-6; gcd[j].gd.pos.width = 70;
3541 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3542 0 : gcd[j].gd.cid = CID_BaseX;
3543 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3544 0 : gcd[j].creator = GNumericFieldCreate;
3545 0 : harray2[2] = &gcd[j]; harray2[3] = GCD_Glue; harray2[4] = GCD_Glue;
3546 0 : ++j;
3547 :
3548 0 : label[j].text = (unichar_t *) _("_Y:");
3549 0 : label[j].text_is_1byte = true;
3550 0 : label[j].text_in_resource = true;
3551 0 : gcd[j].gd.label = &label[j];
3552 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3553 0 : gcd[j].creator = GLabelCreate;
3554 0 : harray2[5] = &gcd[j]; harray2[6] = GCD_Glue;
3555 0 : ++j;
3556 :
3557 0 : gcd[j].gd.pos.x = 137; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y; gcd[j].gd.pos.width = 70;
3558 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3559 0 : gcd[j].gd.cid = CID_BaseY;
3560 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3561 0 : gcd[j].creator = GNumericFieldCreate;
3562 0 : harray2[7] = &gcd[j]; harray2[8] = NULL;
3563 0 : ++j;
3564 :
3565 0 : pb[2].gd.flags = gg_enabled|gg_visible;
3566 0 : pb[2].gd.u.boxelements = harray2;
3567 0 : pb[2].creator = GHBoxCreate;
3568 0 : varray[k++] = &pb[2]; varray[k++] = NULL;
3569 :
3570 0 : label[j].text = (unichar_t *) _("Type:");
3571 0 : label[j].text_is_1byte = true;
3572 0 : gcd[j].gd.label = &label[j];
3573 0 : gcd[j].gd.pos.x = gcd[0].gd.pos.x;
3574 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3575 0 : gcd[j].creator = GLabelCreate;
3576 0 : harray3[0] = &gcd[j]; harray3[1] = GCD_Glue; harray3[2] = GCD_Glue;
3577 0 : ++j;
3578 :
3579 0 : label[j].image = &GIcon_smallspirocurve;
3580 0 : gcd[j].gd.label = &label[j];
3581 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
3582 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3583 0 : gcd[j].gd.cid = CID_Curve;
3584 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3585 0 : gcd[j].creator = GRadioCreate;
3586 0 : harray3[3] = &gcd[j]; harray3[4] = GCD_Glue;
3587 0 : ++j;
3588 :
3589 0 : label[j].image = &GIcon_smallspirog2curve;
3590 0 : gcd[j].gd.label = &label[j];
3591 0 : gcd[j].gd.pos.x = 60; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y-2;
3592 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3593 0 : gcd[j].gd.cid = CID_Tangent;
3594 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3595 0 : gcd[j].creator = GRadioCreate;
3596 0 : harray3[5] = &gcd[j]; harray3[6] = GCD_Glue;
3597 0 : ++j;
3598 :
3599 0 : label[j].image = &GIcon_smallspirocorner;
3600 0 : gcd[j].gd.label = &label[j];
3601 0 : gcd[j].gd.pos.x = 100; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3602 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
3603 0 : gcd[j].gd.cid = CID_Corner;
3604 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3605 0 : gcd[j].creator = GRadioCreate;
3606 0 : harray3[7] = &gcd[j]; harray3[8] = GCD_Glue;
3607 0 : ++j;
3608 :
3609 0 : label[j].image = &GIcon_smallspiroleft;
3610 0 : gcd[j].gd.label = &label[j];
3611 0 : gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3612 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
3613 0 : gcd[j].gd.cid = CID_SpiroLeft;
3614 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3615 0 : gcd[j].creator = GRadioCreate;
3616 0 : harray3[9] = &gcd[j]; harray3[10] = GCD_Glue;
3617 0 : ++j;
3618 :
3619 0 : label[j].image = &GIcon_smallspiroright;
3620 0 : gcd[j].gd.label = &label[j];
3621 0 : gcd[j].gd.pos.x = 140; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y;
3622 0 : gcd[j].gd.flags = gg_enabled|gg_visible | gg_rad_continueold;
3623 0 : gcd[j].gd.cid = CID_SpiroRight;
3624 0 : gcd[j].gd.handle_controlevent = PI_SpiroChanged;
3625 0 : gcd[j].creator = GRadioCreate;
3626 0 : harray3[11] = &gcd[j]; harray3[12] = GCD_Glue; harray3[13] = GCD_Glue;
3627 0 : harray3[14] = NULL;
3628 0 : ++j;
3629 :
3630 0 : pb[3].gd.flags = gg_enabled|gg_visible;
3631 0 : pb[3].gd.u.boxelements = harray3;
3632 0 : pb[3].creator = GHBoxCreate;
3633 0 : varray[k++] = &pb[3];
3634 0 : varray[k++] = NULL;
3635 0 : varray[k++] = GCD_Glue;
3636 0 : varray[k++] = NULL;
3637 :
3638 0 : gcd[j].gd.flags = gg_visible | gg_enabled;
3639 0 : label[j].text = (unichar_t *) _("< _Prev");
3640 0 : label[j].text_is_1byte = true;
3641 0 : label[j].text_in_resource = true;
3642 0 : gcd[j].gd.label = &label[j];
3643 0 : gcd[j].gd.cid = CID_Prev;
3644 0 : gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
3645 0 : gcd[j].creator = GButtonCreate;
3646 0 : harray4[0] = GCD_Glue; harray4[1] = &gcd[j];
3647 0 : ++j;
3648 :
3649 0 : gcd[j].gd.flags = gg_visible | gg_enabled;
3650 0 : label[j].text = (unichar_t *) _("_Next >");
3651 0 : label[j].text_is_1byte = true;
3652 0 : label[j].text_in_resource = true;
3653 0 : gcd[j].gd.label = &label[j];
3654 0 : gcd[j].gd.cid = CID_Next;
3655 0 : gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
3656 0 : gcd[j].creator = GButtonCreate;
3657 0 : harray4[2] = &gcd[j]; harray4[3] = GCD_Glue; harray4[4] = NULL;
3658 0 : ++j;
3659 :
3660 0 : pb[4].gd.flags = gg_enabled|gg_visible;
3661 0 : pb[4].gd.u.boxelements = harray4;
3662 0 : pb[4].creator = GHBoxCreate;
3663 0 : varray[k++] = &pb[4];
3664 0 : varray[k++] = NULL;
3665 :
3666 0 : gcd[j].gd.flags = gg_visible | gg_enabled;
3667 0 : label[j].text = (unichar_t *) _("Prev On Contour");
3668 0 : label[j].text_is_1byte = true;
3669 0 : gcd[j].gd.label = &label[j];
3670 0 : gcd[j].gd.cid = CID_PrevC;
3671 0 : gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
3672 0 : gcd[j].creator = GButtonCreate;
3673 0 : harray5[0] = GCD_Glue; harray5[1] = &gcd[j];
3674 0 : ++j;
3675 :
3676 0 : gcd[j].gd.flags = gg_visible | gg_enabled;
3677 0 : label[j].text = (unichar_t *) _("Next On Contour");
3678 0 : label[j].text_is_1byte = true;
3679 0 : gcd[j].gd.label = &label[j];
3680 0 : gcd[j].gd.cid = CID_NextC;
3681 0 : gcd[j].gd.handle_controlevent = PI_SpiroNextPrev;
3682 0 : gcd[j].creator = GButtonCreate;
3683 0 : harray5[2] = &gcd[j]; harray5[3] = GCD_Glue; harray5[4] = NULL;
3684 0 : ++j;
3685 :
3686 0 : pb[5].gd.flags = gg_enabled|gg_visible;
3687 0 : pb[5].gd.u.boxelements = harray5;
3688 0 : pb[5].creator = GHBoxCreate;
3689 0 : varray[k++] = &pb[5];
3690 0 : varray[k++] = NULL;
3691 :
3692 0 : gcd[j].gd.pos.x = 5; gcd[j].gd.pos.y = gcd[j-1].gd.pos.y+28;
3693 0 : gcd[j].gd.pos.width = PI_Width-10;
3694 0 : gcd[j].gd.flags = gg_enabled|gg_visible;
3695 0 : gcd[j].creator = GLineCreate;
3696 0 : ++j;
3697 0 : varray[k++] = &gcd[j-1];
3698 0 : varray[k++] = NULL;
3699 0 : varray[k++] = GCD_Glue;
3700 0 : varray[k++] = NULL;
3701 :
3702 0 : gcd[j].gd.pos.x = 20-3; gcd[j].gd.pos.y = PI_Height-33-3;
3703 0 : gcd[j].gd.flags = gg_visible | gg_enabled | gg_but_default;
3704 0 : label[j].text = (unichar_t *) _("_OK");
3705 0 : label[j].text_is_1byte = true;
3706 0 : label[j].text_in_resource = true;
3707 0 : gcd[j].gd.mnemonic = 'O';
3708 0 : gcd[j].gd.label = &label[j];
3709 0 : gcd[j].gd.handle_controlevent = PI_SpiroOk;
3710 0 : gcd[j].creator = GButtonCreate;
3711 0 : harray6[0] = GCD_Glue; harray6[1] = &gcd[j]; harray6[2] = GCD_Glue; harray6[3] = GCD_Glue;
3712 0 : ++j;
3713 :
3714 0 : gcd[j].gd.pos.x = -20; gcd[j].gd.pos.y = PI_Height-33;
3715 0 : gcd[j].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
3716 0 : label[j].text = (unichar_t *) _("_Cancel");
3717 0 : label[j].text_is_1byte = true;
3718 0 : label[j].text_in_resource = true;
3719 0 : gcd[j].gd.label = &label[j];
3720 0 : gcd[j].gd.mnemonic = 'C';
3721 0 : gcd[j].gd.handle_controlevent = PI_Cancel;
3722 0 : gcd[j].creator = GButtonCreate;
3723 0 : harray6[4] = GCD_Glue; harray6[5] = &gcd[j]; harray6[6] = GCD_Glue; harray6[7] = NULL;
3724 0 : ++j;
3725 :
3726 0 : pb[6].gd.flags = gg_enabled|gg_visible;
3727 0 : pb[6].gd.u.boxelements = harray6;
3728 0 : pb[6].creator = GHBoxCreate;
3729 0 : varray[k++] = &pb[6];
3730 0 : varray[k++] = NULL;
3731 0 : varray[k++] = NULL;
3732 :
3733 0 : pb[0].gd.pos.x = pb[0].gd.pos.y = 2;
3734 0 : pb[0].gd.flags = gg_enabled|gg_visible;
3735 0 : pb[0].gd.u.boxelements = varray;
3736 0 : pb[0].creator = GHVGroupCreate;
3737 :
3738 0 : GGadgetsCreate(gip->gw,pb);
3739 :
3740 0 : GHVBoxSetExpandableRow(pb[0].ret,gb_expandglue);
3741 0 : GHVBoxSetExpandableCol(pb[2].ret,gb_expandglue);
3742 0 : GHVBoxSetExpandableCol(pb[3].ret,gb_expandglue);
3743 0 : GHVBoxSetExpandableCol(pb[4].ret,gb_expandglue);
3744 0 : GHVBoxSetExpandableCol(pb[5].ret,gb_expandglue);
3745 0 : GHVBoxSetExpandableCol(pb[6].ret,gb_expandgluesame);
3746 :
3747 0 : SpiroChangePoint(gip);
3748 :
3749 0 : GHVBoxFitWindow(pb[0].ret);
3750 :
3751 0 : GWidgetHidePalettes();
3752 0 : GDrawSetVisible(gip->gw,true);
3753 0 : while ( !gip->done )
3754 0 : GDrawProcessOneEvent(NULL);
3755 0 : }
3756 :
3757 0 : void CVGetInfo(CharView *cv) {
3758 : SplinePoint *sp;
3759 : SplinePointList *spl;
3760 : RefChar *ref;
3761 : ImageList *img;
3762 : AnchorPoint *ap;
3763 : spiro_cp *scp;
3764 :
3765 0 : if ( !CVOneThingSel(cv,&sp,&spl,&ref,&img,&ap,&scp)) {
3766 0 : } else if ( ref!=NULL )
3767 0 : RefGetInfo(cv,ref);
3768 0 : else if ( img!=NULL )
3769 0 : ImgGetInfo(cv,img);
3770 0 : else if ( ap!=NULL )
3771 0 : ApGetInfo(cv,ap);
3772 0 : else if ( scp!=NULL )
3773 0 : SpiroPointGetInfo(cv,scp,spl);
3774 : else
3775 0 : PointGetInfo(cv,sp,spl);
3776 0 : }
3777 :
3778 0 : void CVPGetInfo(CharView *cv) {
3779 :
3780 0 : if ( cv->p.ref!=NULL )
3781 0 : RefGetInfo(cv,cv->p.ref);
3782 0 : else if ( cv->p.img!=NULL )
3783 0 : ImgGetInfo(cv,cv->p.img);
3784 0 : else if ( cv->p.ap!=NULL )
3785 0 : ApGetInfo(cv,cv->p.ap);
3786 0 : else if ( cv->p.sp!=NULL )
3787 0 : PointGetInfo(cv,cv->p.sp,cv->p.spl);
3788 0 : else if ( cv->p.spiro!=NULL )
3789 0 : SpiroPointGetInfo(cv,cv->p.spiro,cv->p.spl);
3790 0 : }
3791 :
3792 0 : void SCRefBy(SplineChar *sc) {
3793 0 : int cnt,i,tot=0;
3794 0 : char **deps = NULL;
3795 : struct splinecharlist *d;
3796 : char *buts[3];
3797 :
3798 0 : buts[0] = _("_Show");
3799 0 : buts[1] = _("_Cancel");
3800 0 : buts[2] = NULL;
3801 :
3802 0 : for ( i=0; i<2; ++i ) {
3803 0 : cnt = 0;
3804 0 : for ( d = sc->dependents; d!=NULL; d=d->next ) {
3805 0 : if ( deps!=NULL )
3806 0 : deps[tot-cnt] = copy(d->sc->name);
3807 0 : ++cnt;
3808 : }
3809 0 : if ( cnt==0 )
3810 0 : return;
3811 0 : if ( i==0 )
3812 0 : deps = calloc(cnt+1,sizeof(unichar_t *));
3813 0 : tot = cnt-1;
3814 : }
3815 :
3816 0 : i = gwwv_choose_with_buttons(_("Dependents"),(const char **) deps, cnt, 0, buts, _("Dependents") );
3817 0 : if ( i!=-1 ) {
3818 0 : i = tot-i;
3819 0 : for ( d = sc->dependents, cnt=0; d!=NULL && cnt<i; d=d->next, ++cnt );
3820 0 : CharViewCreate(d->sc,(FontView *) (sc->parent->fv),-1);
3821 : }
3822 0 : for ( i=0; i<=tot; ++i )
3823 0 : free( deps[i] );
3824 0 : free(deps);
3825 : }
3826 :
3827 0 : static int UsedIn(char *name, char *subs) {
3828 0 : int nlen = strlen( name );
3829 0 : while ( *subs!='\0' ) {
3830 0 : if ( strncmp(subs,name,nlen)==0 && (subs[nlen]==' ' || subs[nlen]=='\0'))
3831 0 : return( true );
3832 0 : while ( *subs!=' ' && *subs!='\0' ) ++subs;
3833 0 : while ( *subs==' ' ) ++subs;
3834 : }
3835 0 : return( false );
3836 : }
3837 :
3838 0 : int SCUsedBySubs(SplineChar *sc) {
3839 : int k, i;
3840 : SplineFont *_sf, *sf;
3841 : PST *pst;
3842 :
3843 0 : if ( sc==NULL )
3844 0 : return( false );
3845 :
3846 0 : _sf = sc->parent;
3847 0 : if ( _sf->cidmaster!=NULL ) _sf=_sf->cidmaster;
3848 0 : k=0;
3849 : do {
3850 0 : sf = _sf->subfontcnt==0 ? _sf : _sf->subfonts[k];
3851 0 : for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
3852 0 : for ( pst=sf->glyphs[i]->possub; pst!=NULL; pst=pst->next ) {
3853 0 : if ( pst->type==pst_substitution || pst->type==pst_alternate ||
3854 0 : pst->type==pst_multiple || pst->type==pst_ligature )
3855 0 : if ( UsedIn(sc->name,pst->u.mult.components))
3856 0 : return( true );
3857 : }
3858 : }
3859 0 : ++k;
3860 0 : } while ( k<_sf->subfontcnt );
3861 0 : return( false );
3862 : }
3863 :
3864 0 : void SCSubBy(SplineChar *sc) {
3865 : int i,j,k,tot;
3866 0 : char **deps = NULL;
3867 : SplineChar **depsc;
3868 : char ubuf[200];
3869 : SplineFont *sf, *_sf;
3870 : PST *pst;
3871 : char *buts[3];
3872 :
3873 0 : buts[0] = _("Show");
3874 0 : buts[1] = _("_Cancel");
3875 0 : buts[2] = NULL;
3876 :
3877 0 : if ( sc==NULL )
3878 0 : return;
3879 :
3880 0 : _sf = sc->parent;
3881 0 : if ( _sf->cidmaster!=NULL ) _sf=_sf->cidmaster;
3882 0 : for ( j=0; j<2; ++j ) {
3883 0 : tot = 0;
3884 0 : k=0;
3885 : do {
3886 0 : sf = _sf->subfontcnt==0 ? _sf : _sf->subfonts[k];
3887 0 : for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
3888 0 : for ( pst=sf->glyphs[i]->possub; pst!=NULL; pst=pst->next ) {
3889 0 : if ( pst->type==pst_substitution || pst->type==pst_alternate ||
3890 0 : pst->type==pst_multiple || pst->type==pst_ligature )
3891 0 : if ( UsedIn(sc->name,pst->u.mult.components)) {
3892 0 : if ( deps!=NULL ) {
3893 0 : snprintf(ubuf,sizeof(ubuf),
3894 0 : _("Subtable %.60s in glyph %.60s"),
3895 0 : pst->subtable->subtable_name,
3896 0 : sf->glyphs[i]->name);
3897 0 : deps[tot] = copy(ubuf);
3898 0 : depsc[tot] = sf->glyphs[i];
3899 : }
3900 0 : ++tot;
3901 : }
3902 : }
3903 : }
3904 0 : ++k;
3905 0 : } while ( k<_sf->subfontcnt );
3906 0 : if ( tot==0 )
3907 0 : return;
3908 0 : if ( j==0 ) {
3909 0 : deps = calloc(tot+1,sizeof(char *));
3910 0 : depsc = malloc(tot*sizeof(SplineChar *));
3911 : }
3912 : }
3913 :
3914 0 : i = gwwv_choose_with_buttons(_("Dependent Substitutions"),(const char **) deps, tot, 0, buts, _("Dependent Substitutions") );
3915 0 : if ( i>-1 ) {
3916 0 : CharViewCreate(depsc[i],(FontView *) (sc->parent->fv),-1);
3917 : }
3918 0 : for ( i=0; i<=tot; ++i )
3919 0 : free( deps[i] );
3920 0 : free(deps);
3921 0 : free(depsc);
3922 : }
|