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 /*----------------------------------------------------------------------*/
13 #include <sys/types.h>
18 #include <X11/Intrinsic.h>
19 #include <X11/StringDefs.h>
20 #include <X11/Xutil.h>
27 /*----------------------------------------------------------------------*/
29 /*----------------------------------------------------------------------*/
31 #include "colordefs.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 */
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
;
57 extern Tcl_Interp
*xcinterp
;
60 /*----------------------------------------------------------------------*/
61 /* Local Variable definitions */
62 /*----------------------------------------------------------------------*/
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
;
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
) {
91 if (sscanf(_STR2
, "%f", &fval
) == 0) {
93 Wprintf("Illegal value");
95 else *dataptr
= fval
/ iscale
;
98 oscale
= xobjs
.pagelist
[areawin
->page
]->outscale
* CMSCALE
;
99 if (sscanf(_STR2
, "%f", &fval
) == 0) {
101 Wprintf("Illegal value");
103 else *dataptr
= fval
* IN_CM_CONVERT
/ (iscale
* oscale
);
105 case DEC_INCH
: case FRAC_INCH
: {
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
)))) {
116 Wprintf("Illegal value");
119 if (parts
== 2) fval
/= (float)f2
;
120 else if (parts
== 3) fval
+= ((float)f2
/ (float)f3
);
121 *dataptr
= fval
* 72.0 / (iscale
* oscale
);
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
) {
140 sprintf(buffer
, "%5.3f", value
* iscale
);
143 oscale
= xobjs
.pagelist
[areawin
->page
]->outscale
* CMSCALE
;
144 sprintf(buffer
, "%5.3f cm", value
* iscale
* oscale
/ IN_CM_CONVERT
);
147 oscale
= xobjs
.pagelist
[areawin
->page
]->outscale
* INCHSCALE
;
148 sprintf(buffer
, "%5.3f in", value
* iscale
* oscale
/ 72.0);
151 oscale
= xobjs
.pagelist
[areawin
->page
]->outscale
* INCHSCALE
;
152 fraccalc(((value
* iscale
* oscale
) / 72.0), buffer
);
153 strcat(buffer
, " in");
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) {
168 Wprintf("Illegal value");
172 if (oldvalue
!= *dataptr
) drawarea(NULL
, NULL
, NULL
);
175 /*--------------------------------------------------------------*/
176 /* Set text scale. */
177 /*--------------------------------------------------------------*/
179 void changetextscale(float newscale
)
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
)) {
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
;
201 labeltext(FONT_SCALE
, (char *)&newscale
);
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) {
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
) {
221 settext
->scale
= newscale
;
223 register_for_undo(XCF_Rescale
, UNDO_MORE
, areawin
->topinstance
,
224 (genericptr
)settext
, (double)oldscale
);
229 if (waschanged
) undo_finish_series();
233 /*--------------------------------------------------------------*/
234 /* Auto-scale the drawing to fit the declared page size. */
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
;
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");
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
);
280 width
= toplevelwidth(areawin
->topinstance
, NULL
);
281 height
= toplevelheight(areawin
->topinstance
, NULL
);
284 if (xobjs
.pagelist
[page
]->orient
== 0) { /* Portrait */
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
)
304 Boolean inchunits
= True
;
308 curtype
= xobjs
.pagelist
[areawin
->page
]->coordstyle
;
310 if (sscanf(strptr
, "%f %11s", &pv
, units
) < 2)
313 if (!strncmp(units
, "cm", 2) || !strncmp(units
, "centimeters", 11))
317 return ((inchunits
) ? (pv
* 2.54) : pv
);
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
)
334 char units
[10], *expos
;
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.");
349 if (sscanf(_STR2
, "%f", &px
) == 0 ||
350 sscanf(expos
+ 1, "%f %9s", &py
, units
) == 0) {
351 Wprintf("Illegal Form for page size.");
358 /* Don't reduce page to less than the margins (1") or negative */
361 if ((px
<= 2.0) || (py
<= 2.0)) {
362 Wprintf("Page size too small for margins.");
366 dataptr
->x
= (short)(px
* 72.0);
367 dataptr
->y
= (short)(py
* 72.0);
369 if (!strcmp(units
, "cm")) {
377 /*--------------------------------------------------------------*/
378 /* Get the text size (global or selected, depending on mode */
379 /*--------------------------------------------------------------*/
381 labelptr
gettextsize(float **floatptr
)
383 labelptr settext
= NULL
;
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
);
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
);
424 /*--------------------------------------------------------------*/
425 /* Set a character kern value */
426 /*--------------------------------------------------------------*/
428 void setkern(xcWidget w
, stringpart
*kpart
)
435 if ((sptr
= strchr(_STR2
, ',')) == NULL
)
436 Wprintf("Use notation X,Y");
439 sscanf(_STR2
, "%hd", &kd
[0]);
440 sscanf(sptr
+ 1, "%hd", &kd
[1]);
442 labeltext(KERN
, (char *)kd
);
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
)
461 if ((sptr
= strchr(_STR2
, ':')) == NULL
)
462 Wprintf("Use ratio X:Y");
465 sscanf(_STR2
, "%hd", &(dataptr
->x
));
466 sscanf(sptr
+ 1, "%hd", &(dataptr
->y
));
467 Wprintf("New scale is %hd:%hd", dataptr
->x
, dataptr
->y
);
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
;
482 int res
= sscanf(_STR2
, "%f", &tmpres
);
484 // Negative values are flips---deal with them independently
489 if (res
== 0 || tmpres
== 0) {
490 Wprintf("Illegal value");
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
);
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 */
516 /*----------------------------------------------------------------*/
518 void setwwidth(xcWidget w
, void *dataptr
)
520 float tmpres
, oldwidth
;
527 if (sscanf(_STR2
, "%f", &tmpres
) == 0) {
528 Wprintf("Illegal value");
531 else if (areawin
->selects
== 0) {
532 areawin
->linewidth
= tmpres
;
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
);
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 /*--------------------------------------------------------------*/
576 void makenewfontbutton()
579 if (nfontnumbers
== 1)
580 fontnumbers
= (u_short
*)malloc(sizeof(u_short
));
582 fontnumbers
= (u_short
*)realloc(fontnumbers
, nfontnumbers
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. */
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
)
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
;
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 /*----------------------------------------------------------------*/
660 void togglegrid(u_short type
)
662 static char *stylenames
[] = {
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
;
685 togglegridstyles(button
);
687 xobjs
.pagelist
[areawin
->page
]->coordstyle
= (short)value
;
690 case FRAC_INCH
: case DEC_INCH
: case INTERNAL
:
692 xobjs
.pagelist
[areawin
->page
]->outscale
*= scalefac
;
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 */
705 xobjs
.pagelist
[areawin
->page
]->outscale
*= scalefac
;
707 xobjs
.pagelist
[areawin
->page
]->pagesize
.x
= 595;
708 xobjs
.pagelist
[areawin
->page
]->pagesize
.y
= 842; /* A4 */
713 if (oldtype
!= xobjs
.pagelist
[areawin
->page
]->coordstyle
) {
714 drawarea(NULL
, NULL
, NULL
);
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 /*----------------------------------------------*/
742 for (i
= 0; i
< xobjs
.numlibs
- 1; i
++) {
743 if (xobjs
.userlibs
[i
].number
== 0)
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
);
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) */
772 /* char libstring[20]; (jdk) */
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];
784 newlibobj
= (objectptr
) malloc(sizeof(object
));
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
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 */
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 */
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
);
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 */
875 if (colorval
!= DEFAULTCOLOR
)
876 sprintf(cstr
, "%5d", colorval
);
878 XcInternalTagCall(xcinterp
, 3, "color", "set", (colorval
== DEFAULTCOLOR
) ?
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. */
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
);
904 strcpy(fstr
, "solid");
907 strcpy(fstr
, "unfilled");
909 switch (styleval
& BORDERS
) {
911 bptr
= borders
[DashedIdx
];
914 bptr
= borders
[DottedIdx
];
917 bptr
= borders
[UnborderedIdx
];
920 bptr
= borders
[SolidIdx
];
924 XcInternalTagCall(xcinterp
, 3, "fill", fstr
,
925 (styleval
& OPAQUE
) ? "opaque" : "transparent");
926 XcInternalTagCall(xcinterp
, 3, "border", "bbox", (styleval
& BBOX
) ? "true" :
928 XcInternalTagCall(xcinterp
, 3, "border", "clipmask", (styleval
& CLIPMASK
) ?
930 XcInternalTagCall(xcinterp
, 2, "border", (styleval
& UNCLOSED
) ? "unclosed" :
932 XcInternalTagCall(xcinterp
, 2, "border", bptr
);
935 #endif /* TCL_WRAPPER */
937 /*--------------------------------------------------------------*/
938 /* Check for a bounding box polygon */
939 /*--------------------------------------------------------------*/
941 polyptr
checkforbbox(objectptr localdata
)
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
;
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 */
957 /*--------------------------------------------------------------*/
959 int setelementstyle(xcWidget w
, u_short value
, u_short mask
)
961 Boolean preselected
, selected
= False
;
963 u_short newstyle
, oldstyle
;
965 if (areawin
->selects
== 0) {
968 checkselect(POLYGON
);
970 checkselect(ARC
| SPLINE
| POLYGON
| PATH
);
972 else preselected
= TRUE
;
974 if (areawin
->selects
> 0) {
977 if (areawin
->selects
!= 1) {
978 Wprintf("Choose only one polygon to be the bounding box");
981 else if (SELECTTYPE(areawin
->selectlist
) != POLYGON
) {
982 Wprintf("Bounding box can only be a polygon");
985 else if (((ckp
= checkforbbox(topobject
)) != NULL
) &&
986 (ckp
!= SELTOPOLY(areawin
->selectlist
))) {
987 Wprintf("Only one bounding box allowed per page");
992 for (sstyle
= areawin
->selectlist
; sstyle
< areawin
->selectlist
993 + areawin
->selects
; sstyle
++) {
994 short stype
= SELECTTYPE(sstyle
);
995 if (stype
& (ARC
| POLYGON
| SPLINE
| PATH
)) {
999 estyle
= &((SELTOARC(sstyle
))->style
);
1002 estyle
= &((SELTOSPLINE(sstyle
))->style
);
1005 estyle
= &((SELTOPOLY(sstyle
))->style
);
1008 estyle
= &((SELTOPATH(sstyle
))->style
);
1011 oldstyle
= newstyle
= *estyle
;
1012 newstyle
&= ~(mask
);
1015 if (oldstyle
!= newstyle
) {
1016 if ((newstyle
& NOBORDER
) && !(newstyle
& FILLED
)) {
1017 Wprintf("Must have either a border or filler");
1021 SetForeground(dpy
, areawin
->gc
, BACKGROUND
);
1022 easydraw(*sstyle
, DOFORALL
);
1026 (SELTOPOLY(sstyle
))->color
= (value
& BBOX
) ? BBOXCOLOR
1029 SetForeground(dpy
, areawin
->gc
, SELECTCOLOR
);
1030 easydraw(*sstyle
, DOFORALL
);
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
);
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
);
1049 pwriteback(areawin
->topinstance
);
1051 newstyle
= areawin
->style
;
1053 Wprintf("Cannot set default style to Bounding Box");
1054 newstyle
&= ~(BBOX
);
1057 else if (value
& CLIPMASK
) {
1058 Wprintf("Cannot set default style to Clip Mask");
1059 newstyle
&= ~(CLIPMASK
);
1067 if ((newstyle
& NOBORDER
) && !(newstyle
& FILLED
)) {
1068 Wprintf("Must have either a border or filler");
1071 areawin
->style
= newstyle
;
1077 setallstylemarks(newstyle
);
1082 return (int)newstyle
;
1085 /*-----------------------------------------------*/
1086 /* Set the color value for all selected elements */
1087 /*-----------------------------------------------*/
1091 void setcolor(xcWidget w
, int cindex
)
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
);
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
));
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
);
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
);
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
);
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
)
1188 XcInternalTagCall(xcinterp
, 3, "label", "flipinvariant", (anchorvalue
& FLIPINV
) ?
1190 XcInternalTagCall(xcinterp
, 3, "label", "latex", (anchorvalue
& LATEXLABEL
) ?
1192 XcInternalTagCall(xcinterp
, 3, "label", "visible", (anchorvalue
& PINVISIBLE
) ?
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
);
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
);
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
);
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
) {
1286 short i
, newstyle
, newenc
;
1288 if (fontcount
== 0) return -1;
1289 if (curfont
< 0) curfont
= 0;
1292 newfamily
= fonts
[curfont
].family
;
1293 else if (newfont
>= fontcount
) { /* move to next font family */
1296 while (strcmp(fonts
[fontnumbers
[newfont
]].family
, fonts
[curfont
].family
))
1298 newidx
= (newfont
+ 1) % nfontnumbers
;
1299 while (!strcmp(fonts
[curfont
].family
, fonts
[fontnumbers
[newidx
]].family
) &&
1301 newidx
= (newidx
+ 1) % nfontnumbers
;
1302 newfamily
= fonts
[fontnumbers
[newidx
]].family
;
1303 newfont
= fontnumbers
[newidx
];
1306 newfamily
= fonts
[newfont
].family
;
1309 newstyle
= fonts
[curfont
].flags
& 0x03;
1311 newstyle
= style
& 0x03;
1314 newenc
= fonts
[curfont
].flags
& 0xf80;
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
))
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
++) {
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
++) {
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
++) {
1361 if (!strcmp(fonts
[i
].family
, newfamily
)) return i
;
1365 /* Failure to find matching font property */
1368 Wprintf("Font %s not available in this style", newfamily
);
1371 Wprintf("Font %s not available in this encoding", newfamily
);
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
)
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);
1400 undrawtext(settext
);
1401 strptr
->data
.font
= i
;
1402 redrawtext(settext
);
1404 charreport(settext
);
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
);
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
)
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
);
1455 if (areawin
->selects
== 0) {
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
) {
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
)
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);
1500 undrawtext(settext
);
1501 strptr
->data
.font
= i
;
1502 redrawtext(settext
);
1504 charreport(settext
);
1506 togglefontstyles(w
);
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
);
1530 Wprintf("Default font is now %s", fonts
[newfont
].psname
);
1531 areawin
->psfont
= newfont
;
1534 toggleencodingmark(value
);
1536 togglefontstyles(w
);
1540 /*----------------------------------------------------------------*/
1541 /* Wrapper for routine setfontstyle() */
1542 /*----------------------------------------------------------------*/
1544 void fontstyle(xcWidget w
, pointertype value
, caddr_t nulldata
)
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
);
1560 if (areawin
->selects
== 0) {
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
) {
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
)
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
);
1603 undrawtext(settext
);
1604 strptr
->data
.font
= i
;
1605 redrawtext(settext
);
1607 charreport(settext
);
1609 toggleencodingmark(value
);
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
);
1632 Wprintf("Default font is now %s", fonts
[newfont
].psname
);
1633 areawin
->psfont
= newfont
;
1641 /*----------------------------------------------------------------*/
1642 /* Wrapper for routine setfontencoding() */
1643 /*----------------------------------------------------------------*/
1645 void fontencoding(xcWidget w
, pointertype value
, caddr_t nulldata
)
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
);
1661 if (areawin
->selects
== 0) {
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
) {
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 */
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 /*----------------------------------------------*/
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
);
1703 /*-------------------------------------------------------------------------*/