Skip to content

Commit 9dec47c

Browse files
Corrected a fairly long-standing error in which the MASKHINTS_ values
in the .mag file "properties" list are not handled as being in database units during .mag file reading and writing (although they do track internally), making them subject to being scaled incorrectly and change between a read and a write. Thanks to Sylvain Munaut for identifying the problem.
1 parent fd2b1eb commit 9dec47c

File tree

2 files changed

+177
-36
lines changed

2 files changed

+177
-36
lines changed

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.3.479
1+
8.3.480

database/DBio.c

+176-35
Original file line numberDiff line numberDiff line change
@@ -2267,7 +2267,8 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
22672267
if (!strcmp(propertyname, "GDS_FILE"))
22682268
cellDef->cd_flags |= CDVENDORGDS;
22692269

2270-
/* Also process FIXED_BBOX property, as units must match */
2270+
/* Also process FIXED_BBOX property, as units must match, */
2271+
/* and ditto for MASKHINTS_*. */
22712272

22722273
if (!strcmp(propertyname, "FIXED_BBOX"))
22732274
{
@@ -2308,6 +2309,74 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled)
23082309
(void) DBPropPut(cellDef, propertyname, storedvalue);
23092310
}
23102311
}
2312+
else if (!strncmp(propertyname, "MASKHINTS_", 10))
2313+
{
2314+
Rect locbbox;
2315+
char *pptr = pvalueptr;
2316+
int numvals, numrects = 0, slen, n;
2317+
2318+
while (*pptr != '\0')
2319+
{
2320+
numvals = sscanf(pptr, "%d %d %d %d",
2321+
&(locbbox.r_xbot),
2322+
&(locbbox.r_ybot),
2323+
&(locbbox.r_xtop),
2324+
&(locbbox.r_ytop));
2325+
if (numvals <= 0)
2326+
break;
2327+
else if (numvals != 4)
2328+
{
2329+
TxError("Cannot read bounding box values in %s property",
2330+
propertyname);
2331+
break;
2332+
}
2333+
else
2334+
{
2335+
if (numrects == 0)
2336+
{
2337+
storedvalue = (char *)mallocMagic(40);
2338+
*storedvalue = '\0';
2339+
slen = -1;
2340+
}
2341+
else
2342+
{
2343+
char *newvalue;
2344+
slen = strlen(storedvalue);
2345+
newvalue = (char *)mallocMagic(40 + slen);
2346+
sprintf(newvalue, "%s ", storedvalue);
2347+
freeMagic(storedvalue);
2348+
storedvalue = newvalue;
2349+
}
2350+
numrects++;
2351+
2352+
if (scalen > 1)
2353+
{
2354+
locbbox.r_xbot *= scalen;
2355+
locbbox.r_ybot *= scalen;
2356+
locbbox.r_xtop *= scalen;
2357+
locbbox.r_ytop *= scalen;
2358+
}
2359+
if (scaled > 1)
2360+
{
2361+
locbbox.r_xbot /= scaled;
2362+
locbbox.r_ybot /= scaled;
2363+
locbbox.r_xtop /= scaled;
2364+
locbbox.r_ytop /= scaled;
2365+
}
2366+
sprintf(storedvalue + slen + 1, "%d %d %d %d",
2367+
locbbox.r_xbot, locbbox.r_ybot,
2368+
locbbox.r_xtop, locbbox.r_ytop);
2369+
2370+
/* Skip forward four values in pvalueptr */
2371+
for (n = 0; n < 4; n++)
2372+
{
2373+
while (!isspace(*pptr)) pptr++;
2374+
while (isspace(*pptr) && (*pptr != '\0')) pptr++;
2375+
}
2376+
}
2377+
}
2378+
(void) DBPropPut(cellDef, propertyname, storedvalue);
2379+
}
23112380
else
23122381
{
23132382
storedvalue = StrDup((char **)NULL, pvalueptr);
@@ -3177,6 +3246,16 @@ dbCountPropFunc(key, value, count)
31773246
return 0;
31783247
}
31793248

