Reworked the way that magic displays measurement values (both linear
and area) so that they are consistent across commands. The default behavior remains the same, for backwards compatibility. However, a new "units" command has been added, so that "units microns" results in measurements always being displayed in microns, with choice of that or "internal", "lambda", or "grid". The units themselves may be printed (for interactive use) or not (for scripted use). The use of "units" is independent of "snap", after overriding the default behavior, so that units parsed on the command line are interpreted according to "units", not to "snap".
This commit is contained in:
parent
8822f8dce2
commit
81436b75ed
146
commands/CmdAB.c
146
commands/CmdAB.c
|
|
@ -338,14 +338,17 @@ CmdArray(
|
|||
case ARRAY_WIDTH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xsepvalue;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xsepvalue = DBWPrintValue(la->arrayInfo.ar_xsep,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_xsep));
|
||||
Tcl_NewStringObj(xsepvalue, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -355,7 +358,7 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x separation %d\n", la->arrayInfo.ar_xsep);
|
||||
TxPrintf("x separation %s\n", xsepvalue);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -374,14 +377,17 @@ CmdArray(
|
|||
case ARRAY_HEIGHT:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *ysepvalue;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
ysepvalue = DBWPrintValue(la->arrayInfo.ar_ysep,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_ysep));
|
||||
Tcl_NewStringObj(ysepvalue, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -391,7 +397,7 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
|
||||
TxPrintf("y separation %s\n", ysepvalue);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -410,16 +416,21 @@ CmdArray(
|
|||
case ARRAY_PITCH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xpitch, *ypitch;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xpitch = DBWPrintValue(la->arrayInfo.ar_xsep,
|
||||
w, TRUE);
|
||||
ypitch = DBWPrintValue(la->arrayInfo.ar_ysep,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_xsep));
|
||||
Tcl_NewStringObj(xpitch, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_ysep));
|
||||
Tcl_NewStringObj(ypitch, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -429,8 +440,8 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x separation %d ", la->arrayInfo.ar_xsep);
|
||||
TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
|
||||
TxPrintf("x separation %s ", xpitch);
|
||||
TxPrintf("y separation %s\n", ypitch);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -450,16 +461,21 @@ CmdArray(
|
|||
case ARRAY_POSITION:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xpos, *ypos;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xpos = DBWPrintValue(la->cellUse->cu_bbox.r_xbot,
|
||||
w, TRUE);
|
||||
ypos = DBWPrintValue(la->cellUse->cu_bbox.r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->cellUse->cu_bbox.r_xbot));
|
||||
Tcl_NewStringObj(xpos, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->cellUse->cu_bbox.r_ybot));
|
||||
Tcl_NewStringObj(ypos, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -469,8 +485,8 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x=%d ", la->cellUse->cu_bbox.r_xbot);
|
||||
TxPrintf("y=%d\n", la->cellUse->cu_bbox.r_ybot);
|
||||
TxPrintf("x=%s ", xpos);
|
||||
TxPrintf("y=%s\n", ypos);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -874,13 +890,16 @@ CmdBox(
|
|||
TxRebuildCommand(cmd);
|
||||
return;
|
||||
}
|
||||
else if (DBWSnapToGrid != DBW_SNAP_USER)
|
||||
else if (DBWUnits != DBW_UNITS_USER)
|
||||
{
|
||||
distancex = cmdParseCoord(w, cmd->tx_argv[3], TRUE, FALSE);
|
||||
distancey = distancex;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For user units, the distance may be different in the X and Y
|
||||
* directions for a given value.
|
||||
*/
|
||||
switch (direction)
|
||||
{
|
||||
case GEO_EAST: case GEO_WEST:
|
||||
|
|
@ -908,15 +927,14 @@ CmdBox(
|
|||
case BOX_WIDTH:
|
||||
if (argc == 2)
|
||||
{
|
||||
char *boxvalues;
|
||||
boxvalues = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d",
|
||||
boxptr->r_xtop - boxptr->r_xbot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1));
|
||||
#else
|
||||
TxPrintf("%s box width is %d\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xtop - boxptr->r_xbot);
|
||||
TxPrintf("%s box width is %s\n", (refEdit) ? "Edit" : "Root",
|
||||
boxvalues);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -928,15 +946,14 @@ CmdBox(
|
|||
case BOX_HEIGHT:
|
||||
if (argc == 2)
|
||||
{
|
||||
char *boxvalues;
|
||||
boxvalues = DBWPrintValue(boxptr->r_ytop - boxptr->r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d",
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1));
|
||||
#else
|
||||
TxPrintf("%s box height is %d\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
TxPrintf("%s box height is %s\n", (refEdit) ? "Edit" : "Root",
|
||||
boxvalues);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -949,16 +966,24 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d",
|
||||
boxptr->r_xtop - boxptr->r_xbot,
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluex, *boxvaluey;
|
||||
boxvaluex = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot,
|
||||
w, TRUE);
|
||||
boxvaluey = DBWPrintValue(boxptr->r_ytop - boxptr->r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluex, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluey, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box size is %d x %d\n",
|
||||
TxPrintf("%s box size is %s x %s\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xtop - boxptr->r_xbot,
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
boxvaluex, boxvaluey);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -973,14 +998,22 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d",
|
||||
boxptr->r_xbot, boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluex, *boxvaluey;
|
||||
boxvaluex = DBWPrintValue(boxptr->r_xbot, w, TRUE);
|
||||
boxvaluey = DBWPrintValue(boxptr->r_ybot, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluex, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluey, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box lower-left corner at (%d, %d)\n",
|
||||
TxPrintf("%s box lower-left corner at (%s, %s)\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xbot, boxptr->r_ybot);
|
||||
boxvaluex, boxvaluey);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -1012,16 +1045,31 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d %d %d",
|
||||
boxptr->r_xbot, boxptr->r_ybot,
|
||||
boxptr->r_xtop, boxptr->r_ytop);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluellx, *boxvaluelly;
|
||||
char *boxvalueurx, *boxvalueury;
|
||||
|
||||
boxvaluellx = DBWPrintValue(boxptr->r_xbot, w, TRUE);
|
||||
boxvaluelly = DBWPrintValue(boxptr->r_ybot, w, FALSE);
|
||||
boxvalueurx = DBWPrintValue(boxptr->r_xtop, w, TRUE);
|
||||
boxvalueury = DBWPrintValue(boxptr->r_ytop, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluellx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluelly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvalueurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvalueury, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box coordinates (%d, %d) to (%d, %d)\n",
|
||||
TxPrintf("%s box coordinates (%s, %s) to (%s, %s)\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xbot, boxptr->r_ybot,
|
||||
boxptr->r_xtop, boxptr->r_ytop);
|
||||
boxvaluellx, boxvaluelly, boxvalueurx, boxvalueury);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1122,12 +1122,13 @@ CmdExtract(
|
|||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
char *halodisp;
|
||||
halodisp = DBWPrintValue(ExtCurStyle->exts_sideCoupleHalo,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_sideCoupleHalo);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(halodisp, -1));
|
||||
#else
|
||||
TxPrintf("Side overlap halo is %d\n", ExtCurStyle->exts_sideCoupleHalo);
|
||||
TxPrintf("Side overlap halo is %s\n", halodisp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -1152,12 +1153,12 @@ CmdExtract(
|
|||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
char *stepdisp;
|
||||
stepdisp = DBWPrintValue(ExtCurStyle->exts_stepSize, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_stepSize);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(stepdisp, -1));
|
||||
#else
|
||||
TxPrintf("Extraction step size is %d\n", ExtCurStyle->exts_stepSize);
|
||||
TxPrintf("Extraction step size is %s\n", stepdisp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1084,25 +1084,33 @@ CmdSelect(
|
|||
*/
|
||||
|
||||
case SEL_BBOX:
|
||||
{
|
||||
char *selllx, *sellly, *selurx, *selury;
|
||||
|
||||
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea);
|
||||
|
||||
selllx = DBWPrintValue(selarea.r_xbot, w, TRUE);
|
||||
sellly = DBWPrintValue(selarea.r_ybot, w, FALSE);
|
||||
selurx = DBWPrintValue(selarea.r_xtop, w, TRUE);
|
||||
selury = DBWPrintValue(selarea.r_ytop, w, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_xbot));
|
||||
Tcl_NewStringObj(selllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_ybot));
|
||||
Tcl_NewStringObj(sellly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_xtop));
|
||||
Tcl_NewStringObj(selurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_ytop));
|
||||
Tcl_NewStringObj(selury, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Select bounding box: %d %d %d %d\n",
|
||||
selarea.r_xbot, selarea.r_ybot,
|
||||
selarea.r_xtop, selarea.r_ytop);
|
||||
TxPrintf("Select bounding box: %s %s %s %s\n",
|
||||
selllx, sellly, selurx, selury);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Make a copy of the selection at its present loction but do not
|
||||
|
|
@ -1985,23 +1993,25 @@ cmdLabelRectFunc(
|
|||
|
||||
if (rect == NULL)
|
||||
{
|
||||
char *labllx, *lablly, *laburx, *labury;
|
||||
|
||||
/* Note: Ideally, the MagWindow pointer should be passed to this function */
|
||||
labllx = DBWPrintValue(label->lab_rect.r_xbot, (MagWindow *)NULL, TRUE);
|
||||
lablly = DBWPrintValue(label->lab_rect.r_ybot, (MagWindow *)NULL, FALSE);
|
||||
laburx = DBWPrintValue(label->lab_rect.r_xtop, (MagWindow *)NULL, TRUE);
|
||||
labury = DBWPrintValue(label->lab_rect.r_ytop, (MagWindow *)NULL, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_GetObjResult(magicinterp);
|
||||
pobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_xbot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_ybot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_xtop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_ytop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(lablly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laburx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labury, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("%d %d %d %d\n",
|
||||
label->lab_rect.r_xbot, label->lab_rect.r_ybot,
|
||||
label->lab_rect.r_xtop, label->lab_rect.r_ytop);
|
||||
TxPrintf("%s %s %s %s\n", labllx, lablly, laburx,labury);
|
||||
#endif
|
||||
}
|
||||
else if (!GEO_SAMERECT(label->lab_rect, *rect))
|
||||
|
|
@ -2317,11 +2327,13 @@ CmdSetLabel(
|
|||
{
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *labsize;
|
||||
|
||||
labsize = DBWPrintValue(DefaultLabel->lab_size, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_size));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(labsize, -1));
|
||||
#else
|
||||
TxPrintf("%d\n", DefaultLabel->lab_size);
|
||||
TxPrintf("%s\n", labsize);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -2360,16 +2372,20 @@ CmdSetLabel(
|
|||
{
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *laboffx, *laboffy;
|
||||
laboffx = DBWPrintValue(DefaultLabel->lab_offset.p_x, w,
|
||||
TRUE);
|
||||
laboffy = DBWPrintValue(DefaultLabel->lab_offset.p_y, w,
|
||||
FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_offset.p_x));
|
||||
Tcl_NewStringObj(laboffx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_offset.p_y));
|
||||
Tcl_NewStringObj(laboffy, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("%d %d\n", DefaultLabel->lab_offset.p_x,
|
||||
DefaultLabel->lab_offset.p_y);
|
||||
TxPrintf("%s %s\n", laboffx, laboffy);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -2887,13 +2903,13 @@ CmdSnap(
|
|||
switch (n)
|
||||
{
|
||||
case SNAP_OFF: case SNAP_INTERNAL:
|
||||
DBWSnapToGrid = DBW_SNAP_INTERNAL;
|
||||
DBWSnapToGrid = DBW_UNITS_INTERNAL;
|
||||
return;
|
||||
case SNAP_LAMBDA:
|
||||
DBWSnapToGrid = DBW_SNAP_LAMBDA;
|
||||
DBWSnapToGrid = DBW_UNITS_LAMBDA;
|
||||
return;
|
||||
case SNAP_GRID: case SNAP_USER: case SNAP_ON:
|
||||
DBWSnapToGrid = DBW_SNAP_USER;
|
||||
DBWSnapToGrid = DBW_UNITS_USER;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2901,21 +2917,19 @@ printit:
|
|||
if (n == SNAP_LIST) /* list */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetResult(magicinterp,
|
||||
(DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"),
|
||||
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"),
|
||||
TCL_VOLATILE);
|
||||
#else
|
||||
TxPrintf("%s\n", (DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
|
||||
TxPrintf("%s\n", (DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"));
|
||||
#endif
|
||||
else
|
||||
TxPrintf("Box is aligned to %s grid\n",
|
||||
(DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
|
||||
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ cmdScaleCoord(
|
|||
{
|
||||
char *endptr;
|
||||
double dval = 0;
|
||||
int mscale = 1;
|
||||
int mscale = 1, curunits;
|
||||
DBWclientRec *crec;
|
||||
|
||||
if (*arg == '{') arg++;
|
||||
|
|
@ -125,8 +125,18 @@ cmdScaleCoord(
|
|||
return 0;
|
||||
}
|
||||
|
||||
else if ((*endptr == 'l')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_LAMBDA)))
|
||||
/* Original behavior was to accept un-suffixed values according to the
|
||||
* "snap" setting. This behavior remains in effect until the "units"
|
||||
* command is used, in which case units follow the selected units
|
||||
* value indepedendently of the snap setting.
|
||||
*/
|
||||
if (DBWUnits == DBW_UNITS_DEFAULT)
|
||||
curunits = DBWSnapToGrid;
|
||||
else
|
||||
curunits = DBWUnits & DBW_UNITS_TYPE_MASK;
|
||||
|
||||
if ((*endptr == 'l')
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_LAMBDA)))
|
||||
{
|
||||
/* lambda or default units */
|
||||
dval *= (double)DBLambda[1];
|
||||
|
|
@ -134,13 +144,13 @@ cmdScaleCoord(
|
|||
return round(dval);
|
||||
}
|
||||
else if ((*endptr == 'i')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_INTERNAL)))
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_INTERNAL)))
|
||||
{
|
||||
/* internal units */
|
||||
return round(dval);
|
||||
}
|
||||
else if ((*endptr == 'g')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_USER)))
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_USER)))
|
||||
{
|
||||
/* grid units */
|
||||
if (w == (MagWindow *)NULL)
|
||||
|
|
@ -166,6 +176,10 @@ cmdScaleCoord(
|
|||
}
|
||||
return round(dval);
|
||||
}
|
||||
else if (*endptr == '\0' && (curunits == DBW_UNITS_MICRONS))
|
||||
{
|
||||
mscale = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* natural units referred to the current cifoutput style */
|
||||
|
|
|
|||
215
commands/CmdTZ.c
215
commands/CmdTZ.c
|
|
@ -455,15 +455,18 @@ CmdTech(
|
|||
}
|
||||
if (!strncmp(cmd->tx_argv[2], "width", 5))
|
||||
{
|
||||
char *techwidth;
|
||||
tresult = DRCGetDefaultLayerWidth(t1);
|
||||
techwidth = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techwidth, -1));
|
||||
#else
|
||||
TxPrintf("Minimum width is %d\n", tresult);
|
||||
TxPrintf("Minimum width is %s\n", techwidth);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "spac", 4))
|
||||
{
|
||||
char *techspace;
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -475,14 +478,16 @@ CmdTech(
|
|||
else
|
||||
t2 = t1;
|
||||
tresult = DRCGetDefaultLayerSpacing(t1, t2);
|
||||
techspace = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techspace, -1));
|
||||
#else
|
||||
TxPrintf("Minimum spacing is %d\n", tresult);
|
||||
TxPrintf("Minimum spacing is %s\n", techspace);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "surr", 4))
|
||||
{
|
||||
char *techsurround;
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -498,14 +503,17 @@ CmdTech(
|
|||
}
|
||||
|
||||
tresult = DRCGetDefaultLayerSurround(t1, t2);
|
||||
techsurround = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techsurround, -1));
|
||||
#else
|
||||
TxPrintf("Minimum surround is %d\n", tresult);
|
||||
TxPrintf("Minimum surround is %s\n", techsurround);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "direc", 5))
|
||||
{
|
||||
char *techdirec;
|
||||
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -521,10 +529,11 @@ CmdTech(
|
|||
}
|
||||
|
||||
tresult = DRCGetDirectionalLayerSurround(t1, t2);
|
||||
techdirec = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techdirec, -1));
|
||||
#else
|
||||
TxPrintf("Minimum surround (in one orientation) is %d\n", tresult);
|
||||
TxPrintf("Minimum surround (in one orientation) is %s\n", techdirec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -754,6 +763,182 @@ cmdUnexpandFunc(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* CmdUnits --
|
||||
*
|
||||
* Implement the "units" command.
|
||||
*
|
||||
* Usage:
|
||||
* units [value] [print|noprint]
|
||||
*
|
||||
* where "value" may be one of "default", "internal", "lambda",
|
||||
* "user" (equivalently "grid"), or "microns".
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The global variable DBWUnits may be changed, which changes the
|
||||
* behavior of magic when interpreting un-suffixed values or
|
||||
* displaying values.
|
||||
*
|
||||
* Notes:
|
||||
* The units behavior was previously dependent on what command was
|
||||
* issued, with results usually being given in internal units, and
|
||||
* with un-suffixed values following the snap behavior. Backwards-
|
||||
* compatible behavior is used on startup or at any time by setting
|
||||
* the units to "default". Otherwise, unit display follows the
|
||||
* given "units" setting.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define UNITS_DEFAULT 0
|
||||
#define UNITS_INTERNAL 1
|
||||
#define UNITS_LAMBDA 2
|
||||
#define UNITS_GRID 3
|
||||
#define UNITS_USER 4
|
||||
#define UNITS_MICRONS 5
|
||||
#define UNITS_LIST 6
|
||||
#define UNITS_PRINT 7
|
||||
#define UNITS_NOPRINT 8
|
||||
|
||||
void
|
||||
CmdUnits(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
static const char * const names[] = { "default", "internal", "lambda",
|
||||
"grid", "user", "microns", "list", "print", "noprint", 0 };
|
||||
int idx, n = UNITS_LIST, n2, saveflag;
|
||||
DBWclientRec *crec;
|
||||
|
||||
if (cmd->tx_argc >= 2)
|
||||
{
|
||||
n = Lookup(cmd->tx_argv[1], names);
|
||||
if (n < 0)
|
||||
{
|
||||
TxPrintf("Usage: units [default | internal | lambda | microns"
|
||||
" | user] [print]\n");
|
||||
return;
|
||||
}
|
||||
if (DBWUnits != DBW_UNITS_DEFAULT)
|
||||
saveflag = DBWUnits & DBW_UNITS_PRINT_FLAG;
|
||||
else
|
||||
saveflag = -1;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case UNITS_DEFAULT:
|
||||
DBWUnits = DBW_UNITS_DEFAULT;
|
||||
break;
|
||||
case UNITS_INTERNAL:
|
||||
DBWUnits = DBW_UNITS_INTERNAL;
|
||||
break;
|
||||
case UNITS_LAMBDA:
|
||||
DBWUnits = DBW_UNITS_LAMBDA;
|
||||
break;
|
||||
case UNITS_USER:
|
||||
case UNITS_GRID:
|
||||
DBWUnits = DBW_UNITS_USER;
|
||||
break;
|
||||
case UNITS_MICRONS:
|
||||
DBWUnits = DBW_UNITS_MICRONS;
|
||||
break;
|
||||
case UNITS_PRINT:
|
||||
saveflag = DBW_UNITS_PRINT_FLAG;
|
||||
break;
|
||||
case UNITS_NOPRINT:
|
||||
saveflag = 0;
|
||||
break;
|
||||
}
|
||||
if (n < 0)
|
||||
{
|
||||
TxError("Unrecognized units option %s\n.", cmd->tx_argv[1]);
|
||||
return;
|
||||
}
|
||||
if (n != UNITS_LIST)
|
||||
{
|
||||
if ((cmd->tx_argc == 3) && (n != UNITS_DEFAULT))
|
||||
{
|
||||
n2 = Lookup(cmd->tx_argv[2], names);
|
||||
switch (n2)
|
||||
{
|
||||
case UNITS_PRINT:
|
||||
DBWUnits |= DBW_UNITS_PRINT_FLAG;
|
||||
break;
|
||||
case UNITS_NOPRINT:
|
||||
DBWUnits &= DBW_UNITS_TYPE_MASK;
|
||||
break;
|
||||
default:
|
||||
TxError("Unrecognized units option %s\n.", cmd->tx_argv[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((n != UNITS_DEFAULT) && (saveflag != -1))
|
||||
{
|
||||
/* Preserve the previous value of the print/noprint flag */
|
||||
DBWUnits &= DBW_UNITS_TYPE_MASK;
|
||||
DBWUnits |= saveflag;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (DBWUnits == DBW_UNITS_DEFAULT)
|
||||
idx = UNITS_DEFAULT;
|
||||
else
|
||||
switch (DBWUnits & DBW_UNITS_TYPE_MASK)
|
||||
{
|
||||
case DBW_UNITS_INTERNAL:
|
||||
idx = UNITS_INTERNAL;
|
||||
break;
|
||||
case DBW_UNITS_LAMBDA:
|
||||
idx = UNITS_LAMBDA;
|
||||
break;
|
||||
case DBW_UNITS_USER:
|
||||
idx = UNITS_USER;
|
||||
break;
|
||||
case DBW_UNITS_MICRONS:
|
||||
idx = UNITS_MICRONS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == UNITS_LIST) /* list */
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj((char *)names[idx], -1));
|
||||
if (idx != UNITS_DEFAULT)
|
||||
{
|
||||
if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj("print", 5));
|
||||
else
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj("noprint", 7));
|
||||
}
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s", names[idx]);
|
||||
if (idx != UNITS_DEFAULT)
|
||||
if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
TxPrintf(" print");
|
||||
TxPrintf("\n");
|
||||
#endif
|
||||
}
|
||||
else if (idx == UNITS_DEFAULT)
|
||||
TxPrintf("Reported units follow the snap setting.\n");
|
||||
else if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
TxPrintf("Values are reported as %s, along with the units.\n", names[idx]);
|
||||
else
|
||||
TxPrintf("Values are reported as %s\n", names[idx]);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1696,18 +1881,20 @@ CmdWire(
|
|||
case VALUES:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *wdisp;
|
||||
width = WireGetWidth();
|
||||
type = WireGetType();
|
||||
wdisp = DBWPrintValue(width, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(width));
|
||||
Tcl_NewStringObj(wdisp, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBTypeLongNameTbl[type], -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Wire layer %s, width %d\n",
|
||||
DBTypeLongNameTbl[type], width);
|
||||
TxPrintf("Wire layer %s, width %s\n",
|
||||
DBTypeLongNameTbl[type], wdisp);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
@ -1732,12 +1919,14 @@ CmdWire(
|
|||
case WIDTH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *wdisp;
|
||||
width = WireGetWidth();
|
||||
wdisp = DBWPrintValue(width, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewIntObj(width);
|
||||
lobj = Tcl_NewStringObj(wdisp, -1);
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Wire width is %d\n", width);
|
||||
TxPrintf("Wire width is %s\n", wdisp);
|
||||
#endif
|
||||
}
|
||||
else if (locargc != 3)
|
||||
|
|
|
|||
|
|
@ -1621,6 +1621,7 @@ dbAbutmentUseFunc(selUse, use, transform, data)
|
|||
Rect bbox, refbox;
|
||||
Transform *trans;
|
||||
char *propvalue;
|
||||
char *refllx, *reflly, *refurx, *refury;
|
||||
bool found;
|
||||
bool *dolist = (bool *)data;
|
||||
|
||||
|
|
@ -1653,21 +1654,25 @@ dbAbutmentUseFunc(selUse, use, transform, data)
|
|||
}
|
||||
GeoTransRect(trans, &bbox, &refbox);
|
||||
|
||||
/* NOTE: Ideally, the MagWindow pointer should get passed to this routine */
|
||||
refllx = DBWPrintValue(refbox.r_xbot, (MagWindow *)NULL, TRUE);
|
||||
reflly = DBWPrintValue(refbox.r_ybot, (MagWindow *)NULL, FALSE);
|
||||
refurx = DBWPrintValue(refbox.r_xtop, (MagWindow *)NULL, TRUE);
|
||||
refury = DBWPrintValue(refbox.r_ytop, (MagWindow *)NULL, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (*dolist)
|
||||
{
|
||||
pobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xbot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ybot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xtop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ytop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(reflly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refury, -1));
|
||||
Tcl_SetObjResult(magicinterp, pobj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
TxPrintf("Abutment box: %d %d %d %d\n", refbox.r_xbot, refbox.r_ybot,
|
||||
refbox.r_xtop, refbox.r_ytop);
|
||||
|
||||
TxPrintf("Abutment box: %s %s %s %s\n", refllx, reflly, refurx, refury);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ extern void CmdRandom(), CmdSave(), CmdScaleGrid(), CmdSee();
|
|||
extern void CmdSelect(), CmdSetLabel(), CmdSideways();
|
||||
extern void CmdShell(), CmdSnap();
|
||||
extern void CmdStretch(), CmdStraighten();
|
||||
extern void CmdTech(), CmdTool(), CmdUnexpand();
|
||||
extern void CmdTech(), CmdTool(), CmdUnexpand(), CmdUnits();
|
||||
extern void CmdUpsidedown(), CmdWhat(), CmdWire(), CmdWriteall();
|
||||
extern void CmdGoto(), CmdFlatten(), CmdXload(), CmdXor();
|
||||
|
||||
|
|
@ -474,6 +474,9 @@ DBWInitCommands()
|
|||
WindAddCommand(DBWclientID,
|
||||
"unexpand unexpand subcells under box",
|
||||
CmdUnexpand, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"units [type] set type of units parsed and displayed",
|
||||
CmdUnits, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"upsidedown flip selection and box upside down",
|
||||
CmdUpsidedown, FALSE);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/main.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
|
|
@ -33,6 +34,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/hash.h"
|
||||
#include "database/database.h"
|
||||
#include "utils/main.h"
|
||||
#include "cif/cif.h"
|
||||
#include "commands/commands.h"
|
||||
#include "dbwind/dbwind.h"
|
||||
#include "graphics/graphics.h"
|
||||
|
|
@ -653,6 +655,311 @@ DBWexit()
|
|||
return (CmdWarnWrite() == 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbwValueFormat ---
|
||||
*
|
||||
* Remove unnecessary trailing zeros and decimal from a floating-point
|
||||
* value formatted with "%.Nf" where N is the expected maximum number
|
||||
* of places after the decimal, matching the argument "places".
|
||||
* This makes the "%f" formatting work like "%g" formatting, but
|
||||
* works around the limitation of "%.Ng" that it operates on the number
|
||||
* of significant digits, not the number of decimal places.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The string "buf" may be altered with a new terminating null character.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
dbwValueFormat(char *buf,
|
||||
int places)
|
||||
{
|
||||
char *p = buf + strlen(buf) - 1;
|
||||
while (p > buf && *p == '0') *p-- = '\0';
|
||||
if (p > buf && *p == '.') *p = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbwPrintValue0 --
|
||||
*
|
||||
* Convert a value in internal database units to a string based on
|
||||
* the chosen display units as defined by DBWUnits (which is set
|
||||
* with the "units" command). If DBWUnits has not been changed
|
||||
* since startup, then the behavior is to print the internal units
|
||||
* in string form. If DBWUnits has been set, then the units type
|
||||
* determines how the output is displayed.
|
||||
*
|
||||
* If "is_square" is TRUE, then the value is in units squared, and
|
||||
* scaling is done accordingly. In the case of DBW_UNITS_USER,
|
||||
* where values are in grid multiples, the units for X and Y may
|
||||
* differ, and "is_x" = TRUE indicates a measurement in the X direction,
|
||||
* while false indicase a measurements in the Y direction. Naturally,
|
||||
* if "is_square" is TRUE then "is_x" is ignored. "is_x" is also ignored
|
||||
* for any output units other than user/grid units.
|
||||
*
|
||||
* If "is_cif" is true, then "value" is in CIF database units
|
||||
* (centimicrons, nanometers, or angstroms, according to the
|
||||
* scalefactor line in the tech file), rather than internal units.
|
||||
*
|
||||
* This routine is generally meant to be called as one of the three
|
||||
* variants defined below it: DBWPrintValue(), DBWPrintSqValue(),
|
||||
* or DBWPrintCIFValue().
|
||||
*
|
||||
* Results:
|
||||
* A pointer to a string. To facilitate printing up to four values
|
||||
* (e.g., rectangle coordinates, such as from "box values"), a static
|
||||
* string partitioned into four parts is created in this subroutine,
|
||||
* and the result points to one position in the string, which is cycled
|
||||
* through every four calls to the subroutine. The caller does not
|
||||
* free the returned string.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* NOTE: Prior to the introduction of the "units" command, magic had the
|
||||
* inconsistent behavior that parsed input values on the command line
|
||||
* would be interpreted per the "snap" setting, but output values were
|
||||
* (almost) always given in internal units. This routine keeps the
|
||||
* original behavior backwards-compatible, as inconsistent as it is.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
dbwPrintValue0(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x, /* TRUE if value is an X dimension */
|
||||
bool is_square, /* TRUE if value is a dimension squared */
|
||||
bool is_cif) /* TRUE if value is in centimicrons */
|
||||
{
|
||||
char *result;
|
||||
float oscale, dscale, fvalue;
|
||||
DBWclientRec *crec;
|
||||
int locunits;
|
||||
|
||||
/* This routine is called often, so avoid constant use of malloc and
|
||||
* free by keeping up to four printed results in static memory.
|
||||
*/
|
||||
static char resultstr[128];
|
||||
static unsigned char resultpos = 0;
|
||||
|
||||
result = &resultstr[resultpos];
|
||||
resultpos += 32;
|
||||
resultpos &= 127; /* At 128, cycle back to zero */
|
||||
|
||||
/* CIF database units are centimicrons/nanometers/angstroms as
|
||||
* set by the "scalefactor" line in the tech file. When "is_cif"
|
||||
* is TRUE, then "value" is in these units. Find the conversion
|
||||
* factor to convert "value" to internal units, and then it can
|
||||
* be subsequently converted to lambda, microns, etc.
|
||||
*/
|
||||
if (is_cif == TRUE)
|
||||
dscale = CIFGetScale(100) / CIFGetOutputScale(1000);
|
||||
else
|
||||
dscale = 1.0;
|
||||
|
||||
/* When printing user/grid units, check for a valid window */
|
||||
|
||||
locunits = DBWUnits;
|
||||
if (locunits != DBW_UNITS_DEFAULT) locunits &= DBW_UNITS_TYPE_MASK;
|
||||
|
||||
/* The MagWindow argument is only needed for user units, since the
|
||||
* user grid values are found there. Setting MagWindow to NULL
|
||||
* effectively disables printing values in user grid units, which
|
||||
* then default to internal units.
|
||||
*/
|
||||
if (locunits == DBW_UNITS_USER)
|
||||
{
|
||||
if (w == (MagWindow *)NULL)
|
||||
{
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *)NULL)
|
||||
locunits = DBW_UNITS_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (locunits)
|
||||
{
|
||||
case DBW_UNITS_DEFAULT:
|
||||
snprintf(result, 32, "%d", value);
|
||||
break;
|
||||
|
||||
case DBW_UNITS_INTERNAL:
|
||||
if (is_cif)
|
||||
{
|
||||
if (is_square)
|
||||
{
|
||||
snprintf(result, 32, "%.6f", value * dscale * dscale);
|
||||
dbwValueFormat(result, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(result, 32, "%.3f", value * dscale);
|
||||
dbwValueFormat(result, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
snprintf(result, 32, "%d", value);
|
||||
if (is_square)
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 29))
|
||||
strcat(result, "i^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 31))
|
||||
strcat(result, "i");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_LAMBDA:
|
||||
|
||||
oscale = (float)DBLambda[0];
|
||||
oscale /= (float)DBLambda[1];
|
||||
if (is_square)
|
||||
{
|
||||
fvalue = (float)value * oscale * oscale * dscale * dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 29))
|
||||
strcat(result, "l^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 31))
|
||||
strcat(result, "l");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_MICRONS:
|
||||
oscale = CIFGetOutputScale(1000);
|
||||
if (is_square)
|
||||
{
|
||||
fvalue = (float)value * oscale * oscale * dscale * dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 28))
|
||||
strcat(result, "um^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "um");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_USER:
|
||||
if (is_square)
|
||||
{
|
||||
oscale = (float)((crec->dbw_gridRect.r_xtop -
|
||||
crec->dbw_gridRect.r_xbot) *
|
||||
(crec->dbw_gridRect.r_ytop -
|
||||
crec->dbw_gridRect.r_ybot));
|
||||
}
|
||||
else if (is_x)
|
||||
{
|
||||
oscale = (float)(crec->dbw_gridRect.r_xtop -
|
||||
crec->dbw_gridRect.r_xbot);
|
||||
}
|
||||
else
|
||||
{
|
||||
oscale = (float)(crec->dbw_gridRect.r_ytop -
|
||||
crec->dbw_gridRect.r_ybot);
|
||||
}
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
if (is_square)
|
||||
{
|
||||
fvalue *= dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 27))
|
||||
strcat(result, "gx*gy");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if (is_x)
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "gx");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "gy");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBWPrintValue --
|
||||
* DBWPrintSqValue --
|
||||
* DBWPrintCIFValue --
|
||||
* DBWPrintCIFSqValue --
|
||||
*
|
||||
* Convenience functions which call dbwPrintValue0() with specific
|
||||
* fixed arguments, so that the calls are not full of boolean values.
|
||||
* The "is_x" boolean is retained because it is used often.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
DBWPrintValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x) /* TRUE if value is an X dimension */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = FALSE and is_cif = FALSE */
|
||||
return dbwPrintValue0(value, w, is_x, FALSE, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintSqValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w) /* current window, for use with grid */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = TRUE and is_cif = FALSE */
|
||||
/* is_x is set to TRUE although it is unused. */
|
||||
return dbwPrintValue0(value, w, TRUE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintCIFValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x) /* TRUE if value is an X dimension */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = FALSE and is_cif = TRUE */
|
||||
return dbwPrintValue0(value, w, is_x, FALSE, TRUE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintCIFSqValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w) /* current window, for use with grid */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = TRUE and is_cif = TRUE */
|
||||
/* is_x is set to TRUE although it is unused. */
|
||||
return dbwPrintValue0(value, w, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -65,11 +65,21 @@ typedef struct _crosshairRec {
|
|||
static CrosshairRec curCrosshair; /* Crosshair position */
|
||||
|
||||
/*
|
||||
* If the following is DBW_SNAP_USER, the box gets snapped to the user's
|
||||
* If the following is DBW_UNITS_USER, the box gets snapped to the user's
|
||||
* grid always, instead of snapping to the usual 1x1 grid. If the value
|
||||
* is DBW_SNAP_INTERNAL, the box gets snapped to the internal grid.
|
||||
* is DBW_UNITS_INTERNAL, the box gets snapped to the internal grid.
|
||||
*/
|
||||
int DBWSnapToGrid = DBW_SNAP_LAMBDA;
|
||||
int DBWSnapToGrid = DBW_UNITS_LAMBDA;
|
||||
|
||||
/*
|
||||
* The original behavior with respect to units was that un-suffixed
|
||||
* values follow whatever the snap setting is (DBWSnapToGrid, above).
|
||||
* Current behavior is that the original behavior is followed while
|
||||
* DBWUnits is set to DBW_UNITS_DEFAULT. However, if the "units"
|
||||
* command is given, then displayed and entered units follow that
|
||||
* value independently of the snap setting.
|
||||
*/
|
||||
int DBWUnits = DBW_UNITS_DEFAULT;
|
||||
|
||||
/* Forward reference: */
|
||||
|
||||
|
|
@ -82,8 +92,8 @@ extern int DBWToolDraw();
|
|||
* toolFindPoint --
|
||||
*
|
||||
* Returns the point in root coordinates.
|
||||
* If DBWSnapToGrid is DBW_SNAP_USER, pick the nearest point that is
|
||||
* aligned with the window's grid. If DBWSnapToGrid is DBW_SNAP_LAMBDA,
|
||||
* If DBWSnapToGrid is DBW_UNITS_USER, pick the nearest point that is
|
||||
* aligned with the window's grid. If DBWSnapToGrid is DBW_UNITS_LAMBDA,
|
||||
* pick the nearest point that is an integer lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -120,7 +130,7 @@ toolFindPoint(p, rootPoint, rootArea)
|
|||
if (!GEO_ENCLOSE(p, &WindCurrentWindow->w_screenArea)) return NULL;
|
||||
|
||||
WindPointToSurface(WindCurrentWindow, p, rootPoint, rootArea);
|
||||
if (DBWSnapToGrid != DBW_SNAP_INTERNAL)
|
||||
if (DBWSnapToGrid != DBW_UNITS_INTERNAL)
|
||||
ToolSnapToGrid(WindCurrentWindow, rootPoint, rootArea);
|
||||
return WindCurrentWindow;
|
||||
|
||||
|
|
@ -844,8 +854,8 @@ DBWResetBox(CellDef *def)
|
|||
* Repositions the box by one of its corners.
|
||||
* If the point given to reposition the box is in screen coordinates,
|
||||
* the box corner is snapped to the user's grid (set with the :grid
|
||||
* command) if DBWSnapToGrid is DBW_SNAP_USER. If DBWSnapToGrid is
|
||||
* DBW_SNAP_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* command) if DBWSnapToGrid is DBW_UNITS_USER. If DBWSnapToGrid is
|
||||
* DBW_UNITS_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -948,8 +958,8 @@ ToolMoveBox(corner, point, screenCoords, rootDef)
|
|||
*
|
||||
* If the point given to reposition the box is in screen coordinates,
|
||||
* the box corner is snapped to the user's grid (set with the :grid
|
||||
* command) if DBWSnapToGrid is DBW_SNAP_USER. If DBWSnapToGrid is
|
||||
* DBW_SNAP_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* command) if DBWSnapToGrid is DBW_UNITS_USER. If DBWSnapToGrid is
|
||||
* DBW_UNITS_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -1092,7 +1102,7 @@ ToolSnapToGrid(w, p, rEnclose)
|
|||
if (crec == NULL || p == NULL)
|
||||
return;
|
||||
|
||||
if (DBWSnapToGrid == DBW_SNAP_LAMBDA)
|
||||
if (DBWSnapToGrid == DBW_UNITS_LAMBDA)
|
||||
{
|
||||
lr.r_xbot = lr.r_ybot = 0;
|
||||
lr.r_xtop = DBLambda[1] / DBLambda[0];
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ typedef struct DBW1 {
|
|||
|
||||
extern WindClient DBWclientID;
|
||||
extern int DBWSnapToGrid;
|
||||
extern int DBWUnits;
|
||||
|
||||
extern int DBWMaxTechStyles;
|
||||
extern int DBWMaxTileStyles;
|
||||
|
|
@ -121,13 +122,17 @@ extern int DBWNumStyles;
|
|||
extern int RtrPolyWidth, RtrMetalWidth, RtrContactWidth;
|
||||
|
||||
/*
|
||||
* Exported procedure headers for redisplay
|
||||
* Exported procedure headers for redisplay and output
|
||||
*/
|
||||
|
||||
extern int DBWWatchTiles();
|
||||
extern void DBWAreaChanged();
|
||||
extern void DBWLabelChanged();
|
||||
extern void DBWDrawLabel();
|
||||
extern char *DBWPrintValue(int value, MagWindow *w, bool is_x);
|
||||
extern char *DBWPrintSqValue(int value, MagWindow *w);
|
||||
extern char *DBWPrintCIFValue(int value, MagWindow *w, bool is_x);
|
||||
extern char *DBWPrintCIFSqValue(int value, MagWindow *w);
|
||||
|
||||
/*
|
||||
* Exported procedures and variables related to the technology file
|
||||
|
|
@ -169,14 +174,36 @@ extern void DBWBoxHandler();
|
|||
#define TOOL_ILG -1
|
||||
|
||||
/* The following defines are used to indicate which coordinate system
|
||||
* the cursor box snaps to when moved with mouse clicks (values for
|
||||
* DBWSnapToGrid).
|
||||
* is used when displaying or returning values. By default this is
|
||||
* set to DBW_UNITS_INTERNAL. From magic version 8.3.595, this is
|
||||
* independently set from "snap". For backwards compatibility,
|
||||
* the value starts as DBW_UNITS_DEFAULT which implements the original
|
||||
* behavior in which the "snap" setting dictates the dispaly units.
|
||||
* Only if set to a non-negative value do the display units operate
|
||||
* independently of the snap setting.
|
||||
*
|
||||
* NOTES:
|
||||
* Lambda units are fixed by the tech file.
|
||||
* Internal units are scalable.
|
||||
* User units are scalable; this can be used, for example, to
|
||||
* set a box position according to multiples of a track
|
||||
* pitch, but is most often used manually with the "g"
|
||||
* (for "grid") suffix; e.g., "move box e 1g"
|
||||
* Micron units are dependent on the specified cifoutput style
|
||||
* and how the tech file defines the scalefactor for it.
|
||||
*/
|
||||
|
||||
#define DBW_SNAP_INTERNAL 0 /* internal units (fine grid) */
|
||||
#define DBW_SNAP_LAMBDA 1 /* lambda units (coarse grid) */
|
||||
#define DBW_SNAP_USER 2 /* user grid units (user grid) */
|
||||
#define DBW_SNAP_MICRONS 3 /* micron units */
|
||||
#define DBW_UNITS_DEFAULT -1 /* backwards-compatible behavior */
|
||||
#define DBW_UNITS_INTERNAL 0 /* internal units */
|
||||
#define DBW_UNITS_LAMBDA 1 /* lambda units */
|
||||
#define DBW_UNITS_USER 2 /* user grid units */
|
||||
#define DBW_UNITS_MICRONS 3 /* micron units */
|
||||
#define DBW_UNITS_TYPE_MASK 3 /* everything but the flag field(s) */
|
||||
#define DBW_UNITS_PRINT_FLAG 4 /* flag used to indicate that
|
||||
* the units should be printed
|
||||
* with the value; e.g.,
|
||||
* "10um" instead of "10".
|
||||
*/
|
||||
|
||||
/* The following window mask can be used to select all database windows
|
||||
* for things like the mask parameter to DBWAreaChanged.
|
||||
|
|
|
|||
|
|
@ -184,9 +184,9 @@ drcSubstitute (cptr)
|
|||
DRCCookie * cptr; /* Design rule violated */
|
||||
{
|
||||
static char *why_out = NULL;
|
||||
char *whyptr, *sptr, *wptr;
|
||||
int subscnt = 0, whylen;
|
||||
float oscale, value;
|
||||
char *whyptr, *sptr, *wptr, *vptr;
|
||||
int subscnt = 0, whylen, saveunits;
|
||||
float value;
|
||||
extern float CIFGetOutputScale();
|
||||
|
||||
whyptr = DRCCurStyle->DRCWhyList[cptr->drcc_tag];
|
||||
|
|
@ -203,10 +203,14 @@ drcSubstitute (cptr)
|
|||
why_out = (char *)mallocMagic(whylen * sizeof(char));
|
||||
strcpy(why_out, whyptr);
|
||||
|
||||
if (cptr->drcc_flags & DRC_CIFRULE)
|
||||
oscale = CIFGetScale(100); /* 100 = microns to centimicrons */
|
||||
else
|
||||
oscale = CIFGetOutputScale(1000); /* 1000 for conversion to um */
|
||||
/* For backwards compatibility: If the units are set to "default",
|
||||
* then print the DRC value in microns, with units, which is how
|
||||
* the output was previously presented.
|
||||
*/
|
||||
saveunits = DBWUnits;
|
||||
if (saveunits == DBW_UNITS_DEFAULT)
|
||||
DBWUnits = DBW_UNITS_MICRONS | DBW_UNITS_PRINT_FLAG;
|
||||
|
||||
wptr = why_out;
|
||||
|
||||
while ((sptr = strchr(whyptr, '%')) != NULL)
|
||||
|
|
@ -218,21 +222,29 @@ drcSubstitute (cptr)
|
|||
switch (*(sptr + 1))
|
||||
{
|
||||
case 'd':
|
||||
/* Replace with "dist" value in microns */
|
||||
value = (float)cptr->drcc_dist * oscale;
|
||||
snprintf(wptr, 20, "%01.3gum", value);
|
||||
if (cptr->drcc_flags & DRC_CIFRULE)
|
||||
vptr = DBWPrintCIFValue(cptr->drcc_dist, (MagWindow *)NULL, TRUE);
|
||||
else
|
||||
vptr = DBWPrintValue(cptr->drcc_dist, (MagWindow *)NULL, TRUE);
|
||||
snprintf(wptr, 20, "%s", vptr);
|
||||
wptr += strlen(wptr);
|
||||
break;
|
||||
case 'c':
|
||||
/* Replace with "cdist" value in microns */
|
||||
value = (float)cptr->drcc_cdist * oscale;
|
||||
snprintf(wptr, 20, "%01.3gum", value);
|
||||
if (cptr->drcc_flags & DRC_CIFRULE)
|
||||
vptr = DBWPrintCIFValue(cptr->drcc_cdist, (MagWindow *)NULL, TRUE);
|
||||
else
|
||||
vptr = DBWPrintValue(cptr->drcc_cdist, (MagWindow *)NULL, TRUE);
|
||||
snprintf(wptr, 20, "%s", vptr);
|
||||
wptr += strlen(wptr);
|
||||
break;
|
||||
case 'a':
|
||||
/* Replace with "cdist" value in microns squared */
|
||||
value = (float)cptr->drcc_cdist * oscale * oscale;
|
||||
snprintf(wptr, 20, "%01.4gum^2", value);
|
||||
if (cptr->drcc_flags & DRC_CIFRULE)
|
||||
vptr = DBWPrintCIFSqValue(cptr->drcc_cdist, (MagWindow *)NULL);
|
||||
else
|
||||
vptr = DBWPrintSqValue(cptr->drcc_cdist, (MagWindow *)NULL);
|
||||
snprintf(wptr, 20, "%s", vptr);
|
||||
wptr += strlen(wptr);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -245,6 +257,7 @@ drcSubstitute (cptr)
|
|||
/* copy remainder of string (including trailing null) */
|
||||
strncpy(wptr, whyptr, strlen(whyptr) + 1);
|
||||
|
||||
DBWUnits = saveunits;
|
||||
return why_out;
|
||||
}
|
||||
|
||||
|
|
@ -425,6 +438,8 @@ drcListallError (celldef, rect, cptr, scx)
|
|||
}
|
||||
if (drcsave == DRCErrorCount)
|
||||
{
|
||||
char *rllx, *rlly, *rurx, *rury;
|
||||
|
||||
DRCErrorCount += 1;
|
||||
h = HashFind(&DRCErrorTable, drcSubstitute(cptr));
|
||||
lobj = (Tcl_Obj *) HashGetValue(h);
|
||||
|
|
@ -433,10 +448,15 @@ drcListallError (celldef, rect, cptr, scx)
|
|||
|
||||
pobj = Tcl_NewListObj(0, NULL);
|
||||
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_xbot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_ybot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_xtop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_ytop));
|
||||
rllx = DBWPrintValue(r.r_xbot, (MagWindow *)NULL, TRUE);
|
||||
rlly = DBWPrintValue(r.r_ybot, (MagWindow *)NULL, FALSE);
|
||||
rurx = DBWPrintValue(r.r_xtop, (MagWindow *)NULL, TRUE);
|
||||
rury = DBWPrintValue(r.r_ytop, (MagWindow *)NULL, FALSE);
|
||||
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(rllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(rlly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(rurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(rury, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
|
||||
|
||||
HashSetValue(h, lobj);
|
||||
|
|
|
|||
|
|
@ -694,15 +694,22 @@ w3dCutBox(w, cmd)
|
|||
{
|
||||
if (crec->clipped)
|
||||
{
|
||||
char *cllx, *clly, *curx, *cury;
|
||||
|
||||
cllx = DBWPrintValue(crec->cutbox.r_xbot, w, TRUE);
|
||||
clly = DBWPrintValue(crec->cutbox.r_ybot, w, TRUE);
|
||||
curx = DBWPrintValue(crec->cutbox.r_xtop, w, TRUE);
|
||||
cury = DBWPrintValue(crec->cutbox.r_ytop, w, TRUE);
|
||||
|
||||
Tcl_Obj *rlist = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, rlist,
|
||||
Tcl_NewIntObj((int)(crec->cutbox.r_xbot)));
|
||||
Tcl_NewStringObj(cllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, rlist,
|
||||
Tcl_NewIntObj((int)(crec->cutbox.r_ybot)));
|
||||
Tcl_NewStringObj(clly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, rlist,
|
||||
Tcl_NewIntObj((int)(crec->cutbox.r_xtop)));
|
||||
Tcl_NewStringObj(curx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, rlist,
|
||||
Tcl_NewIntObj((int)(crec->cutbox.r_ytop)));
|
||||
Tcl_NewStringObj(cury, -1));
|
||||
|
||||
Tcl_SetObjResult(magicinterp, rlist);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,18 +650,20 @@ proc magic::boxview {win {cmdstr ""}} {
|
|||
|
||||
set framename [winfo parent $win]
|
||||
if {$framename == "."} {return}
|
||||
if {[catch {set cr [cif scale out]}]} {return}
|
||||
set curunits [units list]
|
||||
units microns noprint
|
||||
set bval [${win} box values]
|
||||
set bllx [expr {[lindex $bval 0] * $cr }]
|
||||
set blly [expr {[lindex $bval 1] * $cr }]
|
||||
set burx [expr {[lindex $bval 2] * $cr }]
|
||||
set bury [expr {[lindex $bval 3] * $cr }]
|
||||
set bllx [lindex $bval 0]
|
||||
set blly [lindex $bval 1]
|
||||
set burx [lindex $bval 2]
|
||||
set bury [lindex $bval 3]
|
||||
if {[expr {$bllx == int($bllx)}]} {set bllx [expr {int($bllx)}]}
|
||||
if {[expr {$blly == int($blly)}]} {set blly [expr {int($blly)}]}
|
||||
if {[expr {$burx == int($burx)}]} {set burx [expr {int($burx)}]}
|
||||
if {[expr {$bury == int($bury)}]} {set bury [expr {int($bury)}]}
|
||||
set titletext [format "box (%+g %+g) to (%+g %+g) microns" \
|
||||
$bllx $blly $burx $bury]
|
||||
units {*}$curunits
|
||||
${framename}.titlebar.pos configure -text $titletext
|
||||
}
|
||||
}
|
||||
|
|
@ -673,37 +675,27 @@ proc magic::cursorview {win} {
|
|||
}
|
||||
*bypass logcommands suspend
|
||||
set framename [winfo parent $win]
|
||||
if {[catch {set cr [*bypass cif scale out]}]} {
|
||||
*bypass logcommands resume
|
||||
return
|
||||
}
|
||||
if {$cr == 0} {return}
|
||||
set olst [${win} cursor internal]
|
||||
set olst [${win} cursor microns]
|
||||
|
||||
set olstx [lindex $olst 0]
|
||||
set olsty [lindex $olst 1]
|
||||
|
||||
if {$Opts(crosshair)} {
|
||||
*bypass crosshair ${olstx}i ${olsty}i
|
||||
}
|
||||
|
||||
# Use catch, because occasionally this fails on startup
|
||||
if {[catch {
|
||||
set olstx [expr {$olstx * $cr}]
|
||||
set olsty [expr {$olsty * $cr}]
|
||||
}]} {
|
||||
*bypass logcommands resume
|
||||
return
|
||||
*bypass crosshair ${olstx}um ${olsty}um
|
||||
}
|
||||
|
||||
if {[${win} box exists]} {
|
||||
set curunits [${win} units list]
|
||||
${win} units microns noprint
|
||||
set dlst [${win} box position]
|
||||
set dx [expr {$olstx - ([lindex $dlst 0]) * $cr }]
|
||||
set dy [expr {$olsty - ([lindex $dlst 1]) * $cr }]
|
||||
|
||||
set dx [expr {$olstx - [lindex $dlst 0]}]
|
||||
set dy [expr {$olsty - [lindex $dlst 1]}]
|
||||
if {[expr {$dx == int($dx)}]} {set dx [expr {int($dx)}]}
|
||||
if {[expr {$dy == int($dy)}]} {set dy [expr {int($dy)}]}
|
||||
set titletext [format "(%+g %+g) %+g %+g microns" $olstx $olsty $dx $dy]
|
||||
${framename}.titlebar.pos configure -text $titletext
|
||||
${win} units {*}$curunits
|
||||
} else {
|
||||
set titletext [format "(%+g %+g) microns" $olstx $olsty]
|
||||
${framename}.titlebar.pos configure -text $titletext
|
||||
|
|
@ -834,7 +826,10 @@ proc magic::setscrollvalues {win} {
|
|||
|
||||
*bypass logcommands suspend
|
||||
set svalues [${win} view get]
|
||||
set curunits [units list]
|
||||
units internal noprint
|
||||
set bvalues [${win} view bbox]
|
||||
units {*}$curunits
|
||||
|
||||
set framename [winfo parent ${win}]
|
||||
if {$framename == "."} {
|
||||
|
|
@ -911,8 +906,11 @@ proc magic::scrollview { w win orient } {
|
|||
set v2 $scale($orient,update)
|
||||
set delta [expr {$v2 - $v1}]
|
||||
|
||||
set curunits [units list]
|
||||
units internal noprint
|
||||
set bvalues [${win} view bbox]
|
||||
set wvalues [${win} windowpositions]
|
||||
units {*}$curunits
|
||||
|
||||
# Note that adding 0.000 in expression forces floating-point
|
||||
|
||||
|
|
@ -1299,7 +1297,17 @@ proc magic::openwrapper {{cell ""} {framename ""}} {
|
|||
$m add command -label "Grid off" -command {magic::grid off}
|
||||
$m add command -label "Snap-to-grid on" -command {magic::snap on}
|
||||
$m add command -label "Snap-to-grid off" -command {magic::snap off}
|
||||
$m add command -label "Measure box" -command {magic::box }
|
||||
$m add command -label "Measure box" -command {magic::box}
|
||||
$m add separator
|
||||
$m add command -label "Report internal units" -command {magic::units internal}
|
||||
$m add command -label "Report lambda units" -command {magic::units lambda}
|
||||
$m add command -label "Report micron units" -command {magic::units microns}
|
||||
$m add command -label "Report grid units" -command {magic::units grid}
|
||||
$m add check -label "Display units" -variable Opts(printunits) \
|
||||
-command [subst {if { \$Opts(printunits) } { \
|
||||
magic::units print } else { magic::units noprint } }]
|
||||
|
||||
|
||||
$m add separator
|
||||
$m add command -label "Set grid 0.05um" -command {magic::grid 0.05um}
|
||||
$m add command -label "Set grid 0.10um" -command {magic::grid 0.10um}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ RunStatsRealTime(void)
|
|||
while (inct >= 10) { inct -= 10; incs++; }
|
||||
while (incs >= 60) { incs -= 60; incm++; }
|
||||
|
||||
sprintf(buf, "%ld:%02ld.%ld %ld:%02ld.%ld",
|
||||
snprintf(buf, (size_t)50, "%ld:%02ld.%ld %ld:%02ld.%ld",
|
||||
totm, tots, tott, incm, incs, inct);
|
||||
|
||||
lasttime = curtime;
|
||||
|
|
|
|||
|
|
@ -449,14 +449,26 @@ windCursorCmd(w, cmd)
|
|||
TxCommand *cmd;
|
||||
{
|
||||
Point p_in, p_out;
|
||||
int resulttype = DBW_SNAP_INTERNAL;
|
||||
int resulttype, saveunits;
|
||||
double cursx, cursy, oscale;
|
||||
char *dispx, *dispy;
|
||||
DBWclientRec *crec;
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *listxy;
|
||||
#endif
|
||||
|
||||
/* The original behavior was to use internal
|
||||
* units by default. This remains the case
|
||||
* unless units are set with the "units"
|
||||
* command, in which case units follow the
|
||||
* specified units.
|
||||
*/
|
||||
if (DBWUnits == DBW_UNITS_DEFAULT)
|
||||
resulttype = DBW_UNITS_INTERNAL;
|
||||
else
|
||||
resulttype = DBWUnits;
|
||||
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
if (StrIsInt(cmd->tx_argv[1]))
|
||||
|
|
@ -465,17 +477,21 @@ windCursorCmd(w, cmd)
|
|||
(*GrSetCursorPtr)(atoi(cmd->tx_argv[1]));
|
||||
return;
|
||||
}
|
||||
else if (*cmd->tx_argv[1] == 'i')
|
||||
{
|
||||
resulttype = DBW_UNITS_INTERNAL;
|
||||
}
|
||||
else if (*cmd->tx_argv[1] == 'l')
|
||||
{
|
||||
resulttype = DBW_SNAP_LAMBDA;
|
||||
resulttype = DBW_UNITS_LAMBDA;
|
||||
}
|
||||
else if (*cmd->tx_argv[1] == 'u')
|
||||
{
|
||||
resulttype = DBW_SNAP_USER;
|
||||
resulttype = DBW_UNITS_USER;
|
||||
}
|
||||
else if (*cmd->tx_argv[1] == 'm')
|
||||
{
|
||||
resulttype = DBW_SNAP_MICRONS;
|
||||
resulttype = DBW_UNITS_MICRONS;
|
||||
}
|
||||
else if (*cmd->tx_argv[1] == 'w')
|
||||
{
|
||||
|
|
@ -485,7 +501,7 @@ windCursorCmd(w, cmd)
|
|||
{
|
||||
resulttype = -2; // Use this value for "screen"
|
||||
}
|
||||
else if (*cmd->tx_argv[1] != 'i')
|
||||
else
|
||||
{
|
||||
TxError("Usage: cursor glyphnum\n");
|
||||
TxError(" (or): cursor [internal | lambda | microns | user | window]\n");
|
||||
|
|
@ -506,54 +522,37 @@ windCursorCmd(w, cmd)
|
|||
WindPointToSurface(w, &p_in, &p_out, (Rect *)NULL);
|
||||
|
||||
/* Snap the cursor position if snap is in effect */
|
||||
if (DBWSnapToGrid != DBW_SNAP_INTERNAL)
|
||||
if (DBWSnapToGrid != DBW_UNITS_INTERNAL)
|
||||
ToolSnapToGrid(w, &p_out, (Rect *)NULL);
|
||||
}
|
||||
|
||||
/* Transform the result to declared units with option "lambda" or "grid" */
|
||||
switch (resulttype) {
|
||||
case -2:
|
||||
case -1:
|
||||
cursx = (double)p_in.p_x;
|
||||
cursy = (double)p_in.p_y;
|
||||
break;
|
||||
case DBW_SNAP_INTERNAL:
|
||||
cursx = (double)p_out.p_x;
|
||||
cursy = (double)p_out.p_y;
|
||||
break;
|
||||
case DBW_SNAP_LAMBDA:
|
||||
cursx = (double)(p_out.p_x * DBLambda[0]) / (double)DBLambda[1];
|
||||
cursy = (double)(p_out.p_y * DBLambda[0]) / (double)DBLambda[1];
|
||||
break;
|
||||
case DBW_SNAP_MICRONS:
|
||||
oscale = (double)CIFGetOutputScale(1000);
|
||||
cursx = (double)(p_out.p_x * oscale);
|
||||
cursy = (double)(p_out.p_y * oscale);
|
||||
break;
|
||||
case DBW_SNAP_USER:
|
||||
crec = (DBWclientRec *)w->w_clientData;
|
||||
cursx = (double)((p_out.p_x - crec->dbw_gridRect.r_xbot)
|
||||
/ (crec->dbw_gridRect.r_xtop - crec->dbw_gridRect.r_xbot));
|
||||
cursy = (double)((p_out.p_y - crec->dbw_gridRect.r_ybot)
|
||||
/ (crec->dbw_gridRect.r_ytop - crec->dbw_gridRect.r_ybot));
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
listxy = Tcl_NewListObj(0, NULL);
|
||||
if ((cursx == round(cursx)) && (cursy == round(cursy)))
|
||||
saveunits = DBWUnits;
|
||||
if (resulttype < 0)
|
||||
{
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)cursx));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)cursy));
|
||||
/* Not really internal units, but that prints integer units verbatim */
|
||||
DBWUnits = DBW_UNITS_INTERNAL;
|
||||
cursx = (double)p_in.p_x;
|
||||
cursy = (double)p_in.p_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewDoubleObj(cursx));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewDoubleObj(cursy));
|
||||
DBWUnits = resulttype;
|
||||
cursx = (double)p_out.p_x;
|
||||
cursy = (double)p_out.p_y;
|
||||
}
|
||||
|
||||
dispx = DBWPrintValue(cursx, w, TRUE);
|
||||
dispy = DBWPrintValue(cursy, w, FALSE);
|
||||
DBWUnits = saveunits;
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
listxy = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewStringObj(dispx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewStringObj(dispy, -1));
|
||||
Tcl_SetObjResult(magicinterp, listxy);
|
||||
#else
|
||||
TxPrintf("%g %g\n", cursx, cursy);
|
||||
TxPrintf("%s %s\n", dispx, dispy);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -820,6 +820,9 @@ windViewCmd(w, cmd)
|
|||
|
||||
if (!strncmp(cmd->tx_argv[1], "get", 3))
|
||||
{
|
||||
/* NOTE: The surface area is in screen (pixel) coordinates
|
||||
* and so does not follow the "units" display type.
|
||||
*/
|
||||
#ifndef MAGIC_WRAPPER
|
||||
TxPrintf("(%d, %d) to (%d, %d)\n",
|
||||
w->w_surfaceArea.r_xbot, w->w_surfaceArea.r_ybot,
|
||||
|
|
@ -838,19 +841,24 @@ windViewCmd(w, cmd)
|
|||
}
|
||||
else if (!strncmp(cmd->tx_argv[1], "bbox", 4))
|
||||
{
|
||||
char *vllx, *vlly, *vurx, *vury;
|
||||
|
||||
vllx = DBWPrintValue(w->w_bbox->r_xbot, w, TRUE);
|
||||
vlly = DBWPrintValue(w->w_bbox->r_ybot, w, FALSE);
|
||||
vurx = DBWPrintValue(w->w_bbox->r_xtop, w, TRUE);
|
||||
vury = DBWPrintValue(w->w_bbox->r_ytop, w, FALSE);
|
||||
|
||||
#ifndef MAGIC_WRAPPER
|
||||
TxPrintf("(%d, %d) to (%d, %d)\n",
|
||||
w->w_bbox->r_xbot, w->w_bbox->r_ybot,
|
||||
w->w_bbox->r_xtop, w->w_bbox->r_ytop);
|
||||
TxPrintf("(%s, %s) to (%s, %s)\n", vllx, vlly, vurx, vury);
|
||||
#else
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy,
|
||||
Tcl_NewIntObj((int)w->w_bbox->r_xbot));
|
||||
Tcl_NewStringObj(vllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy,
|
||||
Tcl_NewIntObj((int)w->w_bbox->r_ybot));
|
||||
Tcl_NewStringObj(vlly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy,
|
||||
Tcl_NewIntObj((int)w->w_bbox->r_xtop));
|
||||
Tcl_NewStringObj(vurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, listxy,
|
||||
Tcl_NewIntObj((int)w->w_bbox->r_ytop));
|
||||
Tcl_NewStringObj(vury, -1));
|
||||
Tcl_SetObjResult(magicinterp, listxy);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue