447
/* Don't use areastruct.areawin; if called from inside an object */
448
/* (e.g., "here" in a Tcl expression), areastruct.areawin will be */
449
/* an off-screen pixmap, and cause a crash. */
451
XQueryPointer(dpy, Tk_WindowId(areastruct.area), &nullwin, &nullwin,
452
&nullint, &nullint, &xpos, &ypos, &nullui);
454
XQueryPointer_TkW32(dpy, Tk_WindowId(areastruct.area), &nullwin, &nullwin,
455
&nullint, &nullint, &xpos, &ypos, &nullui);
424
458
XQueryPointer(dpy, areastruct.areawin, &nullwin, &nullwin, &nullint,
425
459
&nullint, &xpos, &ypos, &nullui);
849
888
/* Calculate the bounding box of an object instance */
850
889
/*----------------------------------------------------------------------*/
852
void objinstbbox(objinstptr obbox, XPoint *npoints)
891
void objinstbbox(objinstptr obbox, XPoint *npoints, Boolean expand)
854
893
XPoint points[4];
894
int extend = (expand) ? 4 : 0;
856
points[0].x = points[1].x = obbox->bbox.lowerleft.x;
857
points[1].y = points[2].y = obbox->bbox.lowerleft.y + obbox->bbox.height;
858
points[2].x = points[3].x = obbox->bbox.lowerleft.x + obbox->bbox.width;
859
points[0].y = points[3].y = obbox->bbox.lowerleft.y;
896
points[0].x = points[1].x = obbox->bbox.lowerleft.x - extend;
897
points[1].y = points[2].y = obbox->bbox.lowerleft.y + obbox->bbox.height
899
points[2].x = points[3].x = obbox->bbox.lowerleft.x + obbox->bbox.width
901
points[0].y = points[3].y = obbox->bbox.lowerleft.y - extend;
861
903
UTransformPoints(points, npoints, 4, obbox->position,
862
904
obbox->scale, obbox->rotation);
883
925
+ tmpext.descent;
884
926
points[1].y = points[2].y = points[0].y + tmpext.ascent - tmpext.descent;
887
928
/* separate bounding box for pinlabels and infolabels */
890
931
for (j = 0; j < 4; j++)
891
932
pinadjust(labox->justify, &points[j].x, &points[j].y, 1);
894
934
UTransformPoints(points, npoints, 4, labox->position,
895
935
labox->scale, labox->rotation);
938
/*----------------------------------------------------------------------*/
939
/* Calculate the bounding box of a graphic image */
940
/*----------------------------------------------------------------------*/
942
void graphicbbox(graphicptr gp, XPoint *npoints)
945
int hw = gp->source->width >> 1;
946
int hh = gp->source->height >> 1;
948
points[1].x = points[2].x = hw;
949
points[0].x = points[3].x = -hw;
951
points[0].y = points[1].y = -hh;
952
points[2].y = points[3].y = hh;
954
UTransformPoints(points, npoints, 4, gp->position,
955
gp->scale, gp->rotation);
898
958
/*--------------------------------------------------------------*/
899
959
/* Wrapper for single call to calcbboxsingle() in the netlister */
900
960
/*--------------------------------------------------------------*/
938
/* because a pin is offset from its position point, include */
939
/* that point in the bounding box. */
941
if (TOLABEL(bboxgen)->pin) {
942
bboxcalc(TOLABEL(bboxgen)->position.x, llx, urx);
943
bboxcalc(TOLABEL(bboxgen)->position.y, lly, ury);
946
labelbbox(TOLABEL(bboxgen), npoints, thisinst);
948
for (j = 0; j < 4; j++) {
949
bboxcalc(npoints[j].x, llx, urx);
950
bboxcalc(npoints[j].y, lly, ury);
996
/* because a pin is offset from its position point, include */
997
/* that point in the bounding box. */
999
if (TOLABEL(bboxgen)->pin) {
1000
bboxcalc(TOLABEL(bboxgen)->position.x, llx, urx);
1001
bboxcalc(TOLABEL(bboxgen)->position.y, lly, ury);
1003
labelbbox(TOLABEL(bboxgen), npoints, thisinst);
1005
for (j = 0; j < 4; j++) {
1006
bboxcalc(npoints[j].x, llx, urx);
1007
bboxcalc(npoints[j].y, lly, ury);
1012
graphicbbox(TOGRAPHIC(bboxgen), npoints);
1013
for (j = 0; j < 4; j++) {
1014
bboxcalc(npoints[j].x, llx, urx);
1015
bboxcalc(npoints[j].y, lly, ury);
955
1020
genericptr *pathc;
1130
1184
/* takes the default value. */
1131
1185
/*--------------------------------------------------------------*/
1133
void updateinstparam(objectptr bobj, int mode)
1187
void updateinstparam(objectptr bobj)
1136
1190
objectptr pageobj;
1138
/* this is a modified version of updatepagebounds() */
1139
/* mode == 0: change bounds on pagelib and the page */
1140
/* containing this object *instance* */
1143
/* pick up calling object and instance from the edit stack */
1144
objinstptr pinst = areastruct.stack->thisinst;
1146
pageobj = pinst->thisobject;
1148
for (j = 0; j < pageobj->parts; j++)
1149
if (*(pageobj->plist + j) == (genericptr)pinst) break;
1150
if (j == pageobj->parts) {
1151
Fprintf(stderr, "Error: Calling page does not contain expected objinst!\n");
1154
calcbboxvalues(pinst, (genericptr *)(pageobj->plist + j));
1155
for (i = 0; i < xobjs.pages; i++) {
1156
if (xobjs.pagelist[i]->pageinst != NULL) {
1157
if (xobjs.pagelist[i]->pageinst->thisobject == pageobj) {
1158
updatepagelib(PAGELIB, i);
1163
if (i == xobjs.pages)
1164
Fprintf(stderr, "Error: Calling page not found!\n");
1167
/* mode == 1: change bounds on pagelib and all pages */
1168
/* containing this *object* if and only if the object */
1169
/* instance takes the default value. Also update the */
1173
for (i = 0; i < xobjs.pages; i++)
1174
if (xobjs.pagelist[i]->pageinst != NULL) {
1175
pageobj = xobjs.pagelist[i]->pageinst->thisobject;
1176
if ((j = find_object(pageobj, topobject)) >= 0) {
1178
/* Really, we'd like to recalculate the bounding box only if the */
1179
/* parameter value is the default value which was just changed. */
1180
/* However, then any non-default values may contain the wrong */
1181
/* substitutions. */
1183
objinstptr cinst = TOOBJINST(pageobj->plist + j);
1184
if (cinst->thisobject->num_params == 0) {
1185
calcbboxvalues(xobjs.pagelist[i]->pageinst, pageobj->plist + j);
1186
updatepagelib(PAGELIB, i);
1191
for (i = 0; i < xobjs.numlibs; i++)
1192
if (object_in_library(i, topobject))
1193
composelib(i + LIBRARY);
1192
/* change bounds on pagelib and all pages */
1193
/* containing this *object* if and only if the object */
1194
/* instance takes the default value. Also update the */
1197
for (i = 0; i < xobjs.pages; i++)
1198
if (xobjs.pagelist[i]->pageinst != NULL) {
1199
pageobj = xobjs.pagelist[i]->pageinst->thisobject;
1200
if ((j = find_object(pageobj, topobject)) >= 0) {
1202
/* Really, we'd like to recalculate the bounding box only if the */
1203
/* parameter value is the default value which was just changed. */
1204
/* However, then any non-default values may contain the wrong */
1205
/* substitutions. */
1207
objinstptr cinst = TOOBJINST(pageobj->plist + j);
1208
if (cinst->thisobject->params == NULL) {
1209
calcbboxvalues(xobjs.pagelist[i]->pageinst, pageobj->plist + j);
1210
updatepagelib(PAGELIB, i);
1215
for (i = 0; i < xobjs.numlibs; i++)
1216
if (object_in_library(i, topobject))
1217
composelib(i + LIBRARY);
1197
1220
/*--------------------------------------------------------------*/
1450
1481
void UDrawXAt(XPoint *wpt)
1452
XSetLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapButt, JoinMiter);
1453
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wpt->x - 3,
1483
SetThinLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapButt, JoinMiter);
1484
DrawLine(dpy, areastruct.areawin, areastruct.gc, wpt->x - 3,
1454
1485
wpt->y - 3, wpt->x + 3, wpt->y + 3);
1455
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wpt->x + 3,
1486
DrawLine(dpy, areastruct.areawin, areastruct.gc, wpt->x + 3,
1456
1487
wpt->y - 3, wpt->x - 3, wpt->y + 3);
1638
1671
XPoint upt, vpt;
1640
XSetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
1641
XSetFunction(dpy, areastruct.gc, GXxor);
1673
SetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
1674
SetFunction(dpy, areastruct.gc, GXxor);
1643
1676
user_to_window(cpt, &upt);
1644
1677
user_to_window(opt, &vpt);
1646
XSetLineAttributes(dpy, areastruct.gc, 0, LineOnOffDash, CapButt, JoinMiter);
1647
XDrawLine(dpy, areastruct.areawin, areastruct.gc, vpt.x, vpt.y, upt.x, upt.y);
1679
SetThinLineAttributes(dpy, areastruct.gc, 0, LineOnOffDash, CapButt, JoinMiter);
1680
DrawLine(dpy, areastruct.areawin, areastruct.gc, vpt.x, vpt.y, upt.x, upt.y);
1649
XSetLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapButt, JoinMiter);
1650
XDrawLine(dpy, areastruct.areawin, areastruct.gc, upt.x - 3, upt.y - 3,
1682
SetThinLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapButt, JoinMiter);
1683
DrawLine(dpy, areastruct.areawin, areastruct.gc, upt.x - 3, upt.y - 3,
1651
1684
upt.x + 3, upt.y + 3);
1652
XDrawLine(dpy, areastruct.areawin, areastruct.gc, upt.x + 3, upt.y - 3,
1685
DrawLine(dpy, areastruct.areawin, areastruct.gc, upt.x + 3, upt.y - 3,
1653
1686
upt.x - 3, upt.y + 3);
1655
XSetFunction(dpy, areastruct.gc, areastruct.gctype);
1656
XSetForeground(dpy, areastruct.gc, areastruct.gccolor);
1688
SetFunction(dpy, areastruct.gc, areastruct.gctype);
1689
SetForeground(dpy, areastruct.gc, areastruct.gccolor);
1659
1692
/*-------------------------------------------------------------------------*/
1665
1698
user_to_window(origin, &worig);
1666
1699
user_to_window(corner, &wcorn);
1668
XSetFunction(dpy, areastruct.gc, GXxor);
1669
XSetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
1670
XSetLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapRound, JoinBevel);
1701
SetFunction(dpy, areastruct.gc, GXxor);
1702
SetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
1703
SetThinLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapRound, JoinBevel);
1672
XDrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, worig.y,
1705
DrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, worig.y,
1673
1706
worig.x, wcorn.y);
1674
XDrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, wcorn.y,
1707
DrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, wcorn.y,
1675
1708
wcorn.x, wcorn.y);
1676
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, wcorn.y,
1709
DrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, wcorn.y,
1677
1710
wcorn.x, worig.y);
1678
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, worig.y,
1711
DrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, worig.y,
1679
1712
worig.x, worig.y);
1715
/*----------------------------------------------------------------------*/
1716
/* Draw a box indicating the dimensions of the edit element that most */
1717
/* closely reach the position "corner". */
1718
/*----------------------------------------------------------------------*/
1720
void UDrawRescaleBox(XPoint *corner)
1722
XPoint origpoints[5], newpoints[5];
1724
float savescale, newscale, lastscale, tempscale;
1725
long mindist, testdist, lastmindist;
1729
/* To be done---draw a box around each selected part, not */
1730
/* just the first one. */
1732
SetFunction(dpy, areastruct.gc, GXxor);
1733
SetForeground(dpy, areastruct.gc, AUXCOLOR ^ BACKGROUND);
1734
SetThinLineAttributes(dpy, areastruct.gc, 0, LineSolid, CapRound, JoinBevel);
1736
for (j = 0; j < areastruct.selects; j++) {
1737
rgen = SELTOGENERIC(areastruct.selectlist + j);
1739
switch(ELEMENTTYPE(rgen)) {
1741
rlab = (labelptr)rgen;
1742
savescale = rlab->scale;
1743
newscale = lastscale = rlab->scale * 2;
1745
while (mindist > 4) {
1746
rlab->scale = newscale;
1747
labelbbox(rlab, newpoints, areastruct.topinstance);
1748
newpoints[5] = newpoints[0];
1749
lastmindist = mindist;
1751
for (i = 0; i < 4; i++) {
1752
testdist = finddist(&newpoints[i], &newpoints[i+1], corner);
1753
if (testdist < mindist)
1756
if (mindist == lastmindist)
1758
else if (lastmindist == LONG_MAX)
1761
tempscale = (fabs)((newscale * lastmindist) - (lastscale * mindist)) /
1762
(abs)(lastmindist - mindist);
1763
lastscale = newscale;
1764
newscale = tempscale;
1767
rlab->scale = savescale;
1773
/* Note: should be able to handle other elements, as well */
1776
UTransformbyCTM(DCTM, newpoints, origpoints, 4);
1777
strokepath(origpoints, 4, 0, 1);
1682
1781
/*-------------------------------------------------------------------------*/
1683
1782
void UDrawBBox()
1692
1791
corner.x = origin.x + bbinst->bbox.width;
1693
1792
corner.y = origin.y + bbinst->bbox.height;
1696
1794
/* Include any schematic labels in the bounding box. */
1697
1795
extendschembbox(bbinst, &origin, &corner);
1700
1797
user_to_window(origin, &worig);
1701
1798
user_to_window(corner, &wcorn);
1703
XSetForeground(dpy, areastruct.gc, BBOXCOLOR);
1704
XDrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, worig.y,
1800
SetForeground(dpy, areastruct.gc, BBOXCOLOR);
1801
DrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, worig.y,
1705
1802
worig.x, wcorn.y);
1706
XDrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, wcorn.y,
1803
DrawLine(dpy, areastruct.areawin, areastruct.gc, worig.x, wcorn.y,
1707
1804
wcorn.x, wcorn.y);
1708
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, wcorn.y,
1805
DrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, wcorn.y,
1709
1806
wcorn.x, worig.y);
1710
XDrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, worig.y,
1807
DrawLine(dpy, areastruct.areawin, areastruct.gc, wcorn.x, worig.y,
1711
1808
worig.x, worig.y);
1720
1817
char solidpart;
1721
1818
char dashstring[3];
1724
tmpwidth = max(1, UTopTransScale(xobjs.pagelist[areastruct.page]->wirewidth *
1822
tmpwidth = UTopTransScale(xobjs.pagelist[areastruct.page]->wirewidth * width);
1823
minwidth = max(1, (short)tmpwidth);
1727
1825
if (style & FILLED || (!(style & FILLED) && style & OPAQUE)) {
1728
1826
if ((style & FILLSOLID) == FILLSOLID)
1729
XSetFillStyle(dpy, areastruct.gc, FillSolid);
1827
SetFillStyle(dpy, areastruct.gc, FillSolid);
1730
1828
else if (!(style & FILLED)) {
1731
XSetFillStyle(dpy, areastruct.gc, FillOpaqueStippled);
1732
XSetStipple(dpy, areastruct.gc, STIPPLE[7]);
1829
SetFillStyle(dpy, areastruct.gc, FillOpaqueStippled);
1830
SetStipple(dpy, areastruct.gc, 7);
1735
1833
if (style & OPAQUE)
1736
XSetFillStyle(dpy, areastruct.gc, FillOpaqueStippled);
1834
SetFillStyle(dpy, areastruct.gc, FillOpaqueStippled);
1738
XSetFillStyle(dpy, areastruct.gc, FillStippled);
1739
XSetStipple(dpy, areastruct.gc, STIPPLE[ (style &
1836
SetFillStyle(dpy, areastruct.gc, FillStippled);
1837
SetStipple(dpy, areastruct.gc, ((style & FILLSOLID) >> 5));
1742
XFillPolygon(dpy, areastruct.areawin, areastruct.gc, pathlist, number, Nonconvex,
1839
FillPolygon(dpy, areastruct.areawin, areastruct.gc, pathlist, number, Nonconvex,
1743
1840
CoordModeOrigin);
1744
1841
/* return to original state */
1745
XSetFillStyle(dpy, areastruct.gc, FillSolid);
1842
SetFillStyle(dpy, areastruct.gc, FillSolid);
1747
1844
if (!(style & NOBORDER)) {
1748
1845
/* set up dots or dashes */
1749
if (style & DASHED) solidpart = (char)(4 * tmpwidth);
1750
else if (style & DOTTED) solidpart = (char)tmpwidth;
1751
sprintf(dashstring, "%c%c", solidpart, (char)(4 * tmpwidth));
1846
if (style & DASHED) solidpart = (char)(4 * minwidth);
1847
else if (style & DOTTED) solidpart = (char)minwidth;
1848
sprintf(dashstring, "%c%c", solidpart, (char)(4 * minwidth));
1752
1849
if (style & (DASHED | DOTTED)) {
1753
XSetDashes(dpy, areastruct.gc, 0, dashstring, 2);
1754
XSetLineAttributes(dpy, areastruct.gc, tmpwidth >= 2.0 ?
1755
(int)tmpwidth : 0, LineOnOffDash, CapButt, JoinBevel);
1850
SetDashes(dpy, areastruct.gc, 0, dashstring, 2);
1851
SetLineAttributes(dpy, areastruct.gc, tmpwidth, LineOnOffDash,
1852
CapButt, JoinMiter);
1758
XSetLineAttributes(dpy, areastruct.gc, tmpwidth >= 2.0 ?
1759
(int)tmpwidth : 0, LineSolid, CapRound, JoinBevel);
1855
SetLineAttributes(dpy, areastruct.gc, tmpwidth, LineSolid,
1856
(style & SQUARECAP) ? CapProjecting : CapRound, JoinMiter);
1761
1858
/* draw the spline and close off if so specified */
1762
XDrawLines(dpy, areastruct.areawin, areastruct.gc, pathlist,
1859
DrawLines(dpy, areastruct.areawin, areastruct.gc, pathlist,
1763
1860
number, CoordModeOrigin);
1764
1861
if (!(style & UNCLOSED))
1765
XDrawLine(dpy, areastruct.areawin, areastruct.gc, pathlist[0].x,
1862
DrawLine(dpy, areastruct.areawin, areastruct.gc, pathlist[0].x,
1766
1863
pathlist[0].y, pathlist[number - 1].x, pathlist[number - 1].y);
1891
1989
/* do a quick test for intersection with the display window */
1893
UTransformbyCTM(DCTM, &(theobject->bbox.lowerleft), &(bboxout[0]), 1);
1894
bboxin.x = theobject->bbox.lowerleft.x + theobject->bbox.width;
1895
bboxin.y = theobject->bbox.lowerleft.y + theobject->bbox.height;
1896
UTransformbyCTM(DCTM, &bboxin, &(bboxout[1]), 1);
1991
bboxin[0].x = theobject->bbox.lowerleft.x;
1992
bboxin[0].y = theobject->bbox.lowerleft.y;
1993
bboxin[1].x = theobject->bbox.lowerleft.x + theobject->bbox.width;
1994
bboxin[1].y = theobject->bbox.lowerleft.y + theobject->bbox.height;
1996
extendschembbox(theinstance, &(bboxin[0]), &(bboxin[1]));
1997
UTransformbyCTM(DCTM, bboxin, bboxout, 2);
1898
1999
xm = (bboxout[0].x < bboxout[1].x) ? 0 : 1;
1899
2000
ym = (bboxout[0].y < bboxout[1].y) ? 0 : 1;
1907
2008
/* draw all of the elements */
1909
2010
tmpwidth = UTopTransScale(xobjs.pagelist[areastruct.page]->wirewidth);
1910
XSetLineAttributes(dpy, areastruct.gc, tmpwidth >= 2.0 ? (int)tmpwidth :
1911
0, LineSolid, CapRound, JoinBevel);
1913
for (areagen = theobject->plist; areagen < theobject->plist +
1914
theobject->parts; areagen++) {
2011
SetLineAttributes(dpy, areastruct.gc, tmpwidth, LineSolid, CapRound,
2014
/* guard against plist being regenerated during a redraw by the */
2015
/* expression parameter mechanism (should that be prohibited?) */
2017
for (thispart = 0; thispart < theobject->parts; thispart++) {
2018
areagen = theobject->plist + thispart;
2019
if ((*areagen)->type & DRAW_HIDE) continue;
1916
2021
if (defaultcolor != DOFORALL) {
1917
2022
if ((*areagen)->color != curcolor) {
1982
2088
if (stack) pop_stack(stack);
1985
/*-------------------------------------------------------------------------*/
2091
/*----------------------------------------------------------------------*/
2092
/* Recursively run through the current page and find any labels which */
2093
/* are declared to be style LATEX. If "checkonly" is present, we set */
2094
/* it to TRUE or FALSE depending on whether or not LATEX labels have */
2095
/* been encountered. If NULL, then we write LATEX output appropriately */
2096
/* to a file named with the page filename + suffix ".tex". */
2097
/*----------------------------------------------------------------------*/
2099
void UDoLatex(objinstptr theinstance, short level, FILE *f,
2100
float scale, int tx, int ty, Boolean *checkonly)
2105
genericptr *areagen;
2106
objectptr theobject = theinstance->thisobject;
2112
UPreMultCTM(DCTM, theinstance->position, theinstance->scale,
2113
theinstance->rotation);
2115
/* make parameter substitutions */
2116
psubstitute(theinstance);
2118
/* find all of the elements */
2120
for (areagen = theobject->plist; areagen < theobject->plist +
2121
theobject->parts; areagen++) {
2123
switch(ELEMENTTYPE(*areagen)) {
2125
UDoLatex(TOOBJINST(areagen), level + 1, f, scale, tx, ty, checkonly);
2129
thislabel = TOLABEL(areagen);
2130
if (level == 0 || thislabel->pin == False ||
2131
(thislabel->justify & PINVISIBLE))
2132
if (thislabel->justify & LATEXLABEL) {
2138
lpos.x = thislabel->position.x;
2139
lpos.y = thislabel->position.y;
2140
UTransformbyCTM(DCTM, &lpos, &xlpos, 1);
2143
xfpos.x = (float)xlpos.x * scale;
2144
xfpos.y = (float)xlpos.y * scale;
2151
ltext = textprint(thislabel->string, theinstance);
2152
tbjust = thislabel->justify & (NOTBOTTOM | TOP);
2153
lrjust = thislabel->justify & (NOTLEFT | RIGHT);
2154
fprintf(f, "\\putbox{%3.2fin}{%3.2fin}{",
2156
if (lrjust == (NOTLEFT | RIGHT)) fprintf(f, "\\rightbox{");
2157
else if (lrjust == NOTLEFT) fprintf(f, "\\centbox{");
2158
if (tbjust == (NOTBOTTOM | TOP)) fprintf(f, "\\topbox{");
2159
else if (tbjust == NOTBOTTOM) fprintf(f, "\\midbox{");
2160
fprintf(f, "%s", ltext);
2161
if (lrjust != NORMAL) fprintf(f, "}");
2162
if (tbjust != NORMAL) fprintf(f, "}");
2163
fprintf(f, "}%%\n");
2173
/*----------------------------------------------------------------------*/
2174
/* Top level routine for writing LATEX output. */
2175
/*----------------------------------------------------------------------*/
2181
int tx, ty, width, height;
2183
Boolean checklatex = FALSE;
2186
UDoLatex(areastruct.topinstance, 0, NULL, 1.0, 0, 0, &checklatex);
2188
if (checklatex == FALSE) return; /* No LaTeX labels to write */
2190
sprintf(filename, "%s.tex", xobjs.pagelist[areastruct.page]->filename);
2191
f = fopen(filename, "w");
2193
fprintf(f, "%% XCircuit output \"%s\" for LaTeX input from %s.ps\n",
2194
filename, xobjs.pagelist[areastruct.page]->filename);
2195
fprintf(f, "\\def\\putbox#1#2#3{\\makebox[0in][l]{\\makebox[#1][l]{}"
2196
"\\raisebox{\\baselineskip}[0in][0in]"
2197
"{\\raisebox{#2}[0in][0in]{#3}}}}\n");
2198
fprintf(f, "\\def\\rightbox#1{\\makebox[0in][r]{#1}}\n");
2199
fprintf(f, "\\def\\centbox#1{\\makebox[0in]{#1}}\n");
2200
fprintf(f, "\\def\\topbox#1{\\raisebox{-\\baselineskip}[0in][0in]{#1}}\n");
2201
fprintf(f, "\\def\\midbox#1{\\raisebox{-0.5\\baselineskip}[0in][0in]{#1}}\n");
2202
fprintf(f, "\\begin{flushleft}\n");
2204
filename[strlen(filename) - 4] = '\0';
2205
if (strchr(filename, '.') == NULL)
2206
sprintf(filename + strlen(filename), ".ps");
2208
fprintf(f, "\\epsfig{file=%s}\\\\\n", filename);
2210
psscale = getpsscale(xobjs.pagelist[areastruct.page]->outscale,
2213
width = toplevelwidth(areastruct.topinstance, &origin.x);
2214
height = toplevelheight(areastruct.topinstance, &origin.y);
2216
tx = (int)(72 / psscale) - origin.x,
2217
ty = (int)(72 / psscale) - origin.y;
2219
fprintf(f, "%% translate x=%d y=%d scale %3.2f\n", tx, ty, psscale);
2221
UPushCTM(); /* Save current state */
2222
UResetCTM(DCTM); /* Set to identity matrix */
2223
UDoLatex(areastruct.topinstance, 0, f, psscale, tx, ty, NULL);
2224
UPopCTM(); /* Restore state */
2226
fprintf(f, "\\end{flushleft}\n");