3249+
/* Structure used by dbPropWriteFunc. Holds the FILE stream pointer of
3250+
* the file being written to, and the scale reducer for dimensional
3251+
* values in the output (magscale).
3252+
*/
3253+
3254+
typedef struct _pwfrec {
3255+
FILE *pwf_file;
3256+
int pwf_reducer;
3257+
} pwfrec;
3258+
31803259
/*
31813260
* ----------------------------------------------------------------------------
31823261
*
@@ -3228,6 +3307,7 @@ DBCellWriteFile(cellDef, f)
32283307
CellUse **useList;
32293308
int i, numUses = 0, numProps = 0;
32303309
struct cellUseList cul;
3310+
pwfrec pwf;
32313311

32323312
#define FPUTSF(f,s)\
32333313
{\
@@ -3450,34 +3530,6 @@ DBCellWriteFile(cellDef, f)
34503530

34513531
/* And any properties */
34523532

3453-
/* NOTE: FIXED_BBOX is treated specially; values are database */
3454-
/* values and should be divided by reducer. Easiest to do it */
3455-
/* here and revert values after. */
3456-
3457-
propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &propfound);
3458-
if (propfound)
3459-
{
3460-
char *proporig, *propscaled;
3461-
Rect scalebox, bbox;
3462-
3463-
proporig = StrDup((char **)NULL, propvalue);
3464-
propscaled = mallocMagic(strlen(propvalue) + 5);
3465-
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
3466-
&bbox.r_xtop, &bbox.r_ytop) == 4)
3467-
{
3468-
scalebox.r_xbot = bbox.r_xbot / reducer;
3469-
scalebox.r_xtop = bbox.r_xtop / reducer;
3470-
scalebox.r_ybot = bbox.r_ybot / reducer;
3471-
scalebox.r_ytop = bbox.r_ytop / reducer;
3472-
sprintf(propscaled, "%d %d %d %d",
3473-
bbox.r_xbot / reducer, bbox.r_ybot / reducer,
3474-
bbox.r_xtop / reducer, bbox.r_ytop / reducer);
3475-
3476-
DBPropPut(cellDef, "FIXED_BBOX", propscaled);
3477-
propvalue = proporig;
3478-
}
3479-
}
3480-
34813533
DBPropEnum(cellDef, dbCountPropFunc, (ClientData)&numProps);
34823534
if (numProps > 0)
34833535
{
@@ -3492,19 +3544,18 @@ DBCellWriteFile(cellDef, f)
34923544
keycompare);
34933545

34943546
FPUTSF(f, "<< properties >>\n");
3547+
pwf.pwf_file = f;
3548+
pwf.pwf_reducer = reducer;
34953549
for (i = 0; i < numProps; i++)
34963550
{
34973551
dbWritePropFunc(propRec.keyValueList[i]->key,
34983552
propRec.keyValueList[i]->value,
3499-
(ClientData)f);
3553+
(ClientData)&pwf);
35003554
freeMagic ((char *)propRec.keyValueList[i]);
35013555
}
35023556
freeMagic((char *)propRec.keyValueList);
35033557
}
35043558

3505-
/* Restore the original values in FIXED_BBOX, if any */
3506-
if (propfound) DBPropPut(cellDef, "FIXED_BBOX", propvalue);
3507-
35083559
FPUTSF(f, "<< end >>\n");
35093560

35103561
if (fflush(f) == EOF || ferror(f))
@@ -3539,6 +3590,11 @@ DBCellWriteFile(cellDef, f)
35393590
* expected property strings and output the value based on the
35403591
* known format of what it points to.
35413592
*
3593+
* Also, this function assumes that properties FIXED_BBOX and
3594+
* MASKHINTS_* are in internal units, and converts them by
3595+
* dividing by the reducer value passed in cdata. No other
3596+
* properties are altered.
3597+
*
35423598
* ----------------------------------------------------------------------------
35433599
*/
35443600

