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 if (waschanged
) undo_finish_series();
508 pwriteback(areawin
->topinstance
);
509 drawarea(NULL
, NULL
, NULL
);
512 /*----------------------------------------------------------------*/
513 /* Set the linewidth of all selected arcs, polygons, splines, and */
515 /*----------------------------------------------------------------*/
517 void setwwidth(xcWidget w
, void *dataptr
)
519 float tmpres
, oldwidth
;
526 if (sscanf(_STR2
, "%f", &tmpres
) == 0) {
527 Wprintf("Illegal value");
530 else if (areawin
->selects
== 0) {
531 areawin
->linewidth
= tmpres
;
534 for (osel
= areawin
->selectlist
; osel
< areawin
->selectlist
+
535 areawin
->selects
; osel
++) {
536 if (SELECTTYPE(osel
) == ARC
) {
537 nsarc
= SELTOARC(osel
);
538 oldwidth
= nsarc
->width
;
539 nsarc
->width
= tmpres
;
541 else if (SELECTTYPE(osel
) == POLYGON
) {
542 nspoly
= SELTOPOLY(osel
);
543 oldwidth
= nspoly
->width
;
544 nspoly
->width
= tmpres
;
546 else if (SELECTTYPE(osel
) == SPLINE
) {
547 nsspline
= SELTOSPLINE(osel
);
548 oldwidth
= nsspline
->width
;
549 nsspline
->width
= tmpres
;
551 else if (SELECTTYPE(osel
) == PATH
) {
552 nspath
= SELTOPATH(osel
);
553 oldwidth
= nspath
->width
;
554 nspath
->width
= tmpres
;
557 if (oldwidth
!= tmpres
)
558 register_for_undo(XCF_Rescale
, UNDO_MORE
, areawin
->topinstance
,
559 SELTOGENERIC(osel
), (double)oldwidth
);
562 pwriteback(areawin
->topinstance
);
563 drawarea(NULL
, NULL
, NULL
);
567 /*--------------------------------------------------------------*/
568 /* Add a new font name to the list of known fonts */
569 /* Register the font number for the Alt-F cycling mechanism */
570 /* Tcl: depends on command tag mechanism for GUI menu update. */
571 /*--------------------------------------------------------------*/
575 void makenewfontbutton()
578 if (nfontnumbers
== 1)
579 fontnumbers
= (u_short
*)malloc(sizeof(u_short
));
581 fontnumbers
= (u_short
*)realloc(fontnumbers
, nfontnumbers
583 fontnumbers
[nfontnumbers
- 1] = fontcount
- 1;
586 #endif /* TCL_WRAPPER */
588 /*---------------------------------------------------------------*/
589 /* Some Xcircuit routines using toggle and toggleexcl, */
590 /* put here because they reference the menu structures directly. */
592 /* Note that by bypassing addnewcolorentry(), the new colors in */
593 /* colorlist are NOT added to the GUI list of colors. */
594 /*---------------------------------------------------------------*/
596 void setcolorscheme(Boolean boolvalue
)
601 colorlist
[PARAMCOLOR
].color
.pixel
= appdata
.parampix
;
602 colorlist
[AUXCOLOR
].color
.pixel
= appdata
.auxpix
;
603 colorlist
[OFFBUTTONCOLOR
].color
.pixel
= appdata
.buttonpix
;
604 colorlist
[SELECTCOLOR
].color
.pixel
= appdata
.selectpix
;
605 colorlist
[GRIDCOLOR
].color
.pixel
= appdata
.gridpix
;
606 colorlist
[SNAPCOLOR
].color
.pixel
= appdata
.snappix
;
607 colorlist
[AXESCOLOR
].color
.pixel
= appdata
.axespix
;
608 colorlist
[BACKGROUND
].color
.pixel
= appdata
.bg
;
609 colorlist
[FOREGROUND
].color
.pixel
= appdata
.fg
;
612 colorlist
[PARAMCOLOR
].color
.pixel
= appdata
.parampix2
;
613 colorlist
[AUXCOLOR
].color
.pixel
= appdata
.auxpix2
;
614 colorlist
[OFFBUTTONCOLOR
].color
.pixel
= appdata
.buttonpix2
;
615 colorlist
[SELECTCOLOR
].color
.pixel
= appdata
.selectpix2
;
616 colorlist
[GRIDCOLOR
].color
.pixel
= appdata
.gridpix2
;
617 colorlist
[SNAPCOLOR
].color
.pixel
= appdata
.snappix2
;
618 colorlist
[AXESCOLOR
].color
.pixel
= appdata
.axespix2
;
619 colorlist
[BACKGROUND
].color
.pixel
= appdata
.bg2
;
620 colorlist
[FOREGROUND
].color
.pixel
= appdata
.fg2
;
623 colorlist
[BARCOLOR
].color
.pixel
= appdata
.barpix
;
624 colorlist
[FILTERCOLOR
].color
.pixel
= appdata
.filterpix
;
626 colorlist
[LOCALPINCOLOR
].color
.pixel
= appdata
.localcolor
;
627 colorlist
[GLOBALPINCOLOR
].color
.pixel
= appdata
.globalcolor
;
628 colorlist
[INFOLABELCOLOR
].color
.pixel
= appdata
.infocolor
;
629 colorlist
[RATSNESTCOLOR
].color
.pixel
= appdata
.ratsnestcolor
;
630 colorlist
[BBOXCOLOR
].color
.pixel
= appdata
.bboxpix
;
631 colorlist
[CLIPMASKCOLOR
].color
.pixel
= appdata
.clipcolor
;
632 colorlist
[FIXEDBBOXCOLOR
].color
.pixel
= appdata
.fixedbboxpix
;
634 /* Fill in pixel information */
636 for (i
= 0; i
< NUMBER_OF_COLORS
; i
++) {
637 unsigned short r
, g
, b
;
639 /* Get the color the hard way by querying the X server colormap */
640 xc_get_color_rgb(colorlist
[i
].color
.pixel
, &r
, &g
, &b
);
642 /* Store this information locally so we don't have to do */
643 /* the lookup the hard way in the future. */
645 colorlist
[i
].color
.red
= r
;
646 colorlist
[i
].color
.green
= g
;
647 colorlist
[i
].color
.blue
= b
;
649 areawin
->redraw_needed
= True
;
650 drawarea(NULL
, NULL
, NULL
);
653 /*----------------------------------------------------------------*/
654 /* Change menu selection for reported measurement units */
655 /*----------------------------------------------------------------*/
659 void togglegrid(u_short type
)
661 static char *stylenames
[] = {
665 "internal units", NULL
668 XcInternalTagCall(xcinterp
, 3, "config", "coordstyle", stylenames
[type
]);
671 #endif /* TCL_WRAPPER */
673 /*----------------------------------------------------------------*/
674 /* Called by setgridtype() to complete setting the reported */
675 /* measurement units */
676 /*----------------------------------------------------------------*/
678 void getgridtype(xcWidget button
, pointertype value
, caddr_t calldata
)
680 short oldtype
= xobjs
.pagelist
[areawin
->page
]->coordstyle
;
681 float scalefac
= getpsscale(1.0, areawin
->page
) / INCHSCALE
;
684 togglegridstyles(button
);
686 xobjs
.pagelist
[areawin
->page
]->coordstyle
= (short)value
;
689 case FRAC_INCH
: case DEC_INCH
: case INTERNAL
:
691 xobjs
.pagelist
[areawin
->page
]->outscale
*= scalefac
;
693 /* Note: Tcl defines a method for selecting standard */
694 /* page sizes. We really DON'T want to reset the size */
695 /* just because we switched measurement formats! */
697 xobjs
.pagelist
[areawin
->page
]->pagesize
.x
= 612;
698 xobjs
.pagelist
[areawin
->page
]->pagesize
.y
= 792; /* letter */
704 xobjs
.pagelist
[areawin
->page
]->outscale
*= scalefac
;
706 xobjs
.pagelist
[areawin
->page
]->pagesize
.x
= 595;
707 xobjs
.pagelist
[areawin
->page
]->pagesize
.y
= 842; /* A4 */
712 if (oldtype
!= xobjs
.pagelist
[areawin
->page
]->coordstyle
) {
713 drawarea(NULL
, NULL
, NULL
);
718 /*------------------------------------------------------*/
719 /* Make new library, add new button to the "Libraries" */
720 /* cascaded menu, compose the library page, update the */
721 /* library directory, and go to that library page. */
722 /*------------------------------------------------------*/
724 void newlibrary(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
726 int libnum
= createlibrary(FALSE
);
727 startcatalog(w
, libnum
, NULL
);
730 /*----------------------------------------------*/
731 /* Find an empty library, and return its page */
732 /* number if it exists. Otherwise, return -1. */
733 /* This search does not include the so-called */
734 /* "User Library" (last library in list). */
735 /*----------------------------------------------*/
741 for (i
= 0; i
< xobjs
.numlibs
- 1; i
++) {
742 if (xobjs
.userlibs
[i
].number
== 0)
748 /*----------------------------------------------*/
749 /* Make new page; goto that page */
750 /* (wrapper for routine events.c:newpage()) */
751 /*----------------------------------------------*/
753 void newpagemenu(xcWidget w
, pointertype value
, caddr_t nulldata
)
755 newpage((short)value
);
760 /*----------------------------------------------*/
761 /* Make new library and add a new button to the */
762 /* "Libraries" cascaded menu. */
763 /*----------------------------------------------*/
765 int createlibrary(Boolean force
)
767 /* xcWidget libmenu, newbutton, oldbutton; (jdk) */
771 /* char libstring[20]; (jdk) */
775 /* If there's an empty library, return its number */
776 if ((!force
) && (libnum
= findemptylib()) >= 0) return (libnum
+ LIBRARY
);
777 libnum
= (xobjs
.numlibs
++) + LIBRARY
;
778 xobjs
.libtop
= (objinstptr
*)realloc(xobjs
.libtop
,
779 (libnum
+ 1) * sizeof(objinstptr
));
780 xobjs
.libtop
[libnum
] = xobjs
.libtop
[libnum
- 1];
783 newlibobj
= (objectptr
) malloc(sizeof(object
));
785 xobjs
.libtop
[libnum
] = newpageinst(newlibobj
);
787 sprintf(newlibobj
->name
, "Library %d", libnum
- LIBRARY
+ 1);
789 /* Create the library */
791 xobjs
.userlibs
= (Library
*) realloc(xobjs
.userlibs
, xobjs
.numlibs
793 xobjs
.userlibs
[libnum
+ 1 - LIBRARY
] = xobjs
.userlibs
[libnum
- LIBRARY
];
794 xobjs
.userlibs
[libnum
- LIBRARY
].library
= (objectptr
*) malloc(sizeof(objectptr
));
795 xobjs
.userlibs
[libnum
- LIBRARY
].number
= 0;
796 xobjs
.userlibs
[libnum
- LIBRARY
].instlist
= NULL
;
798 sprintf(_STR2
, "xcircuit::newlibrarybutton \"%s\"", newlibobj
->name
);
799 Tcl_Eval(xcinterp
, _STR2
);
801 /* Update the library directory to include the new page */
808 /*--------------------------------------------------------------*/
809 /* Routine called by newpage() if new button needs to be made */
810 /* to add to the "Pages" cascaded menu. */
811 /*--------------------------------------------------------------*/
813 void makepagebutton()
815 /* xcWidget pagemenu, newbutton; (jdk) */
816 /* char pagestring[10]; (jdk) */
818 /* make new entry in the menu */
820 sprintf(_STR2
, "newpagebutton \"Page %d\"", xobjs
.pages
);
821 Tcl_Eval(xcinterp
, _STR2
);
823 /* Update the page directory */
828 /*----------------------------------------------------------------*/
829 /* Find the Page menu button associated with the page number */
830 /* (passed parameter) and set the label of that button to the */
831 /* object name (= page label) */
832 /*----------------------------------------------------------------*/
834 void renamepage(short pagenumber
)
836 objinstptr thisinst
= xobjs
.pagelist
[pagenumber
]->pageinst
;
837 char *pname
, *plabel
;
839 if ((pagenumber
>= 0) && (pagenumber
< xobjs
.pages
- 1) &&
840 (thisinst
!= NULL
)) {
841 plabel
= thisinst
->thisobject
->name
;
842 pname
= (char *)malloc(36 + strlen(plabel
));
843 sprintf(pname
, "catch {xcircuit::renamepage %d {%s}}", pagenumber
+ 1, plabel
);
844 Tcl_Eval(xcinterp
, pname
);
849 /*--------------------------------------------------------------*/
850 /* Same routine as above, for Library page menu buttons */
851 /*--------------------------------------------------------------*/
853 void renamelib(short libnumber
)
855 if (libnumber
<= xobjs
.numlibs
) return;
857 sprintf(_STR2
, "xcircuit::renamelib %d \"%s\"", libnumber
- LIBRARY
+ 1,
858 xobjs
.libtop
[libnumber
]->thisobject
->name
);
859 Tcl_Eval(xcinterp
, _STR2
);
862 /*--------------------------------------------------------------*/
863 /* Set the menu checkmarks on the color menu */
864 /*--------------------------------------------------------------*/
866 void setcolormark(int colorval
)
868 /* Set GUI variables and execute any command tags associated */
869 /* with the "color" command */
874 if (colorval
!= DEFAULTCOLOR
)
875 sprintf(cstr
, "%5d", colorval
);
877 XcInternalTagCall(xcinterp
, 3, "color", "set", (colorval
== DEFAULTCOLOR
) ?
882 /*----------------------------------------------------------------*/
883 /* Set the checkmarks on the element styles menu */
884 /*----------------------------------------------------------------*/
886 void setallstylemarks(u_short styleval
)
888 /* Execute any command tags associated */
889 /* with the "fill" and "border" commands. */
895 const char *borders
[] = {"solid", "unbordered", "dashed", "dotted", NULL
};
896 enum BorderIdx
{ SolidIdx
, UnborderedIdx
, DashedIdx
, DottedIdx
};
898 if (styleval
& FILLED
) {
899 fillfactor
= (int)(12.5 * (float)(1 + ((styleval
& FILLSOLID
) >> 5)));
900 if (fillfactor
< 100)
901 sprintf(fstr
, "%d", fillfactor
);
903 strcpy(fstr
, "solid");
906 strcpy(fstr
, "unfilled");
908 switch (styleval
& BORDERS
) {
910 bptr
= borders
[DashedIdx
];
913 bptr
= borders
[DottedIdx
];
916 bptr
= borders
[UnborderedIdx
];
919 bptr
= borders
[SolidIdx
];
923 XcInternalTagCall(xcinterp
, 3, "fill", fstr
,
924 (styleval
& OPAQUE
) ? "opaque" : "transparent");
925 XcInternalTagCall(xcinterp
, 3, "border", "bbox", (styleval
& BBOX
) ? "true" :
927 XcInternalTagCall(xcinterp
, 3, "border", "clipmask", (styleval
& CLIPMASK
) ?
929 XcInternalTagCall(xcinterp
, 2, "border", (styleval
& UNCLOSED
) ? "unclosed" :
931 XcInternalTagCall(xcinterp
, 2, "border", bptr
);
934 #endif /* TCL_WRAPPER */
936 /*--------------------------------------------------------------*/
937 /* Check for a bounding box polygon */
938 /*--------------------------------------------------------------*/
940 polyptr
checkforbbox(objectptr localdata
)
944 for (cbbox
= (polyptr
*)localdata
->plist
; cbbox
<
945 (polyptr
*)localdata
->plist
+ localdata
->parts
; cbbox
++)
946 if (IS_POLYGON(*cbbox
))
947 if ((*cbbox
)->style
& BBOX
) return *cbbox
;
952 /*--------------------------------------------------------------*/
953 /* Set a value for element style. "Mask" determines the bits */
954 /* to be affected, so that "value" may turn bits either on or */
956 /*--------------------------------------------------------------*/
958 int setelementstyle(xcWidget w
, u_short value
, u_short mask
)
960 Boolean preselected
, selected
= False
;
962 u_short newstyle
, oldstyle
;
964 if (areawin
->selects
== 0) {
967 checkselect(POLYGON
);
969 checkselect(ARC
| SPLINE
| POLYGON
| PATH
);
971 else preselected
= TRUE
;
973 if (areawin
->selects
> 0) {
976 if (areawin
->selects
!= 1) {
977 Wprintf("Choose only one polygon to be the bounding box");
980 else if (SELECTTYPE(areawin
->selectlist
) != POLYGON
) {
981 Wprintf("Bounding box can only be a polygon");
984 else if (((ckp
= checkforbbox(topobject
)) != NULL
) &&
985 (ckp
!= SELTOPOLY(areawin
->selectlist
))) {
986 Wprintf("Only one bounding box allowed per page");
991 for (sstyle
= areawin
->selectlist
; sstyle
< areawin
->selectlist
992 + areawin
->selects
; sstyle
++) {
993 short stype
= SELECTTYPE(sstyle
);
994 if (stype
& (ARC
| POLYGON
| SPLINE
| PATH
)) {
998 estyle
= &((SELTOARC(sstyle
))->style
);
1001 estyle
= &((SELTOSPLINE(sstyle
))->style
);
1004 estyle
= &((SELTOPOLY(sstyle
))->style
);
1007 estyle
= &((SELTOPATH(sstyle
))->style
);
1010 oldstyle
= newstyle
= *estyle
;
1011 newstyle
&= ~(mask
);
1014 if (oldstyle
!= newstyle
) {
1015 if ((newstyle
& NOBORDER
) && !(newstyle
& FILLED
)) {
1016 Wprintf("Must have either a border or filler");
1020 SetForeground(dpy
, areawin
->gc
, BACKGROUND
);
1021 easydraw(*sstyle
, DOFORALL
);
1025 (SELTOPOLY(sstyle
))->color
= (value
& BBOX
) ? BBOXCOLOR
1028 SetForeground(dpy
, areawin
->gc
, SELECTCOLOR
);
1029 easydraw(*sstyle
, DOFORALL
);
1032 register_for_undo(XCF_ChangeStyle
,
1033 (sstyle
== areawin
->selectlist
+ areawin
->selects
- 1) ?
1034 UNDO_DONE
: UNDO_MORE
, areawin
->topinstance
,
1035 SELTOGENERIC(sstyle
), (int)oldstyle
);
1037 /* Tcl version differs in that the element is not deselected after */
1039 register_for_undo(XCF_ChangeStyle
, UNDO_MORE
, areawin
->topinstance
,
1040 SELTOGENERIC(sstyle
), (int)oldstyle
);
1048 pwriteback(areawin
->topinstance
);
1050 newstyle
= areawin
->style
;
1052 Wprintf("Cannot set default style to Bounding Box");
1053 newstyle
&= ~(BBOX
);
1056 else if (value
& CLIPMASK
) {
1057 Wprintf("Cannot set default style to Clip Mask");
1058 newstyle
&= ~(CLIPMASK
);
1066 if ((newstyle
& NOBORDER
) && !(newstyle
& FILLED
)) {
1067 Wprintf("Must have either a border or filler");
1070 areawin
->style
= newstyle
;
1076 setallstylemarks(newstyle
);
1081 return (int)newstyle
;
1084 /*-----------------------------------------------*/
1085 /* Set the color value for all selected elements */
1086 /*-----------------------------------------------*/
1090 void setcolor(xcWidget w
, int cindex
)
1093 int *ecolor
, oldcolor
;
1094 Boolean selected
= False
;
1095 stringpart
*strptr
, *nextptr
;
1097 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1098 labelptr curlabel
= TOLABEL(EDITPART
);
1099 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, curlabel
->string
,
1100 areawin
->topinstance
);
1101 nextptr
= findstringpart(areawin
->textpos
, NULL
, curlabel
->string
,
1102 areawin
->topinstance
);
1103 if (strptr
&& strptr
->type
== FONT_COLOR
) {
1104 undrawtext(curlabel
);
1105 strptr
->data
.color
= cindex
;
1106 redrawtext(curlabel
);
1108 else if (nextptr
&& nextptr
->type
== FONT_COLOR
) {
1109 undrawtext(curlabel
);
1110 nextptr
->data
.color
= cindex
;
1111 redrawtext(curlabel
);
1114 sprintf(_STR2
, "%d", cindex
);
1115 labeltext(FONT_COLOR
, (char *)&cindex
);
1119 else if (areawin
->selects
> 0) {
1120 for (scolor
= areawin
->selectlist
; scolor
< areawin
->selectlist
1121 + areawin
->selects
; scolor
++) {
1122 ecolor
= &(SELTOCOLOR(scolor
));
1127 register_for_undo(XCF_Color
, (scolor
== areawin
->selectlist
1128 + areawin
->selects
- 1) ? UNDO_DONE
: UNDO_MORE
,
1129 areawin
->topinstance
,
1130 SELTOGENERIC(scolor
), (int)oldcolor
);
1134 setcolormark(cindex
);
1136 if (eventmode
!= TEXT_MODE
&& eventmode
!= ETEXT_MODE
)
1137 areawin
->color
= cindex
;
1139 else pwriteback(areawin
->topinstance
);
1142 /*--------------------------------------------------------------*/
1143 /* Set the menu checkmarks on the font menu */
1144 /*--------------------------------------------------------------*/
1146 void togglefontmark(int fontval
)
1148 if (fonts
[fontval
].family
!= NULL
)
1149 XcInternalTagCall(xcinterp
, 3, "label", "family", fonts
[fontval
].family
);
1152 /*------------------------------------------------------*/
1153 /* Set checkmarks on label style menu */
1154 /* fvalue is for font, jvalue is for anchoring */
1155 /*------------------------------------------------------*/
1157 void togglestylemark(int styleval
)
1159 char *cstyle
= translatestyle(styleval
);
1161 XcInternalTagCall(xcinterp
, 3, "label", "style", cstyle
);
1164 /*------------------------------------------------------*/
1165 /* Set checkmarks on label encoding menu */
1166 /*------------------------------------------------------*/
1168 void toggleencodingmark(int encodingval
)
1170 char *cenc
= translateencoding(encodingval
);
1172 XcInternalTagCall(xcinterp
, 3, "label", "encoding", cenc
);
1175 /*------------------------------------------------------*/
1176 /* Set checkmarks on label anchoring & flags menu */
1177 /*------------------------------------------------------*/
1179 void toggleanchormarks(int anchorvalue
)
1181 XcInternalTagCall(xcinterp
, 4, "label", "anchor", (anchorvalue
& RIGHT
) ? "right" :
1182 (anchorvalue
& NOTLEFT
) ? "center" : "left",
1183 (anchorvalue
& TOP
) ? "top" : (anchorvalue
& NOTBOTTOM
) ? "middle" : "bottom");
1184 XcInternalTagCall(xcinterp
, 3, "label", "justify", (anchorvalue
& JUSTIFYRIGHT
) ?
1185 "right" : (anchorvalue
& TEXTCENTERED
) ? "center" : (anchorvalue
& JUSTIFYBOTH
)
1187 XcInternalTagCall(xcinterp
, 3, "label", "flipinvariant", (anchorvalue
& FLIPINV
) ?
1189 XcInternalTagCall(xcinterp
, 3, "label", "latex", (anchorvalue
& LATEXLABEL
) ?
1191 XcInternalTagCall(xcinterp
, 3, "label", "visible", (anchorvalue
& PINVISIBLE
) ?
1195 /*-------------------------------------------------------------*/
1196 /* Simultaneously set all relevant checkmarks for a text label */
1197 /*-------------------------------------------------------------*/
1199 void setfontmarks(short fvalue
, short jvalue
)
1201 if ((fvalue
>= 0) && (fvalue
< fontcount
)) {
1202 toggleencodingmark(fvalue
);
1203 togglestylemark(fvalue
);
1204 togglefontmark(fvalue
);
1206 toggleanchormarks(jvalue
);
1209 #endif /* TCL_WRAPPER */
1211 /*--------------------------------------------------------------*/
1212 /* Parameterize a label string (wrapper for parameterize()). */
1213 /* Assumes that the name has been generated by the popup prompt */
1214 /* and is therefore held in variable _STR2 */
1215 /*--------------------------------------------------------------*/
1217 void stringparam(xcWidget w
, caddr_t clientdata
, caddr_t calldata
)
1219 genericptr
*settext
;
1221 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1222 settext
= (genericptr
*)EDITPART
;
1223 makeparam(TOLABEL(settext
), _STR2
);
1224 if (eventmode
== ETEXT_MODE
)
1227 /* Move cursor position to account for the parameter */
1228 /* start and end markers that have been added to the */
1230 areawin
->textpos
+= 2;
1231 setparammarks(NULL
);
1233 else if (checkselect(LABEL
)) parameterize(P_SUBSTRING
, _STR2
, -1);
1236 /*--------------------------------------------------------------*/
1237 /* Numerical parameterization (wrapper for parameterize()). */
1238 /*--------------------------------------------------------------*/
1240 void startparam(xcWidget w
, pointertype value
, caddr_t calldata
)
1242 if (value
== (pointertype
)P_SUBSTRING
) {
1243 strcpy(_STR2
, (calldata
!= NULL
) ? (char *)calldata
: "substring");
1244 stringparam(w
, NULL
, NULL
);
1246 else if ((eventmode
!= NORMAL_MODE
) || (areawin
->selects
> 0))
1247 parameterize((int)value
, (char *)calldata
, -1);
1250 /*---------------------------------------------------------------*/
1251 /* Unparameterize a label string (wrapper for unparameterize()). */
1252 /*---------------------------------------------------------------*/
1254 void startunparam(xcWidget w
, pointertype value
, caddr_t calldata
)
1256 if (areawin
->selects
> 0)
1257 unparameterize((int)value
);
1259 setparammarks(NULL
);
1262 /*----------------------------------------------------------------*/
1263 /* Set checkmarks on font menu according to the global defaults */
1264 /*----------------------------------------------------------------*/
1266 void setdefaultfontmarks()
1268 setfontmarks(areawin
->psfont
, areawin
->anchor
);
1271 /*----------------------------------------------------------------*/
1272 /* Pick up font name from _STR2 and pass it to loadfontfile() */
1273 /*----------------------------------------------------------------*/
1275 void locloadfont(xcWidget w
, char *value
)
1277 loadfontfile(_STR2
);
1281 /*----------------------------------------------------------------*/
1282 /* Find the best matching font given new font, style, or encoding */
1283 /*----------------------------------------------------------------*/
1284 /* newfont, style, or encoding = -1 when not applicable */
1285 /* Return the number of the best matching font. */
1286 /*----------------------------------------------------------------*/
1288 short findbestfont(short curfont
, short newfont
, short style
, short encoding
) {
1291 short i
, newstyle
, newenc
;
1293 if (fontcount
== 0) return -1;
1294 if (curfont
< 0) curfont
= 0;
1297 newfamily
= fonts
[curfont
].family
;
1298 else if (newfont
>= fontcount
) { /* move to next font family */
1301 while (strcmp(fonts
[fontnumbers
[newfont
]].family
, fonts
[curfont
].family
))
1303 newidx
= (newfont
+ 1) % nfontnumbers
;
1304 while (!strcmp(fonts
[curfont
].family
, fonts
[fontnumbers
[newidx
]].family
) &&
1306 newidx
= (newidx
+ 1) % nfontnumbers
;
1307 newfamily
= fonts
[fontnumbers
[newidx
]].family
;
1308 newfont
= fontnumbers
[newidx
];
1311 newfamily
= fonts
[newfont
].family
;
1314 newstyle
= fonts
[curfont
].flags
& 0x03;
1316 newstyle
= style
& 0x03;
1319 newenc
= fonts
[curfont
].flags
& 0xf80;
1321 newenc
= encoding
<< 7;
1323 /* Best position is a match on all conditions */
1325 for (i
= 0; i
< fontcount
; i
++)
1326 if ((!strcmp(fonts
[i
].family
, newfamily
)) &&
1327 ((fonts
[i
].flags
& 0x03) == newstyle
) &&
1328 ((fonts
[i
].flags
& 0xf80) == newenc
))
1331 /* Fallback position 1: Match requested property and one other. */
1332 /* order of preference: */
1333 /* Requested property Priority 1 Priority 2 */
1334 /* Font Style Encoding */
1335 /* Style Font (none) */
1336 /* Encoding Font (none) */
1338 for (i
= 0; i
< fontcount
; i
++) {
1340 if ((!strcmp(fonts
[i
].family
, newfamily
)) &&
1341 (fonts
[i
].flags
& 0x03) == newstyle
) return i
;
1343 else if (style
>= 0) {
1344 if (((fonts
[i
].flags
& 0x03) == newstyle
) &&
1345 (!strcmp(fonts
[i
].family
, newfamily
))) return i
;
1347 else if (encoding
>= 0) {
1348 if (((fonts
[i
].flags
& 0xf80) == newenc
) &&
1349 (!strcmp(fonts
[i
].family
, newfamily
))) return i
;
1353 for (i
= 0; i
< fontcount
; i
++) {
1355 if ((!strcmp(fonts
[i
].family
, newfamily
)) &&
1356 ((fonts
[i
].flags
& 0xf80) >> 7) == newenc
) return i
;
1360 /* Fallback position 2: Match only the requested property. */
1361 /* For font selection only: Don't want to select a new font */
1362 /* just because a certain style or encoding wasn't available.*/
1364 for (i
= 0; i
< fontcount
; i
++) {
1366 if (!strcmp(fonts
[i
].family
, newfamily
)) return i
;
1370 /* Failure to find matching font property */
1373 Wprintf("Font %s not available in this style", newfamily
);
1376 Wprintf("Font %s not available in this encoding", newfamily
);
1381 /*----------------------------------------------------------------*/
1382 /* Set the font. This depends on the system state as to whether */
1383 /* font is set at current position in label, for an entire label, */
1384 /* or as the default font to begin new labels. */
1385 /*----------------------------------------------------------------*/
1387 void setfontval(xcWidget w
, pointertype value
, labelptr settext
)
1393 if (settext
!= NULL
) {
1395 /* if last byte was a font designator, use it */
1397 if (areawin
->textpos
> 0 || areawin
->textpos
< stringlength(settext
->string
,
1398 True
, areawin
->topinstance
)) {
1399 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, settext
->string
,
1400 areawin
->topinstance
);
1401 if (strptr
->type
== FONT_NAME
) {
1402 tc
= strptr
->data
.font
;
1403 i
= findbestfont(tc
, (short)value
, -1, -1);
1405 undrawtext(settext
);
1406 strptr
->data
.font
= i
;
1407 redrawtext(settext
);
1409 charreport(settext
);
1417 /* otherwise, look for the last style used in the string */
1418 tc
= findcurfont(areawin
->textpos
, settext
->string
, areawin
->topinstance
);
1420 else tc
= areawin
->psfont
;
1422 /* Font change command will always find a value since at least one */
1423 /* font has to exist for the font menu button to exist. */
1425 if ((newfont
= (int)findbestfont(tc
, (short)value
, -1, -1)) < 0) return;
1427 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1428 Wprintf("Font is now %s", fonts
[newfont
].psname
);
1429 sprintf(_STR2
, "%d", newfont
);
1430 labeltext(FONT_NAME
, (char *)&newfont
);
1433 Wprintf("Default font is now %s", fonts
[newfont
].psname
);
1434 areawin
->psfont
= newfont
;
1437 if (w
!= NULL
) togglefontmark(newfont
);
1440 /*----------------------------------------------------------------*/
1441 /* Wrapper for routine setfontval() */
1442 /*----------------------------------------------------------------*/
1444 void setfont(xcWidget w
, pointertype value
, caddr_t calldata
)
1448 short labelcount
= 0;
1449 Boolean preselected
;
1451 if (eventmode
== CATALOG_MODE
|| eventmode
== FONTCAT_MODE
||
1452 eventmode
== EFONTCAT_MODE
) return;
1454 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1455 settext
= *((labelptr
*)EDITPART
);
1456 setfontval(w
, value
, settext
);
1457 charreport(settext
);
1460 if (areawin
->selects
== 0) {
1462 preselected
= FALSE
;
1464 else preselected
= TRUE
;
1465 areawin
->textpos
= 1;
1466 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
1467 areawin
->selects
; fselect
++) {
1468 if (SELECTTYPE(fselect
) == LABEL
) {
1470 settext
= SELTOLABEL(fselect
);
1471 setfontval(NULL
, value
, settext
);
1474 if (labelcount
== 0) setfontval(w
, value
, NULL
);
1475 else if (!preselected
) unselect_all();
1479 /*----------------------------------------------------------------*/
1480 /* Set the style (bold, italic, normal) for the font, similarly */
1481 /* to the above routine setfontval(). */
1482 /*----------------------------------------------------------------*/
1484 void setfontstyle(xcWidget w
, pointertype value
, labelptr settext
)
1490 if (settext
!= NULL
) {
1492 /* if last byte was a font designator, use it */
1494 if (areawin
->textpos
> 0 || areawin
->textpos
< stringlength(settext
->string
,
1495 True
, areawin
->topinstance
)) {
1496 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, settext
->string
,
1497 areawin
->topinstance
);
1498 if (strptr
->type
== FONT_NAME
) {
1499 tc
= strptr
->data
.font
;
1501 /* find font which matches family and style, if available */
1503 i
= findbestfont(tc
, -1, (short)value
, -1);
1505 undrawtext(settext
);
1506 strptr
->data
.font
= i
;
1507 redrawtext(settext
);
1509 charreport(settext
);
1511 togglefontstyles(w
);
1519 /* Otherwise, look for the last font used in the string */
1520 /* Fix by Dimitri Princen. Was areawin->textpos - 2; was there a */
1521 /* reason for that? */
1523 tc
= findcurfont(areawin
->textpos
, settext
->string
, areawin
->topinstance
);
1525 else tc
= areawin
->psfont
;
1527 if ((newfont
= (int)findbestfont(tc
, -1, (short)value
, -1)) < 0) return;
1529 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1530 Wprintf("Font is now %s", fonts
[newfont
].psname
);
1531 sprintf(_STR2
, "%d", newfont
);
1532 labeltext(FONT_NAME
, (char *)&newfont
);
1535 Wprintf("Default font is now %s", fonts
[newfont
].psname
);
1536 areawin
->psfont
= newfont
;
1539 toggleencodingmark(value
);
1541 togglefontstyles(w
);
1545 /*----------------------------------------------------------------*/
1546 /* Wrapper for routine setfontstyle() */
1547 /*----------------------------------------------------------------*/
1549 void fontstyle(xcWidget w
, pointertype value
, caddr_t nulldata
)
1553 short labelcount
= 0;
1554 Boolean preselected
;
1556 if (eventmode
== CATALOG_MODE
|| eventmode
== FONTCAT_MODE
||
1557 eventmode
== EFONTCAT_MODE
) return;
1559 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1560 settext
= *((labelptr
*)EDITPART
);
1561 setfontstyle(w
, value
, settext
);
1562 charreport(settext
);
1565 if (areawin
->selects
== 0) {
1567 preselected
= FALSE
;
1569 else preselected
= TRUE
;
1570 areawin
->textpos
= 1;
1571 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
1572 areawin
->selects
; fselect
++) {
1573 if (SELECTTYPE(fselect
) == LABEL
) {
1575 settext
= SELTOLABEL(fselect
);
1576 setfontstyle(NULL
, value
, settext
);
1579 if (labelcount
== 0) setfontstyle(w
, value
, NULL
);
1580 else if (!preselected
) unselect_all();
1584 /*----------------------------------------------------------------*/
1585 /* Set the encoding (standard, ISO-Latin1, special) for the font, */
1586 /* similarly to the above routine setfontval(). */
1587 /*----------------------------------------------------------------*/
1589 void setfontencoding(xcWidget w
, pointertype value
, labelptr settext
)
1595 if (settext
!= NULL
) {
1597 /* if last byte was a font designator, use it */
1599 if (areawin
->textpos
> 0 || areawin
->textpos
< stringlength(settext
->string
,
1600 True
, areawin
->topinstance
)) {
1601 strptr
= findstringpart(areawin
->textpos
- 1, NULL
, settext
->string
,
1602 areawin
->topinstance
);
1603 if (strptr
->type
== FONT_NAME
) {
1604 tc
= strptr
->data
.font
;
1606 i
= findbestfont(tc
, -1, -1, (short)value
);
1608 undrawtext(settext
);
1609 strptr
->data
.font
= i
;
1610 redrawtext(settext
);
1612 charreport(settext
);
1614 toggleencodingmark(value
);
1624 /* otherwise, look for the last style used in the string */
1625 tc
= findcurfont(areawin
->textpos
- 2, settext
->string
, areawin
->topinstance
);
1627 else tc
= areawin
->psfont
;
1629 if ((newfont
= (int)findbestfont(tc
, -1, -1, (short)value
)) < 0) return;
1631 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1632 Wprintf("Font is now %s", fonts
[newfont
].psname
);
1633 sprintf(_STR2
, "%d", newfont
);
1634 labeltext(FONT_NAME
, (char *)&newfont
);
1637 Wprintf("Default font is now %s", fonts
[newfont
].psname
);
1638 areawin
->psfont
= newfont
;
1646 /*----------------------------------------------------------------*/
1647 /* Wrapper for routine setfontencoding() */
1648 /*----------------------------------------------------------------*/
1650 void fontencoding(xcWidget w
, pointertype value
, caddr_t nulldata
)
1654 short labelcount
= 0;
1655 Boolean preselected
;
1657 if (eventmode
== CATALOG_MODE
|| eventmode
== FONTCAT_MODE
||
1658 eventmode
== EFONTCAT_MODE
) return;
1660 if (eventmode
== TEXT_MODE
|| eventmode
== ETEXT_MODE
) {
1661 settext
= *((labelptr
*)EDITPART
);
1662 setfontencoding(w
, value
, settext
);
1663 charreport(settext
);
1666 if (areawin
->selects
== 0) {
1668 preselected
= FALSE
;
1670 else preselected
= TRUE
;
1671 areawin
->textpos
= 1;
1672 for (fselect
= areawin
->selectlist
; fselect
< areawin
->selectlist
+
1673 areawin
->selects
; fselect
++) {
1674 if (SELECTTYPE(fselect
) == LABEL
) {
1676 settext
= SELTOLABEL(fselect
);
1677 setfontencoding(NULL
, value
, settext
);
1680 if (labelcount
== 0) setfontencoding(w
, value
, NULL
);
1681 else if (!preselected
) unselect_all();
1685 /*----------------------------------------------*/
1686 /* Generate the table of special characters */
1688 /* Return FALSE if the edited label is LaTeX- */
1689 /* compatible, since LaTeX text does not */
1690 /* usually contain special characters, but it */
1691 /* does contain a lot of backslashes. */
1692 /*----------------------------------------------*/
1699 curlabel
= TOLABEL(EDITPART
);
1700 if (curlabel
->anchor
& LATEXLABEL
) return False
;
1702 cfont
= findcurfont(areawin
->textpos
, curlabel
->string
, areawin
->topinstance
);
1703 composefontlib(cfont
);
1704 startcatalog(NULL
, FONTLIB
, NULL
);
1708 /*-------------------------------------------------------------------------*/