Additional change to avoid querying the cursor position when in
[xcircuit.git] / menucalls.c
blob6bf5375866e9047472308b45f31ab17286b55755
1 /*----------------------------------------------------------------------*/
2 /* menucalls.c --- callback routines from the menu buttons, and */
3 /* associated routines (either Tcl/Tk routines or */
4 /* non-specific; Xt routines split off in file */
5 /* xtfuncs.c 3/28/06) */
6 /* Copyright (c) 2002 Tim Edwards, Johns Hopkins University */
7 /*----------------------------------------------------------------------*/
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <sys/types.h>
14 #include <errno.h>
15 #include <limits.h>
17 #ifndef XC_WIN32
18 #include <X11/Intrinsic.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xutil.h>
21 #endif
23 #ifdef TCL_WRAPPER
24 #include <tk.h>
25 #endif
27 /*----------------------------------------------------------------------*/
28 /* Local includes */
29 /*----------------------------------------------------------------------*/
31 #include "colordefs.h"
32 #include "xcircuit.h"
34 /*----------------------------------------------------------------------*/
35 /* Function prototype declarations */
36 /*----------------------------------------------------------------------*/
37 #include "prototypes.h"
39 /*----------------------------------------------------------------------*/
40 /* External Variable definitions */
41 /*----------------------------------------------------------------------*/
43 extern char _STR2[250];
44 extern char _STR[150]; /* Generic multipurpose string */
45 extern xcWidget top;
46 extern Display *dpy;
47 extern Globaldata xobjs;
48 extern XCWindowData *areawin;
49 extern int number_colors;
50 extern colorindex *colorlist;
51 extern ApplicationData appdata;
52 extern Cursor appcursors[NUM_CURSORS];
53 extern fontinfo *fonts;
54 extern short fontcount;
56 #ifdef TCL_WRAPPER
57 extern Tcl_Interp *xcinterp;
58 #endif
60 /*----------------------------------------------------------------------*/
61 /* Local Variable definitions */
62 /*----------------------------------------------------------------------*/
64 u_short *fontnumbers;
65 u_char nfontnumbers;
67 /*----------------------------------------------*/
68 /* Set Poly and Arc line styles and fill styles */
69 /*----------------------------------------------*/
71 #define BORDERS (NOBORDER | DOTTED | DASHED)
72 #define ALLFILLS (FILLSOLID | FILLED)
74 /*----------------------------------------------------------------*/
75 /* setgrid, getgridspace are for grid and snap spacing sizes; */
76 /* include routines to parse fractions */
77 /*----------------------------------------------------------------*/
79 void setgrid(xcWidget w, float *dataptr)
81 float oldvalue = *dataptr;
82 float oscale, iscale = (float)xobjs.pagelist[areawin->page]->drawingscale.y /
83 (float)xobjs.pagelist[areawin->page]->drawingscale.x;
84 float fval;
86 /* For now, assume that the value is in the current display style. */
87 /* Might be nice in the future to make it accept any input. . . */
89 switch (xobjs.pagelist[areawin->page]->coordstyle) {
90 case INTERNAL:
91 if (sscanf(_STR2, "%f", &fval) == 0) {
92 *dataptr = oldvalue;
93 Wprintf("Illegal value");
95 else *dataptr = fval / iscale;
96 break;
97 case CM:
98 oscale = xobjs.pagelist[areawin->page]->outscale * CMSCALE;
99 if (sscanf(_STR2, "%f", &fval) == 0) {
100 *dataptr = oldvalue;
101 Wprintf("Illegal value");
103 else *dataptr = fval * IN_CM_CONVERT / (iscale * oscale);
104 break;
105 case DEC_INCH: case FRAC_INCH: {
106 short parts;
107 char *sptr;
108 int f2, f3;
110 oscale = xobjs.pagelist[areawin->page]->outscale * INCHSCALE;
111 for (sptr = _STR2; *sptr != '\0'; sptr++)
112 if (*sptr == '/') *sptr = ' ';
113 parts = sscanf(_STR2, "%f %d %d", &fval, &f2, &f3);
114 if ((parts == 0) || (parts != 1 && (fval != (float)((int)fval)))) {
115 *dataptr = oldvalue;
116 Wprintf("Illegal value");
117 break;
119 if (parts == 2) fval /= (float)f2;
120 else if (parts == 3) fval += ((float)f2 / (float)f3);
121 *dataptr = fval * 72.0 / (iscale * oscale);
122 } break;
124 if (oldvalue != *dataptr) drawarea(NULL, NULL, NULL);
127 /*----------------------------------------------------------------*/
128 /* Write a measurement value into string "buffer" dependant on */
129 /* the current default units of measure (centimeters or inches). */
130 /*----------------------------------------------------------------*/
132 void measurestr(float value, char *buffer)
134 float oscale, iscale;
135 iscale = (float)(xobjs.pagelist[areawin->page]->drawingscale.y) /
136 (float)(xobjs.pagelist[areawin->page]->drawingscale.x);
138 switch (xobjs.pagelist[areawin->page]->coordstyle) {
139 case INTERNAL:
140 sprintf(buffer, "%5.3f", value * iscale);
141 break;
142 case CM:
143 oscale = xobjs.pagelist[areawin->page]->outscale * CMSCALE;
144 sprintf(buffer, "%5.3f cm", value * iscale * oscale / IN_CM_CONVERT);
145 break;
146 case DEC_INCH:
147 oscale = xobjs.pagelist[areawin->page]->outscale * INCHSCALE;
148 sprintf(buffer, "%5.3f in", value * iscale * oscale / 72.0);
149 break;
150 case FRAC_INCH:
151 oscale = xobjs.pagelist[areawin->page]->outscale * INCHSCALE;
152 fraccalc(((value * iscale * oscale) / 72.0), buffer);
153 strcat(buffer, " in");
154 break;
158 /*----------------------------------------------------------------*/
159 /* set the global default line width. The unit used internally */
160 /* is twice the value passed through pointer "dataptr". */
161 /*----------------------------------------------------------------*/
163 void setwidth(xcWidget w, float *dataptr)
165 float oldvalue = *dataptr;
166 if (sscanf(_STR2, "%f", dataptr) == 0) {
167 *dataptr = oldvalue;
168 Wprintf("Illegal value");
169 return;
171 (*dataptr) *= 2.0;
172 if (oldvalue != *dataptr) drawarea(NULL, NULL, NULL);
175 /*--------------------------------------------------------------*/
176 /* Set text scale. */
177 /*--------------------------------------------------------------*/
179 void changetextscale(float newscale)
181 short *osel;
182 labelptr settext;
183 stringpart *strptr, *nextptr;
185 /* In edit mode, add font scale change. */
187 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
188 settext = *((labelptr *)EDITPART);
189 if (areawin->textpos > 0 || areawin->textpos < stringlength(settext->string, True,
190 areawin->topinstance)) {
191 undrawtext(settext);
192 strptr = findstringpart(areawin->textpos - 1, NULL, settext->string,
193 areawin->topinstance);
194 nextptr = findstringpart(areawin->textpos, NULL, settext->string,
195 areawin->topinstance);
196 if (strptr->type == FONT_SCALE)
197 strptr->data.scale = newscale;
198 else if (nextptr && nextptr->type == FONT_SCALE)
199 nextptr->data.scale = newscale;
200 else
201 labeltext(FONT_SCALE, (char *)&newscale);
202 redrawtext(settext);
204 else if (stringlength(settext->string, True, areawin->topinstance) > 0)
205 labeltext(FONT_SCALE, (char *)&newscale);
206 else (settext->scale = newscale);
209 /* Change scale on all selected text objects */
211 else if (areawin->selects > 0) {
212 float oldscale;
213 Boolean waschanged = FALSE;
214 for (osel = areawin->selectlist; osel < areawin->selectlist +
215 areawin->selects; osel++) {
216 if (SELECTTYPE(osel) == LABEL) {
217 settext = SELTOLABEL(osel);
218 oldscale = settext->scale;
219 if (oldscale != newscale) {
220 undrawtext(settext);
221 settext->scale = newscale;
222 redrawtext(settext);
223 register_for_undo(XCF_Rescale, UNDO_MORE, areawin->topinstance,
224 (genericptr)settext, (double)oldscale);
225 waschanged = TRUE;
229 if (waschanged) undo_finish_series();
233 /*--------------------------------------------------------------*/
234 /* Auto-scale the drawing to fit the declared page size. */
235 /* */
236 /* If the page is declared encapsulated, then do nothing. */
237 /* If a frame box is on the page, then scale to fit the frame */
238 /* to the declared page size, not the whole object. */
239 /*--------------------------------------------------------------*/
241 void autoscale(int page)
243 float newxscale, newyscale;
244 float scalefudge = (xobjs.pagelist[page]->coordstyle
245 == CM) ? CMSCALE : INCHSCALE;
246 int width, height;
247 polyptr framebox;
249 /* Check if auto-fit flag is selected */
250 if (!(xobjs.pagelist[page]->pmode & 2)) return;
251 /* Ignore auto-fit flag in EPS mode */
252 if (!(xobjs.pagelist[page]->pmode & 1)) return;
254 else if (topobject->bbox.width == 0 || topobject->bbox.height == 0) {
255 // Wprintf("Cannot auto-fit empty page");
256 return;
259 newxscale = (xobjs.pagelist[page]->pagesize.x -
260 (2 * xobjs.pagelist[page]->margins.x)) / scalefudge;
261 newyscale = (xobjs.pagelist[page]->pagesize.y -
262 (2 * xobjs.pagelist[page]->margins.y)) / scalefudge;
264 if ((framebox = checkforbbox(topobject)) != NULL) {
265 int i, minx, miny, maxx, maxy;
267 minx = maxx = framebox->points[0].x;
268 miny = maxy = framebox->points[0].y;
269 for (i = 1; i < framebox->number; i++) {
270 if (framebox->points[i].x < minx) minx = framebox->points[i].x;
271 else if (framebox->points[i].x > maxx) maxx = framebox->points[i].x;
272 if (framebox->points[i].y < miny) miny = framebox->points[i].y;
273 else if (framebox->points[i].y > maxy) maxy = framebox->points[i].y;
275 width = (maxx - minx);
276 height = (maxy - miny);
278 else {
280 width = toplevelwidth(areawin->topinstance, NULL);
281 height = toplevelheight(areawin->topinstance, NULL);
284 if (xobjs.pagelist[page]->orient == 0) { /* Portrait */
285 newxscale /= width;
286 newyscale /= height;
288 else {
289 newxscale /= height;
290 newyscale /= width;
292 xobjs.pagelist[page]->outscale = min(newxscale, newyscale);
295 /*--------------------------------------------------------------*/
296 /* Parse a string for possible units of measure. Convert to */
297 /* current units of measure, if necessary. Return the value */
298 /* in current units, as a type float. */
299 /*--------------------------------------------------------------*/
301 float parseunits(char *strptr)
303 short curtype;
304 Boolean inchunits = True;
305 float pv;
306 char units[12];
308 curtype = xobjs.pagelist[areawin->page]->coordstyle;
310 if (sscanf(strptr, "%f %11s", &pv, units) < 2)
311 return pv;
312 else {
313 if (!strncmp(units, "cm", 2) || !strncmp(units, "centimeters", 11))
314 inchunits = False;
315 switch(curtype) {
316 case CM:
317 return ((inchunits) ? (pv * 2.54) : pv);
318 default:
319 return ((inchunits) ? pv : (pv / 2.54));
324 /*--------------------------------------------------------------*/
325 /* Set the output page size, in the current unit of measure */
326 /* Return value: TRUE if _STR2 values were in inches, FALSE */
327 /* if in centimeters. */
328 /* XXX This API gives no good way to signal errors. */
329 /*--------------------------------------------------------------*/
331 Boolean setoutputpagesize(XPoint *dataptr)
333 float px, py;
334 char units[10], *expos;
335 #ifndef TCL_WRAPPER
336 Arg wargs[1];
337 #endif
339 strcpy(units, "in");
341 if (sscanf(_STR2, "%f %*c %f %9s", &px, &py, units) < 4) {
342 if (sscanf(_STR2, "%f %*c %f", &px, &py) < 3) {
343 if ((expos = strchr(_STR2, 'x')) == NULL) {
344 Wprintf("Illegal Form for page size.");
345 return FALSE;
347 else {
348 *expos = '\0';
349 if (sscanf(_STR2, "%f", &px) == 0 ||
350 sscanf(expos + 1, "%f %9s", &py, units) == 0) {
351 Wprintf("Illegal Form for page size.");
352 return FALSE;
358 /* Don't reduce page to less than the margins (1") or negative */
359 /* scales result. */
361 if ((px <= 2.0) || (py <= 2.0)) {
362 Wprintf("Page size too small for margins.");
363 return FALSE;
366 dataptr->x = (short)(px * 72.0);
367 dataptr->y = (short)(py * 72.0);
369 if (!strcmp(units, "cm")) {
370 dataptr->x /= 2.54;
371 dataptr->y /= 2.54;
372 return FALSE;
374 return TRUE;
377 /*--------------------------------------------------------------*/
378 /* Get the text size (global or selected, depending on mode */
379 /*--------------------------------------------------------------*/
381 labelptr gettextsize(float **floatptr)
383 labelptr settext = NULL;
384 short *osel;
385 stringpart *strptr, *nextptr;
386 const float f_one = 1.00;
388 if (floatptr) *floatptr = &areawin->textscale;
390 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
391 if (areawin->textpos > 0 || areawin->textpos < stringlength(settext->string,
392 True, areawin->topinstance)) {
393 settext = *((labelptr *)EDITPART);
394 strptr = findstringpart(areawin->textpos - 1, NULL, settext->string,
395 areawin->topinstance);
396 nextptr = findstringpart(areawin->textpos, NULL, settext->string,
397 areawin->topinstance);
398 if (strptr->type == FONT_SCALE) {
399 if (floatptr) *floatptr = &strptr->data.scale;
401 else if (nextptr && nextptr->type == FONT_SCALE) {
402 if (floatptr) *floatptr = &nextptr->data.scale;
404 else if (floatptr) *floatptr = (float *)(&f_one);
406 else {
407 settext = *((labelptr *)EDITPART);
408 if (floatptr) *floatptr = &(settext->scale);
411 else if (areawin->selects > 0) {
412 for (osel = areawin->selectlist; osel < areawin->selectlist +
413 areawin->selects; osel++) {
414 if (SELECTTYPE(osel) == LABEL) {
415 settext = SELTOLABEL(osel);
416 if (floatptr) *floatptr = &(settext->scale);
417 break;
421 return settext;
424 /*--------------------------------------------------------------*/
425 /* Set a character kern value */
426 /*--------------------------------------------------------------*/
428 void setkern(xcWidget w, stringpart *kpart)
430 char *sptr;
431 short kd[2];
433 kd[0] = kd[1] = 0;
435 if ((sptr = strchr(_STR2, ',')) == NULL)
436 Wprintf("Use notation X,Y");
437 else {
438 *sptr = '\0';
439 sscanf(_STR2, "%hd", &kd[0]);
440 sscanf(sptr + 1, "%hd", &kd[1]);
441 if (kpart == NULL)
442 labeltext(KERN, (char *)kd);
443 else {
444 labelptr curlabel = TOLABEL(EDITPART);
445 undrawtext(curlabel);
446 kpart->data.kern[0] = kd[0];
447 kpart->data.kern[1] = kd[1];
448 redrawtext(curlabel);
453 /*----------------------------------------------------------------*/
454 /* Set the drawing scale (specified as ratio X:Y) */
455 /*----------------------------------------------------------------*/
457 void setdscale(xcWidget w, XPoint *dataptr)
459 char *sptr;
461 if ((sptr = strchr(_STR2, ':')) == NULL)
462 Wprintf("Use ratio X:Y");
463 else {
464 *sptr = '\0';
465 sscanf(_STR2, "%hd", &(dataptr->x));
466 sscanf(sptr + 1, "%hd", &(dataptr->y));
467 Wprintf("New scale is %hd:%hd", dataptr->x, dataptr->y);
468 W1printf(" ");
472 /*----------------------------------------------------------------*/
473 /* Set the scale of an object or group of selected objects */
474 /*----------------------------------------------------------------*/
476 void setosize(xcWidget w, objinstptr dataptr)
478 float tmpres, oldsize;
479 Boolean waschanged = FALSE;
480 short *osel;
481 objinstptr nsobj;
482 int res = sscanf(_STR2, "%f", &tmpres);
484 // Negative values are flips---deal with them independently
486 if (tmpres < 0)
487 tmpres = -tmpres;
489 if (res == 0 || tmpres == 0) {
490 Wprintf("Illegal value");
491 return;
493 for (osel = areawin->selectlist; osel < areawin->selectlist +
494 areawin->selects; osel++) {
495 if (SELECTTYPE(osel) == OBJINST) {
496 nsobj = SELTOOBJINST(osel);
497 oldsize = nsobj->scale;
498 nsobj->scale = (oldsize < 0) ? -tmpres : tmpres;
500 if (oldsize != tmpres) {
501 register_for_undo(XCF_Rescale, UNDO_MORE, areawin->topinstance,
502 SELTOGENERIC(osel), (double)oldsize);
503 waschanged = TRUE;
507 /* unselect_all(); */
508 if (waschanged) undo_finish_series();
509 pwriteback(areawin->topinstance);
510 drawarea(NULL, NULL, NULL);
513 /*----------------------------------------------------------------*/
514 /* Set the linewidth of all selected arcs, polygons, splines, and */
515 /* paths. */
516 /*----------------------------------------------------------------*/
518 void setwwidth(xcWidget w, void *dataptr)
520 float tmpres, oldwidth;
521 short *osel;
522 arcptr nsarc;
523 polyptr nspoly;
524 splineptr nsspline;
525 pathptr nspath;
527 if (sscanf(_STR2, "%f", &tmpres) == 0) {
528 Wprintf("Illegal value");
529 return;
531 else if (areawin->selects == 0) {
532 areawin->linewidth = tmpres;
534 else {
535 for (osel = areawin->selectlist; osel < areawin->selectlist +
536 areawin->selects; osel++) {
537 if (SELECTTYPE(osel) == ARC) {
538 nsarc = SELTOARC(osel);
539 oldwidth = nsarc->width;
540 nsarc->width = tmpres;
542 else if (SELECTTYPE(osel) == POLYGON) {
543 nspoly = SELTOPOLY(osel);
544 oldwidth = nspoly->width;
545 nspoly->width = tmpres;
547 else if (SELECTTYPE(osel) == SPLINE) {
548 nsspline = SELTOSPLINE(osel);
549 oldwidth = nsspline->width;
550 nsspline->width = tmpres;
552 else if (SELECTTYPE(osel) == PATH) {
553 nspath = SELTOPATH(osel);
554 oldwidth = nspath->width;
555 nspath->width = tmpres;
558 if (oldwidth != tmpres)
559 register_for_undo(XCF_Rescale, UNDO_MORE, areawin->topinstance,
560 SELTOGENERIC(osel), (double)oldwidth);
562 unselect_all();
563 pwriteback(areawin->topinstance);
564 drawarea(NULL, NULL, NULL);
568 /*--------------------------------------------------------------*/
569 /* Add a new font name to the list of known fonts */
570 /* Register the font number for the Alt-F cycling mechanism */
571 /* Tcl: depends on command tag mechanism for GUI menu update. */
572 /*--------------------------------------------------------------*/
574 #ifdef TCL_WRAPPER
576 void makenewfontbutton()
578 nfontnumbers++;
579 if (nfontnumbers == 1)
580 fontnumbers = (u_short *)malloc(sizeof(u_short));
581 else
582 fontnumbers = (u_short *)realloc(fontnumbers, nfontnumbers
583 * sizeof(u_short));
584 fontnumbers[nfontnumbers - 1] = fontcount - 1;
587 #endif /* TCL_WRAPPER */
589 /*---------------------------------------------------------------*/
590 /* Some Xcircuit routines using toggle and toggleexcl, */
591 /* put here because they reference the menu structures directly. */
592 /* */
593 /* Note that by bypassing addnewcolorentry(), the new colors in */
594 /* colorlist are NOT added to the GUI list of colors. */
595 /*---------------------------------------------------------------*/
597 void setcolorscheme(Boolean boolvalue)
599 int i;
601 if (boolvalue) {
602 colorlist[PARAMCOLOR].color.pixel = appdata.parampix;
603 colorlist[AUXCOLOR].color.pixel = appdata.auxpix;
604 colorlist[OFFBUTTONCOLOR].color.pixel = appdata.buttonpix;
605 colorlist[SELECTCOLOR].color.pixel = appdata.selectpix;
606 colorlist[GRIDCOLOR].color.pixel = appdata.gridpix;
607 colorlist[SNAPCOLOR].color.pixel = appdata.snappix;
608 colorlist[AXESCOLOR].color.pixel = appdata.axespix;
609 colorlist[BACKGROUND].color.pixel = appdata.bg;
610 colorlist[FOREGROUND].color.pixel = appdata.fg;
612 else {
613 colorlist[PARAMCOLOR].color.pixel = appdata.parampix2;
614 colorlist[AUXCOLOR].color.pixel = appdata.auxpix2;
615 colorlist[OFFBUTTONCOLOR].color.pixel = appdata.buttonpix2;
616 colorlist[SELECTCOLOR].color.pixel = appdata.selectpix2;
617 colorlist[GRIDCOLOR].color.pixel = appdata.gridpix2;
618 colorlist[SNAPCOLOR].color.pixel = appdata.snappix2;
619 colorlist[AXESCOLOR].color.pixel = appdata.axespix2;
620 colorlist[BACKGROUND].color.pixel = appdata.bg2;
621 colorlist[FOREGROUND].color.pixel = appdata.fg2;
624 colorlist[BARCOLOR].color.pixel = appdata.barpix;
625 colorlist[FILTERCOLOR].color.pixel = appdata.filterpix;
627 colorlist[LOCALPINCOLOR].color.pixel = appdata.localcolor;
628 colorlist[GLOBALPINCOLOR].color.pixel = appdata.globalcolor;
629 colorlist[INFOLABELCOLOR].color.pixel = appdata.infocolor;
630 colorlist[RATSNESTCOLOR].color.pixel = appdata.ratsnestcolor;
631 colorlist[BBOXCOLOR].color.pixel = appdata.bboxpix;
632 colorlist[CLIPMASKCOLOR].color.pixel = appdata.clipcolor;
633 colorlist[FIXEDBBOXCOLOR].color.pixel = appdata.fixedbboxpix;
635 /* Fill in pixel information */
637 for (i = 0; i < NUMBER_OF_COLORS; i++) {
638 unsigned short r, g, b;
640 /* Get the color the hard way by querying the X server colormap */
641 xc_get_color_rgb(colorlist[i].color.pixel, &r, &g, &b);
643 /* Store this information locally so we don't have to do */
644 /* the lookup the hard way in the future. */
646 colorlist[i].color.red = r;
647 colorlist[i].color.green = g;
648 colorlist[i].color.blue = b;
650 areawin->redraw_needed = True;
651 drawarea(NULL, NULL, NULL);
654 /*----------------------------------------------------------------*/
655 /* Change menu selection for reported measurement units */
656 /*----------------------------------------------------------------*/
658 #ifdef TCL_WRAPPER
660 void togglegrid(u_short type)
662 static char *stylenames[] = {
663 "decimal inches",
664 "fractional inches",
665 "centimeters",
666 "internal units", NULL
669 XcInternalTagCall(xcinterp, 3, "config", "coordstyle", stylenames[type]);
672 #endif /* TCL_WRAPPER */
674 /*----------------------------------------------------------------*/
675 /* Called by setgridtype() to complete setting the reported */
676 /* measurement units */
677 /*----------------------------------------------------------------*/
679 void getgridtype(xcWidget button, pointertype value, caddr_t calldata)
681 short oldtype = xobjs.pagelist[areawin->page]->coordstyle;
682 float scalefac = getpsscale(1.0, areawin->page) / INCHSCALE;
684 #ifndef TCL_WRAPPER
685 togglegridstyles(button);
686 #endif
687 xobjs.pagelist[areawin->page]->coordstyle = (short)value;
689 switch(value) {
690 case FRAC_INCH: case DEC_INCH: case INTERNAL:
691 if (oldtype == CM) {
692 xobjs.pagelist[areawin->page]->outscale *= scalefac;
693 #ifndef TCL_WRAPPER
694 /* Note: Tcl defines a method for selecting standard */
695 /* page sizes. We really DON'T want to reset the size */
696 /* just because we switched measurement formats! */
698 xobjs.pagelist[areawin->page]->pagesize.x = 612;
699 xobjs.pagelist[areawin->page]->pagesize.y = 792; /* letter */
700 #endif
702 break;
703 case CM:
704 if (oldtype != CM) {
705 xobjs.pagelist[areawin->page]->outscale *= scalefac;
706 #ifndef TCL_WRAPPER
707 xobjs.pagelist[areawin->page]->pagesize.x = 595;
708 xobjs.pagelist[areawin->page]->pagesize.y = 842; /* A4 */
709 #endif
711 break;
713 if (oldtype != xobjs.pagelist[areawin->page]->coordstyle) {
714 drawarea(NULL, NULL, NULL);
715 W1printf(" ");
719 /*------------------------------------------------------*/
720 /* Make new library, add new button to the "Libraries" */
721 /* cascaded menu, compose the library page, update the */
722 /* library directory, and go to that library page. */
723 /*------------------------------------------------------*/
725 void newlibrary(xcWidget w, caddr_t clientdata, caddr_t calldata)
727 int libnum = createlibrary(FALSE);
728 startcatalog(w, libnum, NULL);
731 /*----------------------------------------------*/
732 /* Find an empty library, and return its page */
733 /* number if it exists. Otherwise, return -1. */
734 /* This search does not include the so-called */
735 /* "User Library" (last library in list). */
736 /*----------------------------------------------*/
738 int findemptylib()
740 int i;
742 for (i = 0; i < xobjs.numlibs - 1; i++) {
743 if (xobjs.userlibs[i].number == 0)
744 return i;
746 return -1;
749 /*----------------------------------------------*/
750 /* Make new page; goto that page */
751 /* (wrapper for routine events.c:newpage()) */
752 /*----------------------------------------------*/
754 void newpagemenu(xcWidget w, pointertype value, caddr_t nulldata)
756 newpage((short)value);
759 #ifdef TCL_WRAPPER
761 /*----------------------------------------------*/
762 /* Make new library and add a new button to the */
763 /* "Libraries" cascaded menu. */
764 /*----------------------------------------------*/
766 int createlibrary(Boolean force)
768 /* xcWidget libmenu, newbutton, oldbutton; (jdk) */
769 #ifndef TCL_WRAPPER
770 Arg wargs[2];
771 #endif
772 /* char libstring[20]; (jdk) */
773 int libnum;
774 objectptr newlibobj;
776 /* If there's an empty library, return its number */
777 if ((!force) && (libnum = findemptylib()) >= 0) return (libnum + LIBRARY);
778 libnum = (xobjs.numlibs++) + LIBRARY;
779 xobjs.libtop = (objinstptr *)realloc(xobjs.libtop,
780 (libnum + 1) * sizeof(objinstptr));
781 xobjs.libtop[libnum] = xobjs.libtop[libnum - 1];
782 libnum--;
784 newlibobj = (objectptr) malloc(sizeof(object));
785 initmem(newlibobj);
786 xobjs.libtop[libnum] = newpageinst(newlibobj);
788 sprintf(newlibobj->name, "Library %d", libnum - LIBRARY + 1);
790 /* Create the library */
792 xobjs.userlibs = (Library *) realloc(xobjs.userlibs, xobjs.numlibs
793 * sizeof(Library));
794 xobjs.userlibs[libnum + 1 - LIBRARY] = xobjs.userlibs[libnum - LIBRARY];
795 xobjs.userlibs[libnum - LIBRARY].library = (objectptr *) malloc(sizeof(objectptr));
796 xobjs.userlibs[libnum - LIBRARY].number = 0;
797 xobjs.userlibs[libnum - LIBRARY].instlist = NULL;
799 sprintf(_STR2, "xcircuit::newlibrarybutton \"%s\"", newlibobj->name);
800 Tcl_Eval(xcinterp, _STR2);
802 /* Update the library directory to include the new page */
804 composelib(LIBLIB);
806 return libnum;
809 /*--------------------------------------------------------------*/
810 /* Routine called by newpage() if new button needs to be made */
811 /* to add to the "Pages" cascaded menu. */
812 /*--------------------------------------------------------------*/
814 void makepagebutton()
816 /* xcWidget pagemenu, newbutton; (jdk) */
817 /* char pagestring[10]; (jdk) */
819 /* make new entry in the menu */
821 sprintf(_STR2, "newpagebutton \"Page %d\"", xobjs.pages);
822 Tcl_Eval(xcinterp, _STR2);
824 /* Update the page directory */
826 composelib(PAGELIB);
829 /*----------------------------------------------------------------*/
830 /* Find the Page menu button associated with the page number */
831 /* (passed parameter) and set the label of that button to the */
832 /* object name (= page label) */
833 /*----------------------------------------------------------------*/
835 void renamepage(short pagenumber)
837 objinstptr thisinst = xobjs.pagelist[pagenumber]->pageinst;
838 char *pname, *plabel;
840 if ((pagenumber >= 0) && (pagenumber < xobjs.pages - 1) &&
841 (thisinst != NULL)) {
842 plabel = thisinst->thisobject->name;
843 pname = (char *)malloc(36 + strlen(plabel));
844 sprintf(pname, "catch {xcircuit::renamepage %d {%s}}", pagenumber + 1, plabel);
845 Tcl_Eval(xcinterp, pname);
846 free(pname);
850 /*--------------------------------------------------------------*/
851 /* Same routine as above, for Library page menu buttons */
852 /*--------------------------------------------------------------*/
854 void renamelib(short libnumber)
856 if (libnumber <= xobjs.numlibs) return;
858 sprintf(_STR2, "xcircuit::renamelib %d \"%s\"", libnumber - LIBRARY + 1,
859 xobjs.libtop[libnumber]->thisobject->name);
860 Tcl_Eval(xcinterp, _STR2);
863 /*--------------------------------------------------------------*/
864 /* Set the menu checkmarks on the color menu */
865 /*--------------------------------------------------------------*/
867 void setcolormark(int colorval)
869 /* Set GUI variables and execute any command tags associated */
870 /* with the "color" command */
872 #ifdef TCL_WRAPPER
873 char cstr[6];
875 if (colorval != DEFAULTCOLOR)
876 sprintf(cstr, "%5d", colorval);
878 XcInternalTagCall(xcinterp, 3, "color", "set", (colorval == DEFAULTCOLOR) ?
879 "inherit" : cstr);
880 #endif
883 /*----------------------------------------------------------------*/
884 /* Set the checkmarks on the element styles menu */
885 /*----------------------------------------------------------------*/
887 void setallstylemarks(u_short styleval)
889 /* Execute any command tags associated */
890 /* with the "fill" and "border" commands. */
892 char fstr[10];
893 int fillfactor;
894 const char *bptr;
896 const char *borders[] = {"solid", "unbordered", "dashed", "dotted", NULL};
897 enum BorderIdx { SolidIdx, UnborderedIdx, DashedIdx, DottedIdx };
899 if (styleval & FILLED) {
900 fillfactor = (int)(12.5 * (float)(1 + ((styleval & FILLSOLID) >> 5)));
901 if (fillfactor < 100)
902 sprintf(fstr, "%d", fillfactor);
903 else
904 strcpy(fstr, "solid");
906 else
907 strcpy(fstr, "unfilled");
909 switch (styleval & BORDERS) {
910 case DASHED:
911 bptr = borders[DashedIdx];
912 break;
913 case DOTTED:
914 bptr = borders[DottedIdx];
915 break;
916 case NOBORDER:
917 bptr = borders[UnborderedIdx];
918 break;
919 default:
920 bptr = borders[SolidIdx];
921 break;
924 XcInternalTagCall(xcinterp, 3, "fill", fstr,
925 (styleval & OPAQUE) ? "opaque" : "transparent");
926 XcInternalTagCall(xcinterp, 3, "border", "bbox", (styleval & BBOX) ? "true" :
927 "false");
928 XcInternalTagCall(xcinterp, 3, "border", "clipmask", (styleval & CLIPMASK) ?
929 "true" : "false");
930 XcInternalTagCall(xcinterp, 2, "border", (styleval & UNCLOSED) ? "unclosed" :
931 "closed");
932 XcInternalTagCall(xcinterp, 2, "border", bptr);
935 #endif /* TCL_WRAPPER */
937 /*--------------------------------------------------------------*/
938 /* Check for a bounding box polygon */
939 /*--------------------------------------------------------------*/
941 polyptr checkforbbox(objectptr localdata)
943 polyptr *cbbox;
945 for (cbbox = (polyptr *)localdata->plist; cbbox <
946 (polyptr *)localdata->plist + localdata->parts; cbbox++)
947 if (IS_POLYGON(*cbbox))
948 if ((*cbbox)->style & BBOX) return *cbbox;
950 return NULL;
953 /*--------------------------------------------------------------*/
954 /* Set a value for element style. "Mask" determines the bits */
955 /* to be affected, so that "value" may turn bits either on or */
956 /* off. */
957 /*--------------------------------------------------------------*/
959 int setelementstyle(xcWidget w, u_short value, u_short mask)
961 Boolean preselected, selected = False;
962 short *sstyle;
963 u_short newstyle, oldstyle;
965 if (areawin->selects == 0) {
966 preselected = FALSE;
967 if (value & BBOX)
968 checkselect(POLYGON);
969 else
970 checkselect(ARC | SPLINE | POLYGON | PATH);
972 else preselected = TRUE;
974 if (areawin->selects > 0) {
975 if (value & BBOX) {
976 polyptr ckp;
977 if (areawin->selects != 1) {
978 Wprintf("Choose only one polygon to be the bounding box");
979 return -1;
981 else if (SELECTTYPE(areawin->selectlist) != POLYGON) {
982 Wprintf("Bounding box can only be a polygon");
983 return -1;
985 else if (((ckp = checkforbbox(topobject)) != NULL) &&
986 (ckp != SELTOPOLY(areawin->selectlist))) {
987 Wprintf("Only one bounding box allowed per page");
988 return -1;
992 for (sstyle = areawin->selectlist; sstyle < areawin->selectlist
993 + areawin->selects; sstyle++) {
994 short stype = SELECTTYPE(sstyle);
995 if (stype & (ARC | POLYGON | SPLINE | PATH)) {
996 short *estyle;
997 switch (stype) {
998 case ARC:
999 estyle = &((SELTOARC(sstyle))->style);
1000 break;
1001 case SPLINE:
1002 estyle = &((SELTOSPLINE(sstyle))->style);
1003 break;
1004 case POLYGON:
1005 estyle = &((SELTOPOLY(sstyle))->style);
1006 break;
1007 case PATH:
1008 estyle = &((SELTOPATH(sstyle))->style);
1009 break;
1011 oldstyle = newstyle = *estyle;
1012 newstyle &= ~(mask);
1013 newstyle |= value;
1015 if (oldstyle != newstyle) {
1016 if ((newstyle & NOBORDER) && !(newstyle & FILLED)) {
1017 Wprintf("Must have either a border or filler");
1018 continue;
1021 SetForeground(dpy, areawin->gc, BACKGROUND);
1022 easydraw(*sstyle, DOFORALL);
1024 *estyle = newstyle;
1025 if (mask & BBOX)
1026 (SELTOPOLY(sstyle))->color = (value & BBOX) ? BBOXCOLOR
1027 : DEFAULTCOLOR;
1029 SetForeground(dpy, areawin->gc, SELECTCOLOR);
1030 easydraw(*sstyle, DOFORALL);
1032 #ifdef TCL_WRAPPER
1033 register_for_undo(XCF_ChangeStyle,
1034 (sstyle == areawin->selectlist + areawin->selects - 1) ?
1035 UNDO_DONE : UNDO_MORE, areawin->topinstance,
1036 SELTOGENERIC(sstyle), (int)oldstyle);
1037 #else
1038 /* Tcl version differs in that the element is not deselected after */
1040 register_for_undo(XCF_ChangeStyle, UNDO_MORE, areawin->topinstance,
1041 SELTOGENERIC(sstyle), (int)oldstyle);
1042 #endif
1044 selected = True;
1048 if (selected)
1049 pwriteback(areawin->topinstance);
1050 else {
1051 newstyle = areawin->style;
1052 if (value & BBOX) {
1053 Wprintf("Cannot set default style to Bounding Box");
1054 newstyle &= ~(BBOX);
1055 return -1;
1057 else if (value & CLIPMASK) {
1058 Wprintf("Cannot set default style to Clip Mask");
1059 newstyle &= ~(CLIPMASK);
1060 return -1;
1062 else {
1063 newstyle &= ~mask;
1064 newstyle |= value;
1067 if ((newstyle & NOBORDER) && !(newstyle & FILLED)) {
1068 Wprintf("Must have either a border or filler");
1069 return -1;
1071 areawin->style = newstyle;
1072 #ifndef TCL_WRAPPER
1073 overdrawpixmap(w);
1074 #endif
1076 #ifndef TCL_WRAPPER
1077 setallstylemarks(newstyle);
1078 #endif
1079 if (!preselected)
1080 unselect_all();
1082 return (int)newstyle;
1085 /*-----------------------------------------------*/
1086 /* Set the color value for all selected elements */
1087 /*-----------------------------------------------*/
1089 #ifdef TCL_WRAPPER
1091 void setcolor(xcWidget w, int cindex)
1093 short *scolor;
1094 int *ecolor, oldcolor;
1095 Boolean selected = False;
1096 stringpart *strptr, *nextptr;
1098 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1099 labelptr curlabel = TOLABEL(EDITPART);
1100 strptr = findstringpart(areawin->textpos - 1, NULL, curlabel->string,
1101 areawin->topinstance);
1102 nextptr = findstringpart(areawin->textpos, NULL, curlabel->string,
1103 areawin->topinstance);
1104 if (strptr && strptr->type == FONT_COLOR) {
1105 undrawtext(curlabel);
1106 strptr->data.color = cindex;
1107 redrawtext(curlabel);
1109 else if (nextptr && nextptr->type == FONT_COLOR) {
1110 undrawtext(curlabel);
1111 nextptr->data.color = cindex;
1112 redrawtext(curlabel);
1114 else {
1115 sprintf(_STR2, "%d", cindex);
1116 labeltext(FONT_COLOR, (char *)&cindex);
1120 else if (areawin->selects > 0) {
1121 for (scolor = areawin->selectlist; scolor < areawin->selectlist
1122 + areawin->selects; scolor++) {
1123 ecolor = &(SELTOCOLOR(scolor));
1124 oldcolor = *ecolor;
1125 *ecolor = cindex;
1126 selected = True;
1128 register_for_undo(XCF_Color, (scolor == areawin->selectlist
1129 + areawin->selects - 1) ? UNDO_DONE : UNDO_MORE,
1130 areawin->topinstance,
1131 SELTOGENERIC(scolor), (int)oldcolor);
1135 setcolormark(cindex);
1136 if (!selected) {
1137 if (eventmode != TEXT_MODE && eventmode != ETEXT_MODE)
1138 areawin->color = cindex;
1140 else pwriteback(areawin->topinstance);
1143 /*--------------------------------------------------------------*/
1144 /* Set the menu checkmarks on the font menu */
1145 /*--------------------------------------------------------------*/
1147 void togglefontmark(int fontval)
1149 if (fonts[fontval].family != NULL)
1150 XcInternalTagCall(xcinterp, 3, "label", "family", fonts[fontval].family);
1153 /*------------------------------------------------------*/
1154 /* Set checkmarks on label style menu */
1155 /* fvalue is for font, jvalue is for anchoring */
1156 /*------------------------------------------------------*/
1158 void togglestylemark(int styleval)
1160 char *cstyle = translatestyle(styleval);
1161 if (cstyle != NULL)
1162 XcInternalTagCall(xcinterp, 3, "label", "style", cstyle);
1165 /*------------------------------------------------------*/
1166 /* Set checkmarks on label encoding menu */
1167 /*------------------------------------------------------*/
1169 void toggleencodingmark(int encodingval)
1171 char *cenc = translateencoding(encodingval);
1172 if (cenc != NULL)
1173 XcInternalTagCall(xcinterp, 3, "label", "encoding", cenc);
1176 /*------------------------------------------------------*/
1177 /* Set checkmarks on label anchoring & flags menu */
1178 /*------------------------------------------------------*/
1180 void toggleanchormarks(int anchorvalue)
1182 XcInternalTagCall(xcinterp, 4, "label", "anchor", (anchorvalue & RIGHT) ? "right" :
1183 (anchorvalue & NOTLEFT) ? "center" : "left",
1184 (anchorvalue & TOP) ? "top" : (anchorvalue & NOTBOTTOM) ? "middle" : "bottom");
1185 XcInternalTagCall(xcinterp, 3, "label", "justify", (anchorvalue & JUSTIFYRIGHT) ?
1186 "right" : (anchorvalue & TEXTCENTERED) ? "center" : (anchorvalue & JUSTIFYBOTH)
1187 ? "both" : "left");
1188 XcInternalTagCall(xcinterp, 3, "label", "flipinvariant", (anchorvalue & FLIPINV) ?
1189 "true" : "false");
1190 XcInternalTagCall(xcinterp, 3, "label", "latex", (anchorvalue & LATEXLABEL) ?
1191 "true" : "false");
1192 XcInternalTagCall(xcinterp, 3, "label", "visible", (anchorvalue & PINVISIBLE) ?
1193 "true" : "false");
1196 /*-------------------------------------------------------------*/
1197 /* Simultaneously set all relevant checkmarks for a text label */
1198 /*-------------------------------------------------------------*/
1200 void setfontmarks(short fvalue, short jvalue)
1202 if ((fvalue >= 0) && (fvalue < fontcount)) {
1203 toggleencodingmark(fvalue);
1204 togglestylemark(fvalue);
1205 togglefontmark(fvalue);
1207 toggleanchormarks(jvalue);
1210 #endif /* TCL_WRAPPER */
1212 /*--------------------------------------------------------------*/
1213 /* Parameterize a label string (wrapper for parameterize()). */
1214 /* Assumes that the name has been generated by the popup prompt */
1215 /* and is therefore held in variable _STR2 */
1216 /*--------------------------------------------------------------*/
1218 void stringparam(xcWidget w, caddr_t clientdata, caddr_t calldata)
1220 genericptr *settext;
1222 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1223 settext = (genericptr *)EDITPART;
1224 makeparam(TOLABEL(settext), _STR2);
1225 unselect_all();
1226 setparammarks(NULL);
1228 else if (checkselect(LABEL)) parameterize(P_SUBSTRING, _STR2, -1);
1231 /*--------------------------------------------------------------*/
1232 /* Numerical parameterization (wrapper for parameterize()). */
1233 /*--------------------------------------------------------------*/
1235 void startparam(xcWidget w, pointertype value, caddr_t calldata)
1237 if (value == (pointertype)P_SUBSTRING) {
1238 strcpy(_STR2, (calldata != NULL) ? (char *)calldata : "substring");
1239 stringparam(w, NULL, NULL);
1241 else if ((eventmode != NORMAL_MODE) || (areawin->selects > 0))
1242 parameterize((int)value, (char *)calldata, -1);
1245 /*---------------------------------------------------------------*/
1246 /* Unparameterize a label string (wrapper for unparameterize()). */
1247 /*---------------------------------------------------------------*/
1249 void startunparam(xcWidget w, pointertype value, caddr_t calldata)
1251 if (areawin->selects > 0)
1252 unparameterize((int)value);
1253 unselect_all();
1254 setparammarks(NULL);
1257 /*----------------------------------------------------------------*/
1258 /* Set checkmarks on font menu according to the global defaults */
1259 /*----------------------------------------------------------------*/
1261 void setdefaultfontmarks()
1263 setfontmarks(areawin->psfont, areawin->anchor);
1266 /*----------------------------------------------------------------*/
1267 /* Pick up font name from _STR2 and pass it to loadfontfile() */
1268 /*----------------------------------------------------------------*/
1270 void locloadfont(xcWidget w, char *value)
1272 loadfontfile(_STR2);
1273 free(value);
1276 /*----------------------------------------------------------------*/
1277 /* Find the best matching font given new font, style, or encoding */
1278 /*----------------------------------------------------------------*/
1279 /* newfont, style, or encoding = -1 when not applicable */
1280 /* Return the number of the best matching font. */
1281 /*----------------------------------------------------------------*/
1283 short findbestfont(short curfont, short newfont, short style, short encoding) {
1285 char *newfamily;
1286 short i, newstyle, newenc;
1288 if (fontcount == 0) return -1;
1289 if (curfont < 0) curfont = 0;
1291 if (newfont < 0)
1292 newfamily = fonts[curfont].family;
1293 else if (newfont >= fontcount) { /* move to next font family */
1294 short newidx;
1295 newfont = 0;
1296 while (strcmp(fonts[fontnumbers[newfont]].family, fonts[curfont].family))
1297 newfont++;
1298 newidx = (newfont + 1) % nfontnumbers;
1299 while (!strcmp(fonts[curfont].family, fonts[fontnumbers[newidx]].family) &&
1300 newfont != newidx)
1301 newidx = (newidx + 1) % nfontnumbers;
1302 newfamily = fonts[fontnumbers[newidx]].family;
1303 newfont = fontnumbers[newidx];
1305 else
1306 newfamily = fonts[newfont].family;
1308 if (style < 0)
1309 newstyle = fonts[curfont].flags & 0x03;
1310 else
1311 newstyle = style & 0x03;
1313 if (encoding < 0)
1314 newenc = fonts[curfont].flags & 0xf80;
1315 else
1316 newenc = encoding << 7;
1318 /* Best position is a match on all conditions */
1320 for (i = 0; i < fontcount; i++)
1321 if ((!strcmp(fonts[i].family, newfamily)) &&
1322 ((fonts[i].flags & 0x03) == newstyle) &&
1323 ((fonts[i].flags & 0xf80) == newenc))
1324 return i;
1326 /* Fallback position 1: Match requested property and one other. */
1327 /* order of preference: */
1328 /* Requested property Priority 1 Priority 2 */
1329 /* Font Style Encoding */
1330 /* Style Font (none) */
1331 /* Encoding Font (none) */
1333 for (i = 0; i < fontcount; i++) {
1334 if (newfont >= 0) {
1335 if ((!strcmp(fonts[i].family, newfamily)) &&
1336 (fonts[i].flags & 0x03) == newstyle) return i;
1338 else if (style >= 0) {
1339 if (((fonts[i].flags & 0x03) == newstyle) &&
1340 (!strcmp(fonts[i].family, newfamily))) return i;
1342 else if (encoding >= 0) {
1343 if (((fonts[i].flags & 0xf80) == newenc) &&
1344 (!strcmp(fonts[i].family, newfamily))) return i;
1348 for (i = 0; i < fontcount; i++) {
1349 if (newfont >= 0) {
1350 if ((!strcmp(fonts[i].family, newfamily)) &&
1351 ((fonts[i].flags & 0xf80) >> 7) == newenc) return i;
1355 /* Fallback position 2: Match only the requested property. */
1356 /* For font selection only: Don't want to select a new font */
1357 /* just because a certain style or encoding wasn't available.*/
1359 for (i = 0; i < fontcount; i++) {
1360 if (newfont >= 0) {
1361 if (!strcmp(fonts[i].family, newfamily)) return i;
1365 /* Failure to find matching font property */
1367 if (style >= 0) {
1368 Wprintf("Font %s not available in this style", newfamily);
1370 else {
1371 Wprintf("Font %s not available in this encoding", newfamily);
1373 return (-1);
1376 /*----------------------------------------------------------------*/
1377 /* Set the font. This depends on the system state as to whether */
1378 /* font is set at current position in label, for an entire label, */
1379 /* or as the default font to begin new labels. */
1380 /*----------------------------------------------------------------*/
1382 void setfontval(xcWidget w, pointertype value, labelptr settext)
1384 int newfont;
1385 short i, tc;
1386 stringpart *strptr;
1388 if (settext != NULL) {
1390 /* if last byte was a font designator, use it */
1392 if (areawin->textpos > 0 || areawin->textpos < stringlength(settext->string,
1393 True, areawin->topinstance)) {
1394 strptr = findstringpart(areawin->textpos - 1, NULL, settext->string,
1395 areawin->topinstance);
1396 if (strptr->type == FONT_NAME) {
1397 tc = strptr->data.font;
1398 i = findbestfont(tc, (short)value, -1, -1);
1399 if (i >= 0) {
1400 undrawtext(settext);
1401 strptr->data.font = i;
1402 redrawtext(settext);
1403 if (w != NULL) {
1404 charreport(settext);
1405 togglefontmark(i);
1408 return;
1412 /* otherwise, look for the last style used in the string */
1413 tc = findcurfont(areawin->textpos, settext->string, areawin->topinstance);
1415 else tc = areawin->psfont;
1417 /* Font change command will always find a value since at least one */
1418 /* font has to exist for the font menu button to exist. */
1420 if ((newfont = (int)findbestfont(tc, (short)value, -1, -1)) < 0) return;
1422 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1423 Wprintf("Font is now %s", fonts[newfont].psname);
1424 sprintf(_STR2, "%d", newfont);
1425 labeltext(FONT_NAME, (char *)&newfont);
1427 else {
1428 Wprintf("Default font is now %s", fonts[newfont].psname);
1429 areawin->psfont = newfont;
1432 if (w != NULL) togglefontmark(newfont);
1435 /*----------------------------------------------------------------*/
1436 /* Wrapper for routine setfontval() */
1437 /*----------------------------------------------------------------*/
1439 void setfont(xcWidget w, pointertype value, caddr_t calldata)
1441 short *fselect;
1442 labelptr settext;
1443 short labelcount = 0;
1444 Boolean preselected;
1446 if (eventmode == CATALOG_MODE || eventmode == FONTCAT_MODE ||
1447 eventmode == EFONTCAT_MODE) return;
1449 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1450 settext = *((labelptr *)EDITPART);
1451 setfontval(w, value, settext);
1452 charreport(settext);
1454 else {
1455 if (areawin->selects == 0) {
1456 checkselect(LABEL);
1457 preselected = FALSE;
1459 else preselected = TRUE;
1460 areawin->textpos = 1;
1461 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
1462 areawin->selects; fselect++) {
1463 if (SELECTTYPE(fselect) == LABEL) {
1464 labelcount++;
1465 settext = SELTOLABEL(fselect);
1466 setfontval(NULL, value, settext);
1469 if (labelcount == 0) setfontval(w, value, NULL);
1470 else if (!preselected) unselect_all();
1474 /*----------------------------------------------------------------*/
1475 /* Set the style (bold, italic, normal) for the font, similarly */
1476 /* to the above routine setfontval(). */
1477 /*----------------------------------------------------------------*/
1479 void setfontstyle(xcWidget w, pointertype value, labelptr settext)
1481 int newfont;
1482 short i, tc;
1483 stringpart *strptr;
1485 if (settext != NULL) {
1487 /* if last byte was a font designator, use it */
1489 if (areawin->textpos > 0 || areawin->textpos < stringlength(settext->string,
1490 True, areawin->topinstance)) {
1491 strptr = findstringpart(areawin->textpos - 1, NULL, settext->string,
1492 areawin->topinstance);
1493 if (strptr->type == FONT_NAME) {
1494 tc = strptr->data.font;
1496 /* find font which matches family and style, if available */
1498 i = findbestfont(tc, -1, (short)value, -1);
1499 if (i >= 0) {
1500 undrawtext(settext);
1501 strptr->data.font = i;
1502 redrawtext(settext);
1503 if (w != NULL) {
1504 charreport(settext);
1505 #ifndef TCL_WRAPPER
1506 togglefontstyles(w);
1507 #endif
1510 return;
1514 /* Otherwise, look for the last font used in the string */
1515 /* Fix by Dimitri Princen. Was areawin->textpos - 2; was there a */
1516 /* reason for that? */
1518 tc = findcurfont(areawin->textpos, settext->string, areawin->topinstance);
1520 else tc = areawin->psfont;
1522 if ((newfont = (int)findbestfont(tc, -1, (short)value, -1)) < 0) return;
1524 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1525 Wprintf("Font is now %s", fonts[newfont].psname);
1526 sprintf(_STR2, "%d", newfont);
1527 labeltext(FONT_NAME, (char *)&newfont);
1529 else {
1530 Wprintf("Default font is now %s", fonts[newfont].psname);
1531 areawin->psfont = newfont;
1533 #ifdef TCL_WRAPPER
1534 toggleencodingmark(value);
1535 #else
1536 togglefontstyles(w);
1537 #endif
1540 /*----------------------------------------------------------------*/
1541 /* Wrapper for routine setfontstyle() */
1542 /*----------------------------------------------------------------*/
1544 void fontstyle(xcWidget w, pointertype value, caddr_t nulldata)
1546 short *fselect;
1547 labelptr settext;
1548 short labelcount = 0;
1549 Boolean preselected;
1551 if (eventmode == CATALOG_MODE || eventmode == FONTCAT_MODE ||
1552 eventmode == EFONTCAT_MODE) return;
1554 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1555 settext = *((labelptr *)EDITPART);
1556 setfontstyle(w, value, settext);
1557 charreport(settext);
1559 else {
1560 if (areawin->selects == 0) {
1561 checkselect(LABEL);
1562 preselected = FALSE;
1564 else preselected = TRUE;
1565 areawin->textpos = 1;
1566 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
1567 areawin->selects; fselect++) {
1568 if (SELECTTYPE(fselect) == LABEL) {
1569 labelcount++;
1570 settext = SELTOLABEL(fselect);
1571 setfontstyle(NULL, value, settext);
1574 if (labelcount == 0) setfontstyle(w, value, NULL);
1575 else if (!preselected) unselect_all();
1579 /*----------------------------------------------------------------*/
1580 /* Set the encoding (standard, ISO-Latin1, special) for the font, */
1581 /* similarly to the above routine setfontval(). */
1582 /*----------------------------------------------------------------*/
1584 void setfontencoding(xcWidget w, pointertype value, labelptr settext)
1586 int newfont;
1587 short i, tc;
1588 stringpart *strptr;
1590 if (settext != NULL) {
1592 /* if last byte was a font designator, use it */
1594 if (areawin->textpos > 0 || areawin->textpos < stringlength(settext->string,
1595 True, areawin->topinstance)) {
1596 strptr = findstringpart(areawin->textpos - 1, NULL, settext->string,
1597 areawin->topinstance);
1598 if (strptr->type == FONT_NAME) {
1599 tc = strptr->data.font;
1601 i = findbestfont(tc, -1, -1, (short)value);
1602 if (i >= 0) {
1603 undrawtext(settext);
1604 strptr->data.font = i;
1605 redrawtext(settext);
1606 if (w != NULL) {
1607 charreport(settext);
1608 #ifdef TCL_WRAPPER
1609 toggleencodingmark(value);
1610 #else
1611 toggleencodings(w);
1612 #endif
1615 return;
1619 /* otherwise, look for the last style used in the string */
1620 tc = findcurfont(areawin->textpos - 2, settext->string, areawin->topinstance);
1622 else tc = areawin->psfont;
1624 if ((newfont = (int)findbestfont(tc, -1, -1, (short)value)) < 0) return;
1626 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1627 Wprintf("Font is now %s", fonts[newfont].psname);
1628 sprintf(_STR2, "%d", newfont);
1629 labeltext(FONT_NAME, (char *)&newfont);
1631 else {
1632 Wprintf("Default font is now %s", fonts[newfont].psname);
1633 areawin->psfont = newfont;
1636 #ifndef TCL_WRAPPER
1637 toggleencodings(w);
1638 #endif
1641 /*----------------------------------------------------------------*/
1642 /* Wrapper for routine setfontencoding() */
1643 /*----------------------------------------------------------------*/
1645 void fontencoding(xcWidget w, pointertype value, caddr_t nulldata)
1647 short *fselect;
1648 labelptr settext;
1649 short labelcount = 0;
1650 Boolean preselected;
1652 if (eventmode == CATALOG_MODE || eventmode == FONTCAT_MODE ||
1653 eventmode == EFONTCAT_MODE) return;
1655 if (eventmode == TEXT_MODE || eventmode == ETEXT_MODE) {
1656 settext = *((labelptr *)EDITPART);
1657 setfontencoding(w, value, settext);
1658 charreport(settext);
1660 else {
1661 if (areawin->selects == 0) {
1662 checkselect(LABEL);
1663 preselected = FALSE;
1665 else preselected = TRUE;
1666 areawin->textpos = 1;
1667 for (fselect = areawin->selectlist; fselect < areawin->selectlist +
1668 areawin->selects; fselect++) {
1669 if (SELECTTYPE(fselect) == LABEL) {
1670 labelcount++;
1671 settext = SELTOLABEL(fselect);
1672 setfontencoding(NULL, value, settext);
1675 if (labelcount == 0) setfontencoding(w, value, NULL);
1676 else if (!preselected) unselect_all();
1680 /*----------------------------------------------*/
1681 /* Generate the table of special characters */
1682 /* */
1683 /* Return FALSE if the edited label is LaTeX- */
1684 /* compatible, since LaTeX text does not */
1685 /* usually contain special characters, but it */
1686 /* does contain a lot of backslashes. */
1687 /*----------------------------------------------*/
1689 Boolean dospecial()
1691 labelptr curlabel;
1692 int cfont;
1694 curlabel = TOLABEL(EDITPART);
1695 if (curlabel->anchor & LATEXLABEL) return False;
1697 cfont = findcurfont(areawin->textpos, curlabel->string, areawin->topinstance);
1698 composefontlib(cfont);
1699 startcatalog(NULL, FONTLIB, NULL);
1700 return True;
1703 /*-------------------------------------------------------------------------*/