@@ -3548,14 +3604,99 @@ dbWritePropFunc(key, value, cdata)
35483604
char *value;
35493605
ClientData cdata;
35503606
{
3551-
FILE *f = (FILE *)cdata;
3607+
pwfrec *pwf = (pwfrec *)cdata;
3608+
FILE *f = pwf->pwf_file;
3609+
int reducer = pwf->pwf_reducer;
3610+
char *newvalue = value;
3611+
3612+
/* NOTE: FIXED_BBOX is treated specially; values are database */
3613+
/* values and should be divided by reducer. Easiest to do it */
3614+
/* here and revert values after. Ditto for MASKHINTS_*. */
3615+
3616+
if (!strcmp(key, "FIXED_BBOX"))
3617+
{
3618+
Rect scalebox, bbox;
3619+
3620+
if (sscanf(value, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
3621+
&bbox.r_xtop, &bbox.r_ytop) == 4)
3622+
{
3623+
scalebox.r_xbot = bbox.r_xbot / reducer;
3624+
scalebox.r_xtop = bbox.r_xtop / reducer;
3625+
scalebox.r_ybot = bbox.r_ybot / reducer;
3626+
scalebox.r_ytop = bbox.r_ytop / reducer;
3627+
3628+
newvalue = mallocMagic(strlen(value) + 5);
3629+
sprintf(newvalue, "%d %d %d %d",
3630+
scalebox.r_xbot, scalebox.r_ybot,
3631+
scalebox.r_xtop, scalebox.r_ytop);
3632+
}
3633+
else
3634+
TxError("Error: Cannot parse FIXED_BBOX property value!\n");
3635+
3636+
}
3637+
else if (!strncmp(key, "MASKHINTS_", 10))
3638+
{
3639+
Rect scalebox, bbox;
3640+
char *vptr = value, *sptr;
3641+
int numvals, numrects = 0, n;
3642+
3643+
while (TRUE)
3644+
{
3645+
numvals = sscanf(vptr, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
3646+
&bbox.r_xtop, &bbox.r_ytop);
3647+
if (numvals <= 0)
3648+
break;
3649+
else if (numvals != 4)
3650+
{
3651+
TxError("Error: Cannot parse %s property value!\n", key);
3652+
/* Revert property value to original string */
3653+
if (newvalue != value) freeMagic(newvalue);
3654+
newvalue = value;
3655+
break;
3656+
}
3657+
else
3658+
{
3659+
scalebox.r_xbot = bbox.r_xbot / reducer;
3660+
scalebox.r_xtop = bbox.r_xtop / reducer;
3661+
scalebox.r_ybot = bbox.r_ybot / reducer;
3662+
scalebox.r_ytop = bbox.r_ytop / reducer;
3663+
if (numrects == 0)
3664+
{
3665+
newvalue = mallocMagic(40);
3666+
sptr = newvalue;
3667+
}
3668+
else
3669+
{
3670+
char *tempvalue;
3671+
tempvalue = mallocMagic(strlen(newvalue) + 40);
3672+
sprintf(tempvalue, "%s ", newvalue);
3673+
sptr = tempvalue + strlen(newvalue) + 1;
3674+
freeMagic(newvalue);
3675+
newvalue = tempvalue;
3676+
}
3677+
sprintf(sptr, "%d %d %d %d",
3678+
scalebox.r_xbot, scalebox.r_ybot,
3679+
scalebox.r_xtop, scalebox.r_ytop);
3680+
numrects++;
3681+
}
3682+
3683+
/* Skip forward four values in value */
3684+
for (n = 0; n < 4; n++)
3685+
{
3686+
while (!isspace(*vptr)) vptr++;
3687+
while (isspace(*vptr) && (*vptr != '\0')) vptr++;
3688+
}
3689+
}
3690+
}
35523691

35533692
FPUTSR(f, "string ");
35543693
FPUTSR(f, key);
35553694
FPUTSR(f, " ");
3556-
FPUTSR(f, value);
3695+
FPUTSR(f, newvalue);
35573696
FPUTSR(f, "\n");
35583697

3698+
if (newvalue != value) freeMagic(newvalue);
3699+
35593700
return 0;
35603701
}
35613702

0 commit comments

Comments
 (0)