2017-04-25 14:41:48 +02:00
|
|
|
/* CIFhier.c -
|
|
|
|
|
*
|
|
|
|
|
* This module handles hierarchy as part of the CIF generator.
|
|
|
|
|
* Because of the nature of the geometrical operations used
|
|
|
|
|
* to generate CIF, such as grow and shrink, the CIF representing
|
|
|
|
|
* two nearby subcells (or elements of an array) may require
|
|
|
|
|
* more than just the combined CIF of the two subcells considered
|
|
|
|
|
* separately. This module computes the extra CIF that may be
|
|
|
|
|
* needed.
|
|
|
|
|
*
|
2020-05-23 23:13:14 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
|
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
|
|
|
* * software and its documentation for any purpose and without *
|
|
|
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
|
|
|
* * notice appear in all copies. The University of California *
|
|
|
|
|
* * makes no representations about the suitability of this *
|
|
|
|
|
* * software for any purpose. It is provided "as is" without *
|
|
|
|
|
* * express or implied warranty. Export of this software outside *
|
|
|
|
|
* * of the United States of America may require an export license. *
|
2017-04-25 14:41:48 +02:00
|
|
|
* *********************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef lint
|
2024-10-04 12:37:02 +02:00
|
|
|
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFhier.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
2017-04-25 14:41:48 +02:00
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2021-01-08 20:39:32 +01:00
|
|
|
#include <string.h>
|
2022-01-07 20:56:43 +01:00
|
|
|
#include <ctype.h>
|
2017-04-25 14:41:48 +02:00
|
|
|
|
2020-11-12 16:34:27 +01:00
|
|
|
#include "tcltk/tclmagic.h"
|
2017-04-25 14:41:48 +02:00
|
|
|
#include "utils/magic.h"
|
|
|
|
|
#include "utils/geometry.h"
|
|
|
|
|
#include "tiles/tile.h"
|
|
|
|
|
#include "utils/hash.h"
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
#include "cif/CIFint.h"
|
|
|
|
|
#include "cif/cif.h"
|
|
|
|
|
#include "drc/drc.h"
|
2020-11-12 16:34:27 +01:00
|
|
|
#include "graphics/graphics.h"
|
2017-04-25 14:41:48 +02:00
|
|
|
#include "textio/textio.h"
|
|
|
|
|
#include "utils/undo.h"
|
|
|
|
|
#include "utils/malloc.h"
|
|
|
|
|
#include "utils/signals.h"
|
|
|
|
|
|
|
|
|
|
/* To compute CIF where there are interaction areas we do two things:
|
|
|
|
|
* 1. Compute the CIF by combining all the material in all the interacting
|
|
|
|
|
* cells together. CIFTotalUse and CIFTotalDef and CIFTotalPlanes
|
|
|
|
|
* are used to hold the flattened material and resulting CIF.
|
|
|
|
|
* 2. Compute the CIF that results by considering the material in each
|
|
|
|
|
* subtree separately and also the material in the parent separately.
|
|
|
|
|
* The paint for each subtree is first flattened into CIFComponentUse
|
|
|
|
|
* and CIFComponentDef, and the resulting CIF from each subtree is
|
|
|
|
|
* OR'ed together into CIFComponentPlanes.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CellUse *CIFTotalUse = NULL;
|
|
|
|
|
CellDef *CIFTotalDef;
|
|
|
|
|
CellUse *CIFComponentUse;
|
|
|
|
|
CellDef *CIFComponentDef;
|
|
|
|
|
Plane *CIFTotalPlanes[MAXCIFLAYERS];
|
|
|
|
|
Plane *CIFComponentPlanes[MAXCIFLAYERS];
|
|
|
|
|
|
|
|
|
|
/* The following use is just used to turn a def into a use for calling
|
|
|
|
|
* procedures that want a use.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CellUse *CIFDummyUse;
|
|
|
|
|
|
|
|
|
|
/* The following local variables are used to share information
|
|
|
|
|
* between top-level procedures and search functions.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Used in cifHierPaintArrayFunc: */
|
|
|
|
|
|
|
|
|
|
Plane *cifHierCurPlane; /* Current plane. */
|
|
|
|
|
static int cifHierXSpacing, cifHierYSpacing, cifHierXCount, cifHierYCount;
|
|
|
|
|
|
|
|
|
|
/* Used in cifGrowSliver */
|
|
|
|
|
static CIFLayer *CurCifLayer;
|
|
|
|
|
|
|
|
|
|
/* Macro for scaling boxes into CIF coordinates: */
|
|
|
|
|
#define SCALE(src, scale, dst) \
|
|
|
|
|
(dst)->r_xbot = (src)->r_xbot * scale; \
|
|
|
|
|
(dst)->r_ybot = (src)->r_ybot * scale; \
|
|
|
|
|
(dst)->r_xtop = (src)->r_xtop * scale; \
|
|
|
|
|
(dst)->r_ytop = (src)->r_ytop * scale;
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* CIFInitCells --
|
|
|
|
|
*
|
|
|
|
|
* This procedure just sets up cell definitions and uses needed
|
|
|
|
|
* for hierarchical checking and other CIF uses.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* DRCUse, DRCDef, and DRCDummyUse are set up if they're not
|
|
|
|
|
* there already.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
CIFInitCells(void)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (CIFTotalUse != NULL) return;
|
|
|
|
|
|
|
|
|
|
CIFTotalDef = DBCellLookDef("__CIF__");
|
|
|
|
|
if (CIFTotalDef == (CellDef *) NULL)
|
|
|
|
|
{
|
2020-03-21 17:40:35 +01:00
|
|
|
CIFTotalDef = DBCellNewDef("__CIF__");
|
2017-04-25 14:41:48 +02:00
|
|
|
ASSERT(CIFTotalDef != (CellDef *) NULL, "cifMakeCell");
|
|
|
|
|
DBCellSetAvail(CIFTotalDef);
|
|
|
|
|
CIFTotalDef->cd_flags |= CDINTERNAL;
|
|
|
|
|
}
|
|
|
|
|
CIFTotalUse = DBCellNewUse (CIFTotalDef, (char *) NULL);
|
|
|
|
|
DBSetTrans (CIFTotalUse, &GeoIdentityTransform);
|
|
|
|
|
CIFTotalUse->cu_expandMask = CU_DESCEND_SPECIAL; /* This is always expanded. */
|
|
|
|
|
|
|
|
|
|
CIFComponentDef = DBCellLookDef("__CIF2__");
|
|
|
|
|
if (CIFComponentDef == (CellDef *) NULL)
|
|
|
|
|
{
|
2020-03-21 17:40:35 +01:00
|
|
|
CIFComponentDef = DBCellNewDef("__CIF2__");
|
2017-04-25 14:41:48 +02:00
|
|
|
ASSERT(CIFComponentDef != (CellDef *) NULL, "cifMakeCell");
|
|
|
|
|
DBCellSetAvail(CIFComponentDef);
|
|
|
|
|
CIFComponentDef->cd_flags |= CDINTERNAL;
|
|
|
|
|
}
|
|
|
|
|
CIFComponentUse = DBCellNewUse (CIFComponentDef, (char *) NULL);
|
|
|
|
|
DBSetTrans (CIFComponentUse, &GeoIdentityTransform);
|
|
|
|
|
CIFComponentUse->cu_expandMask = CU_DESCEND_SPECIAL; /* This is always expanded. */
|
|
|
|
|
|
|
|
|
|
/* Clear out the planes used to collect hierarchical CIF. */
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < MAXCIFLAYERS; i++)
|
|
|
|
|
{
|
|
|
|
|
CIFComponentPlanes[i] = NULL;
|
|
|
|
|
CIFTotalPlanes[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Also create a dummy cell use to use for passing to
|
|
|
|
|
* procedures that need a use when all we've got is a def.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CIFDummyUse = DBCellNewUse(CIFTotalDef, (char *) NULL);
|
|
|
|
|
DBSetTrans (CIFDummyUse, &GeoIdentityTransform);
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierCleanup --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is called after CIF hierarchical processing
|
|
|
|
|
* to clean up the cells and tile planes use for hierarchy and
|
|
|
|
|
* release storage.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* All the CIF-related uses and planes are cleaned up.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierCleanup(void)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* We can't afford for this clearing out to be interrupted, or
|
|
|
|
|
* it could cause the next CIF to be generated wrong.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
SigDisableInterrupts();
|
|
|
|
|
|
|
|
|
|
DBCellClearDef(CIFTotalDef);
|
|
|
|
|
DBCellClearDef(CIFComponentDef);
|
|
|
|
|
for (i = 0; i < MAXCIFLAYERS; i++)
|
|
|
|
|
{
|
|
|
|
|
if (CIFTotalPlanes[i] != NULL)
|
|
|
|
|
{
|
|
|
|
|
DBFreePaintPlane(CIFTotalPlanes[i]);
|
|
|
|
|
TiFreePlane(CIFTotalPlanes[i]);
|
|
|
|
|
CIFTotalPlanes[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (CIFComponentPlanes[i] != NULL)
|
|
|
|
|
{
|
|
|
|
|
DBFreePaintPlane(CIFComponentPlanes[i]);
|
|
|
|
|
TiFreePlane(CIFComponentPlanes[i]);
|
|
|
|
|
CIFComponentPlanes[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SigEnableInterrupts();
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2022-01-19 21:37:45 +01:00
|
|
|
/* Structure used by cifFlatMaskHints, below */
|
|
|
|
|
|
|
|
|
|
typedef struct _maskHintsData
|
|
|
|
|
{
|
|
|
|
|
Transform *mh_trans;
|
|
|
|
|
CellDef *mh_def;
|
|
|
|
|
} MaskHintsData;
|
|
|
|
|
|
2021-01-06 17:35:03 +01:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifMaskHints --
|
|
|
|
|
*
|
|
|
|
|
* Copy a mask hint into a target cell by adding it to the
|
|
|
|
|
* property list of the target cell. If the target cell already
|
|
|
|
|
* has the same mask hint key, then the mask hint value is
|
|
|
|
|
* appended to the property in the target cell def.
|
|
|
|
|
*
|
|
|
|
|
* Returns:
|
|
|
|
|
* 0 to keep the search going.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Modifies properties of the target cell def.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
2022-01-19 21:37:45 +01:00
|
|
|
/* DEPRECATED */
|
2021-01-08 20:39:32 +01:00
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifMaskHints(
|
|
|
|
|
char *name,
|
|
|
|
|
char *value,
|
|
|
|
|
CellDef *targetDef)
|
2021-01-06 17:35:03 +01:00
|
|
|
{
|
|
|
|
|
char *propvalue, *newval;
|
|
|
|
|
bool propfound;
|
|
|
|
|
|
|
|
|
|
if (!strncmp(name, "MASKHINTS_", 10))
|
|
|
|
|
{
|
|
|
|
|
/* Check if name exists already in the flattened cell */
|
|
|
|
|
propvalue = (char *)DBPropGet(targetDef, name, &propfound);
|
|
|
|
|
if (propfound)
|
|
|
|
|
{
|
|
|
|
|
/* Append value to the property */
|
|
|
|
|
newval = mallocMagic(strlen(value) + strlen(propvalue) + 2);
|
|
|
|
|
sprintf(newval, "%s %s", propvalue, value);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
newval = StrDup((char **)NULL, value);
|
|
|
|
|
|
|
|
|
|
DBPropPut(targetDef, name, newval);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-06 16:33:43 +01:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifFlatMaskHints --
|
|
|
|
|
*
|
|
|
|
|
* Copy a mask hint into a flattened cell by transforming it into the
|
|
|
|
|
* coordinate system of the flattened cell, and adding it to the
|
|
|
|
|
* property list of the flattened cell.
|
|
|
|
|
*
|
|
|
|
|
* Returns:
|
|
|
|
|
* 0 to keep the search going.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Modifies properties of the cell def passed in MaskHintsData.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
2021-01-08 20:39:32 +01:00
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifFlatMaskHints(
|
|
|
|
|
char *name,
|
|
|
|
|
char *value,
|
|
|
|
|
MaskHintsData *mhd)
|
2021-01-06 16:33:43 +01:00
|
|
|
{
|
|
|
|
|
Rect r, newr;
|
|
|
|
|
char *vptr, *newval, *lastval, *propvalue;
|
|
|
|
|
bool propfound;
|
2024-05-01 19:45:00 +02:00
|
|
|
int lastlen, numvals;
|
2021-01-06 16:33:43 +01:00
|
|
|
|
|
|
|
|
if (!strncmp(name, "MASKHINTS_", 10))
|
|
|
|
|
{
|
|
|
|
|
newval = (char *)NULL;
|
|
|
|
|
vptr = value;
|
|
|
|
|
while (*vptr != '\0')
|
|
|
|
|
{
|
2024-05-01 19:45:00 +02:00
|
|
|
numvals = sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
|
|
|
|
&r.r_xtop, &r.r_ytop);
|
|
|
|
|
if (numvals == 4)
|
2021-01-06 16:33:43 +01:00
|
|
|
{
|
|
|
|
|
/* Transform rectangle to top level coordinates */
|
|
|
|
|
GeoTransRect(mhd->mh_trans, &r, &newr);
|
|
|
|
|
lastval = newval;
|
|
|
|
|
lastlen = (lastval) ? strlen(lastval) : 0;
|
|
|
|
|
newval = mallocMagic(40 + lastlen);
|
|
|
|
|
if (lastval)
|
|
|
|
|
strcpy(newval, lastval);
|
|
|
|
|
else
|
|
|
|
|
*newval = '\0';
|
2021-01-06 18:17:19 +01:00
|
|
|
sprintf(newval + lastlen, "%s%d %d %d %d", (lastval) ? " " : "",
|
2021-01-06 16:33:43 +01:00
|
|
|
newr.r_xbot, newr.r_ybot, newr.r_xtop, newr.r_ytop);
|
|
|
|
|
if (lastval) freeMagic(lastval);
|
|
|
|
|
|
|
|
|
|
/* Parse through the four values and check if there's more */
|
2022-01-21 03:50:13 +01:00
|
|
|
while (*vptr && isspace(*vptr)) vptr++;
|
2021-01-06 16:33:43 +01:00
|
|
|
while (*vptr && !isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && !isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && !isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && !isspace(*vptr)) vptr++;
|
|
|
|
|
while (*vptr && isspace(*vptr)) vptr++;
|
|
|
|
|
}
|
2024-05-01 19:45:00 +02:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TxError("MASKHINTS_%s: Expected 4 values, found only %d\n",
|
|
|
|
|
name + 10, numvals);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-01-06 16:33:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check if name exists already in the flattened cell */
|
|
|
|
|
propvalue = (char *)DBPropGet(mhd->mh_def, name, &propfound);
|
|
|
|
|
if (propfound)
|
|
|
|
|
{
|
|
|
|
|
/* Append newval to the property */
|
|
|
|
|
lastval = newval;
|
|
|
|
|
newval = mallocMagic(strlen(lastval) + strlen(propvalue) + 2);
|
|
|
|
|
sprintf(newval, "%s %s", propvalue, lastval);
|
|
|
|
|
freeMagic(lastval);
|
|
|
|
|
}
|
|
|
|
|
DBPropPut(mhd->mh_def, name, newval);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-19 21:37:45 +01:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* CIFCopyMaskHints --
|
|
|
|
|
*
|
|
|
|
|
* Callback function to copy mask hints from one cell into another.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* May modify properties in the target cell.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
CIFCopyMaskHints(
|
|
|
|
|
SearchContext *scx,
|
|
|
|
|
CellDef *targetDef)
|
2022-01-19 21:37:45 +01:00
|
|
|
{
|
|
|
|
|
MaskHintsData mhd;
|
|
|
|
|
|
|
|
|
|
CellDef *sourceDef = scx->scx_use->cu_def;
|
|
|
|
|
mhd.mh_trans = &scx->scx_trans;
|
|
|
|
|
mhd.mh_def = targetDef;
|
|
|
|
|
|
|
|
|
|
DBPropEnum(sourceDef, cifFlatMaskHints, &mhd);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-06 16:33:43 +01:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierCopyMaskHints --
|
|
|
|
|
*
|
|
|
|
|
* Callback function to copy mask hints from a subcell into a flattened
|
|
|
|
|
* cell, which is passed in the clientData record.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* May modify properties in the flattened cell.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierCopyMaskHints(
|
|
|
|
|
SearchContext *scx,
|
|
|
|
|
ClientData clientData)
|
2021-01-06 16:33:43 +01:00
|
|
|
{
|
|
|
|
|
MaskHintsData mhd;
|
|
|
|
|
|
|
|
|
|
mhd.mh_trans = &scx->scx_trans;
|
|
|
|
|
mhd.mh_def = (CellDef *)clientData;
|
|
|
|
|
|
|
|
|
|
DBPropEnum(scx->scx_use->cu_def, cifFlatMaskHints, &mhd);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierCopyFunc --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is called to copy paint from the database into
|
|
|
|
|
* flattened areas for CIF generation. It's important to use
|
|
|
|
|
* this procedure rather than calling DBCellCopyAllPaint. The
|
|
|
|
|
* reason is that DBCellCopyAllPaint clips the tiles to the
|
|
|
|
|
* edges of the search area. When generating CIF for layers like
|
|
|
|
|
* contacts, the exact location of the edge of the tile is
|
|
|
|
|
* important. Thus, this procedure always copies WHOLE tiles.
|
|
|
|
|
* Information will be clipped to the edge of the CIF generation
|
|
|
|
|
* area later.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The tile is copied into the definition indicated by the
|
|
|
|
|
* client data.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierCopyFunc(
|
|
|
|
|
Tile *tile, /* Pointer to tile to copy. */
|
|
|
|
|
TreeContext *cxp) /* Describes context of search, including
|
2017-04-25 14:41:48 +02:00
|
|
|
* transform and client data.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
TileType type = TiGetTypeExact(tile);
|
|
|
|
|
Rect sourceRect, targetRect;
|
|
|
|
|
int pNum;
|
|
|
|
|
CellDef *def = (CellDef *) cxp->tc_filter->tf_arg;
|
|
|
|
|
int dinfo = 0;
|
|
|
|
|
|
|
|
|
|
/* Ignore tiles in vendor GDS, unless this is specifically */
|
|
|
|
|
/* overridden by the "see-vendor" option. */
|
|
|
|
|
|
|
|
|
|
if (cxp->tc_scx->scx_use->cu_def->cd_flags & CDVENDORGDS)
|
|
|
|
|
{
|
|
|
|
|
if (!CIFCurStyle)
|
2020-12-14 22:55:29 +01:00
|
|
|
if (!(CIFCurStyle->cs_flags & CWF_SEE_NO_VENDOR))
|
|
|
|
|
return 0;
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ignore space tiles, since they won't do anything anyway. */
|
|
|
|
|
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
{
|
|
|
|
|
dinfo = DBTransformDiagonal(type, &cxp->tc_scx->scx_trans);
|
|
|
|
|
type = (SplitSide(tile)) ? SplitRightType(tile) :
|
|
|
|
|
SplitLeftType(tile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == TT_SPACE) return 0;
|
|
|
|
|
|
|
|
|
|
/* Get the rectangular area, and transform to final coords. */
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &sourceRect);
|
|
|
|
|
GeoTransRect(&cxp->tc_scx->scx_trans, &sourceRect, &targetRect);
|
|
|
|
|
|
|
|
|
|
for (pNum = PL_SELECTBASE; pNum < DBNumPlanes; pNum++)
|
|
|
|
|
{
|
|
|
|
|
if (DBPaintOnPlane(type, pNum))
|
|
|
|
|
{
|
|
|
|
|
DBNMPaintPlane(def->cd_planes[pNum], dinfo, &targetRect,
|
|
|
|
|
DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierCellFunc --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is invoked once for each subcell overlapping
|
|
|
|
|
* an interaction area. It flattens the subcell and its children
|
|
|
|
|
* in the area of the overlap, generates CIF for that area, and
|
|
|
|
|
* saves it in cifHierPieces.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* A new collection of CIF planes is added to cifHierPieces.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierCellFunc(
|
|
|
|
|
SearchContext *scx) /* Describes cell and area in cell. */
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
SearchContext newscx;
|
|
|
|
|
Rect rootArea;
|
|
|
|
|
|
|
|
|
|
/* Do not call this function on cells that are vendor GDS */
|
|
|
|
|
/* (handled in cifHierCopyFunc()) */
|
|
|
|
|
/* if (scx->scx_use->cu_def->cd_flags & CDVENDORGDS) return 0; */
|
|
|
|
|
|
|
|
|
|
/* In order to generate CIF safely in the interaction area, we
|
|
|
|
|
* have to yank material in a larger area: bloats and shrinks
|
|
|
|
|
* may cause this material to affect CIF in the interaction area.
|
|
|
|
|
* This may actually be over-conservative, but it's safe. Think
|
|
|
|
|
* carefully before trying to optimize!
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
DBCellClearDef(CIFComponentDef);
|
|
|
|
|
newscx = *scx;
|
|
|
|
|
GEO_EXPAND(&scx->scx_area, CIFCurStyle->cs_radius, &newscx.scx_area);
|
|
|
|
|
(void) DBTreeSrTiles(&newscx, &CIFCurStyle->cs_yankLayers, 0,
|
2020-05-26 20:29:36 +02:00
|
|
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2021-01-06 16:33:43 +01:00
|
|
|
/* Flatten mask hints in the area of interest */
|
2022-01-19 21:37:45 +01:00
|
|
|
CIFCopyMaskHints(scx, CIFComponentDef);
|
2021-01-06 16:33:43 +01:00
|
|
|
DBTreeSrCells(&newscx, 0, cifHierCopyMaskHints,
|
|
|
|
|
(ClientData)CIFComponentDef);
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Set CIFErrorDef to NULL to ignore errors here... these will
|
|
|
|
|
* get reported anyway when the cell is CIF'ed non-hierarchically,
|
|
|
|
|
* so there's no point in making a second report here.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CIFErrorDef = (CellDef *) NULL;
|
|
|
|
|
GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootArea);
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFComponentDef, scx->scx_use->cu_def, &rootArea,
|
2020-11-12 16:34:27 +01:00
|
|
|
CIFComponentPlanes, &CIFCurStyle->cs_hierLayers, FALSE,
|
|
|
|
|
TRUE, TRUE, (ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
return 0;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierErrorFunc --
|
|
|
|
|
*
|
|
|
|
|
* This function is invoked when the combined CIF in a parent
|
|
|
|
|
* is LESS than the individual CIFs of the children. This means
|
|
|
|
|
* there are bogus rules in the CIF rule set.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Error information is output.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierErrorFunc(
|
|
|
|
|
Tile *tile, /* Tile that covers area it shouldn't. */
|
|
|
|
|
Rect *checkArea) /* Intersection of this and tile is error. */
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
Rect area;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &area);
|
|
|
|
|
|
|
|
|
|
/* Space in a diagonal tile is not an error if the corner containing
|
|
|
|
|
* space bounds the checkArea.
|
|
|
|
|
*/
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
if (((area.r_xbot == checkArea->r_xbot) && !SplitSide(tile)) ||
|
|
|
|
|
((area.r_xtop == checkArea->r_xtop) && SplitSide(tile)))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
GeoClip(&area, checkArea);
|
|
|
|
|
CIFError(&area, "parent and child disagree on CIF");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierCheckFunc --
|
|
|
|
|
*
|
|
|
|
|
* This function is invoked once for each CIF tile coming from
|
|
|
|
|
* a subcell piece. It makes sure there are no space tiles over
|
|
|
|
|
* its area in "plane", then deletes everything from that area
|
|
|
|
|
* in "plane".
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Error messages may be output.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierCheckFunc(
|
|
|
|
|
Tile *tile, /* Tile containing CIF. */
|
|
|
|
|
Plane *plane) /* Plane to check against and modify. */
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
Rect area;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &area);
|
|
|
|
|
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
{
|
|
|
|
|
DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile),
|
|
|
|
|
&area, &DBSpaceBits, cifHierErrorFunc, (ClientData) &area);
|
|
|
|
|
|
|
|
|
|
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
|
|
|
|
|
(PaintUndoInfo *) NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DBSrPaintArea((Tile *) NULL, plane, &area,
|
|
|
|
|
&DBSpaceBits, cifHierErrorFunc, (ClientData) &area);
|
|
|
|
|
DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CIFTileOps++;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-19 04:31:19 +01:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierTempCheckFunc --
|
|
|
|
|
*
|
|
|
|
|
* This function is like cifHierCheckFunc() (see above), but is used
|
|
|
|
|
* for "templayers", where any parent/child disagreement should be
|
|
|
|
|
* considered a non-issue as far as output is concerned. Only the
|
|
|
|
|
* actual mask layer will report any problems.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Error messages may be output.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierTempCheckFunc(
|
|
|
|
|
Tile *tile, /* Tile containing CIF. */
|
|
|
|
|
Plane *plane) /* Plane to check against and modify. */
|
2020-11-19 04:31:19 +01:00
|
|
|
{
|
|
|
|
|
Rect area;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &area);
|
|
|
|
|
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
|
|
|
|
|
(PaintUndoInfo *) NULL);
|
|
|
|
|
else
|
|
|
|
|
DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL);
|
|
|
|
|
|
|
|
|
|
CIFTileOps++;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierPaintFunc --
|
|
|
|
|
*
|
|
|
|
|
* Called to transfer information from one CIF plane to another.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The area of tile is painted into plane.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierPaintFunc(
|
|
|
|
|
Tile *tile,
|
|
|
|
|
Plane *plane) /* Plane in which to paint CIF over tile's
|
2017-04-25 14:41:48 +02:00
|
|
|
* area.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
Rect area;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &area);
|
|
|
|
|
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
|
|
|
|
|
if (IsSplit(tile))
|
|
|
|
|
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFPaintTable,
|
|
|
|
|
(PaintUndoInfo *) NULL);
|
|
|
|
|
else
|
|
|
|
|
DBPaintPlane(plane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
|
|
|
|
|
CIFTileOps += 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifCheckAndErase --
|
|
|
|
|
*
|
|
|
|
|
* This utility procedure processes the hierarchical pieces
|
|
|
|
|
* in two ways. First, it makes sure that all the CIF in
|
|
|
|
|
* CIFComponentPlanes is present in CIFTotalPlanes. Second,
|
|
|
|
|
* it erases from CIFTotalPlanes any information that's in
|
|
|
|
|
* CIFComponentPlanes.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The information in CIFTotalPlanes is reduced, and error messages
|
|
|
|
|
* may be output.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifCheckAndErase(
|
|
|
|
|
CIFStyle *style) /* Describes how to make CIF. */
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* Process all of the bits of CIF in CIFComponentPlanes. */
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
for (i=0; i<style->cs_nLayers; i++)
|
|
|
|
|
{
|
|
|
|
|
CIFErrorLayer = i;
|
|
|
|
|
if (CIFComponentPlanes[i] == NULL) continue;
|
2020-11-19 04:31:19 +01:00
|
|
|
if (CIFCurStyle->cs_layers[i]->cl_flags & CIF_TEMP)
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFComponentPlanes[i],
|
|
|
|
|
&TiPlaneRect, &CIFSolidBits, cifHierTempCheckFunc,
|
|
|
|
|
(ClientData) CIFTotalPlanes[i]);
|
|
|
|
|
else
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFComponentPlanes[i],
|
|
|
|
|
&TiPlaneRect, &CIFSolidBits, cifHierCheckFunc,
|
|
|
|
|
(ClientData) CIFTotalPlanes[i]);
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* CIFGenSubcells --
|
|
|
|
|
*
|
|
|
|
|
* This procedure computes all of the CIF that must be added to
|
|
|
|
|
* a given area to compensate for interactions between subcells.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The parameter "output" is modified (by OR'ing) to hold all
|
|
|
|
|
* the CIF that was generated for subcells.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
CIFGenSubcells(
|
|
|
|
|
CellDef *def, /* Parent cell for which CIF is computed. */
|
|
|
|
|
Rect *area, /* All CIF in this area is interesting. */
|
|
|
|
|
Plane **output) /* Array of pointers to planes into which
|
2017-04-25 14:41:48 +02:00
|
|
|
* the CIF output will be OR'ed (real CIF
|
|
|
|
|
* only).
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
int stepSize, x, y, i, radius, oldTileOps, oldTileOps2;
|
|
|
|
|
Rect totalArea, square, interaction;
|
|
|
|
|
SearchContext scx;
|
2020-11-12 16:34:27 +01:00
|
|
|
int cuts, totcuts;
|
|
|
|
|
float pdone, plast;
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
UndoDisable();
|
|
|
|
|
CIFInitCells();
|
|
|
|
|
radius = CIFCurStyle->cs_radius;
|
|
|
|
|
stepSize = CIFCurStyle->cs_stepSize;
|
|
|
|
|
if (stepSize <= 0)
|
|
|
|
|
{
|
|
|
|
|
stepSize = 20*radius;
|
|
|
|
|
if (stepSize < 50) stepSize = 50;
|
|
|
|
|
}
|
|
|
|
|
CIFDummyUse->cu_def = def;
|
|
|
|
|
scx.scx_use = CIFDummyUse;
|
|
|
|
|
scx.scx_trans = GeoIdentityTransform;
|
|
|
|
|
|
2020-11-12 16:34:27 +01:00
|
|
|
/* This routine can take a long time, so use the display
|
|
|
|
|
* timer to force a 5-second progress check (like is done
|
|
|
|
|
* with extract)
|
|
|
|
|
*/
|
|
|
|
|
GrDisplayStatus = DISPLAY_IN_PROGRESS;
|
|
|
|
|
SigSetTimer(5); /* Print at 5-second intervals */
|
|
|
|
|
cuts = 0;
|
|
|
|
|
pdone = 0.0;
|
|
|
|
|
plast = 0.0;
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Any tile operations processed here get billed to hierarchy
|
|
|
|
|
* in addition to being added to the total.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
oldTileOps = CIFTileOps;
|
|
|
|
|
|
|
|
|
|
/* Divide the area of the cell up into squares, and step through
|
|
|
|
|
* the chunks. In each chunk, the first thing to do is to find
|
|
|
|
|
* out if there are any subcell interactions within one
|
|
|
|
|
* radius of the square.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
totalArea = *area;
|
|
|
|
|
GeoClip(&totalArea, &def->cd_bbox);
|
2020-11-12 16:34:27 +01:00
|
|
|
|
|
|
|
|
totcuts = (totalArea.r_ytop - totalArea.r_ybot + stepSize - 1)
|
|
|
|
|
/ stepSize;
|
|
|
|
|
totcuts *= ((totalArea.r_xtop - totalArea.r_xbot + stepSize - 1)
|
|
|
|
|
/ stepSize);
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
for (y = totalArea.r_ybot; y < totalArea.r_ytop; y += stepSize)
|
|
|
|
|
for (x = totalArea.r_xbot; x < totalArea.r_xtop; x += stepSize)
|
|
|
|
|
{
|
|
|
|
|
square.r_xbot = x;
|
|
|
|
|
square.r_ybot = y;
|
|
|
|
|
square.r_xtop = x + stepSize;
|
|
|
|
|
square.r_ytop = y + stepSize;
|
|
|
|
|
if (square.r_xtop > totalArea.r_xtop)
|
|
|
|
|
square.r_xtop = totalArea.r_xtop;
|
|
|
|
|
if (square.r_ytop > totalArea.r_ytop)
|
|
|
|
|
square.r_ytop = totalArea.r_ytop;
|
|
|
|
|
GEO_EXPAND(&square, radius, &square);
|
2022-02-20 23:36:49 +01:00
|
|
|
if (DRCFindInteractions(def, &square, radius,
|
|
|
|
|
&interaction) <= 0) continue;
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* We've found an interaction. Flatten it into CIFTotalUse, then
|
|
|
|
|
* make CIF from what's flattened. Yank extra material to
|
|
|
|
|
* ensure that CIF is generated correctly.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
GEO_EXPAND(&interaction, CIFCurStyle->cs_radius, &scx.scx_area);
|
|
|
|
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
|
|
|
|
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
2021-01-06 16:33:43 +01:00
|
|
|
/* Flatten mask hints in the area of interest */
|
2022-01-19 21:37:45 +01:00
|
|
|
CIFCopyMaskHints(&scx, CIFTotalDef);
|
2021-01-06 16:33:43 +01:00
|
|
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
|
|
|
|
(ClientData)CIFTotalDef);
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
CIFErrorDef = def;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/* Now go through all the subcells overlapping the area
|
|
|
|
|
* and generate CIF for each subcell individually. OR this
|
|
|
|
|
* combined CIF together into CIFComponentPlanes.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
scx.scx_area = interaction;
|
|
|
|
|
(void) DBCellSrArea(&scx, cifHierCellFunc, (ClientData) NULL);
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Also generate CIF for the paint in the parent alone. Ignore
|
|
|
|
|
* CIF generation errors here, since they will already have been
|
|
|
|
|
* recorded when the parent was CIF'ed by itself.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CIFErrorDef = (CellDef *) NULL;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(def, def, &interaction, CIFComponentPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/* Make sure everything in the pieces is also in the overall
|
|
|
|
|
* CIF, then erase the piece stuff from the overall, and
|
|
|
|
|
* throw away the pieces.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
CIFErrorDef = def;
|
|
|
|
|
cifCheckAndErase(CIFCurStyle);
|
|
|
|
|
|
|
|
|
|
/* Lastly, paint everything from the pieces into the result
|
|
|
|
|
* planes.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
oldTileOps2 = CIFTileOps;
|
|
|
|
|
for (i=0; i<CIFCurStyle->cs_nLayers; i++)
|
|
|
|
|
{
|
|
|
|
|
CurCifLayer = CIFCurStyle->cs_layers[i]; /* for growSliver */
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&TiPlaneRect, &CIFSolidBits, cifHierPaintFunc,
|
|
|
|
|
(ClientData) output[i]);
|
|
|
|
|
}
|
|
|
|
|
CIFHierRects += CIFTileOps - oldTileOps2;
|
|
|
|
|
|
|
|
|
|
cifHierCleanup();
|
2020-11-12 16:34:27 +01:00
|
|
|
|
|
|
|
|
cuts++;
|
|
|
|
|
pdone = 100.0 * ((float)cuts / (float)totcuts);
|
|
|
|
|
if ((((pdone - plast) > 1.0) || (cuts == totcuts)) && (cuts > 1))
|
|
|
|
|
{
|
|
|
|
|
/* Only print something if the 5-second timer has expired */
|
|
|
|
|
if (GrDisplayStatus == DISPLAY_BREAK_PENDING)
|
|
|
|
|
{
|
|
|
|
|
TxPrintf("Completed %d%%\n", (int)(pdone + 0.5));
|
|
|
|
|
plast = pdone;
|
|
|
|
|
TxFlushOut();
|
|
|
|
|
|
|
|
|
|
GrDisplayStatus = DISPLAY_IN_PROGRESS;
|
|
|
|
|
SigSetTimer(5);
|
|
|
|
|
}
|
|
|
|
|
#ifdef MAGIC_WRAPPER
|
|
|
|
|
/* We need to let Tk paint the console display */
|
|
|
|
|
while (Tcl_DoOneEvent(TCL_DONT_WAIT) != 0);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
CIFHierTileOps += CIFTileOps - oldTileOps;
|
2020-11-12 16:34:27 +01:00
|
|
|
|
|
|
|
|
GrDisplayStatus = DISPLAY_IDLE;
|
|
|
|
|
SigRemoveTimer();
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
UndoEnable();
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2021-06-07 22:38:12 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierElementFuncLow(
|
|
|
|
|
CellUse *use, /* CellUse being array-checked. */
|
|
|
|
|
Transform *transform, /* Transform from this instance to
|
2021-06-07 22:38:12 +02:00
|
|
|
* the parent.
|
|
|
|
|
*/
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
int x,
|
|
|
|
|
int y, /* Indices of this instance. */
|
|
|
|
|
Rect *checkArea) /* Area (in parent coords) to be
|
2021-06-07 22:38:12 +02:00
|
|
|
* CIF-generated.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
if (((x - use->cu_xlo) < 2) && ((y - use->cu_ylo) < 2))
|
|
|
|
|
return cifHierElementFunc(use, transform, x, y, checkArea);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierElementFuncHigh(
|
|
|
|
|
CellUse *use, /* CellUse being array-checked. */
|
|
|
|
|
Transform *transform, /* Transform from this instance to
|
2021-06-07 22:38:12 +02:00
|
|
|
* the parent.
|
|
|
|
|
*/
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
int x,
|
|
|
|
|
int y, /* Indices of this instance. */
|
|
|
|
|
Rect *checkArea) /* Area (in parent coords) to be
|
2021-06-07 22:38:12 +02:00
|
|
|
* CIF-generated.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
if (((use->cu_xhi - x) < 2) && ((use->cu_yhi - y) < 2))
|
|
|
|
|
return cifHierElementFunc(use, transform, x, y, checkArea);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierElementFunc --
|
|
|
|
|
*
|
|
|
|
|
* This function is called once for each time an array element
|
|
|
|
|
* overlaps one of the four areas A, B, C, or D in cifHierArrayFunc
|
|
|
|
|
* (see below). Its job is to yank the relevant piece of this
|
|
|
|
|
* cell into CIFTotalDef, and also to yank the same piece into
|
|
|
|
|
* CIFComponentDef and generate a piece of CIF from it. The CIF
|
|
|
|
|
* from the piece is OR'ed into CIFComponentPlanes for later comparison
|
|
|
|
|
* with the parent.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The cell CIFTotalUse is modified, as is CIFComponentUse and
|
|
|
|
|
* CIFComponentPlanes.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierElementFunc(
|
|
|
|
|
CellUse *use, /* CellUse being array-checked. */
|
|
|
|
|
Transform *transform, /* Transform from this instance to
|
2017-04-25 14:41:48 +02:00
|
|
|
* the parent.
|
|
|
|
|
*/
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
int x,
|
|
|
|
|
int y, /* Indices of this instance. */
|
|
|
|
|
Rect *checkArea) /* Area (in parent coords) to be
|
2017-04-25 14:41:48 +02:00
|
|
|
* CIF-generated.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
Rect defArea;
|
|
|
|
|
Transform tinv;
|
|
|
|
|
SearchContext scx;
|
|
|
|
|
|
|
|
|
|
GeoInvertTrans(transform, &tinv);
|
|
|
|
|
GeoTransRect(&tinv, checkArea, &defArea);
|
|
|
|
|
|
|
|
|
|
/* Yank extra material to ensure that CIF is generated correctly. */
|
|
|
|
|
|
|
|
|
|
GEO_EXPAND(&defArea, CIFCurStyle->cs_radius, &scx.scx_area);
|
|
|
|
|
scx.scx_trans = *transform;
|
|
|
|
|
scx.scx_use = use;
|
|
|
|
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
|
|
|
|
cifHierCopyFunc, (ClientData) CIFTotalDef);
|
2022-01-19 21:37:45 +01:00
|
|
|
CIFCopyMaskHints(&scx, CIFTotalDef);
|
2021-01-06 16:33:43 +01:00
|
|
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
|
|
|
|
(ClientData)CIFTotalDef);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
DBCellClearDef(CIFComponentDef);
|
|
|
|
|
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
|
|
|
|
|
cifHierCopyFunc, (ClientData) CIFComponentDef);
|
2022-01-19 21:37:45 +01:00
|
|
|
CIFCopyMaskHints(&scx, CIFComponentDef);
|
2021-01-06 16:33:43 +01:00
|
|
|
DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
|
|
|
|
|
(ClientData)CIFComponentDef);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
CIFErrorDef = (CellDef *) NULL;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ---------------------------------------------------------------------------
|
|
|
|
|
* cifGrowSliver() --
|
|
|
|
|
*
|
|
|
|
|
* This function is passed the address of a "sliver" rectangle. It then
|
2020-05-23 23:13:14 +02:00
|
|
|
* grows the shortest dimension of the sliver so that it is at least minimum
|
2017-04-25 14:41:48 +02:00
|
|
|
* width. The minimum width is found through the variable CurCifLayer which
|
|
|
|
|
* identifies the current layer being generated. A "minwidth" command has been
|
|
|
|
|
* added to the cifoutput section for which the minimum width of each layer
|
|
|
|
|
* can be specified.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always return 0
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* Returns the modified rectangle in "area" (pointer)
|
|
|
|
|
* ---------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifGrowSliver(
|
|
|
|
|
Tile *tile,
|
|
|
|
|
Rect *area)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
int height, width, expand_up, expand_side;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, area);
|
|
|
|
|
expand_up = (TiGetType(BL(tile)) != TT_SPACE) ||
|
|
|
|
|
(TiGetType(TR(tile)) != TT_SPACE);
|
|
|
|
|
expand_side = (TiGetType(LB(tile)) != TT_SPACE) ||
|
|
|
|
|
(TiGetType(RT(tile)) != TT_SPACE);
|
|
|
|
|
if (CurCifLayer->min_width == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
height = area->r_ytop - area->r_ybot;
|
|
|
|
|
width = area->r_xtop - area->r_xbot;
|
|
|
|
|
printf("got sliver %d %d %d %d [%d,%d]\n",
|
|
|
|
|
area->r_xtop, area->r_xbot, area->r_ytop,
|
|
|
|
|
area->r_ybot, expand_up,expand_side);
|
|
|
|
|
|
|
|
|
|
if ((height < width) || expand_up)
|
|
|
|
|
{
|
|
|
|
|
if (height >= CurCifLayer->min_width) return 0;
|
|
|
|
|
area->r_ytop += (CurCifLayer->min_width - height)/2;
|
|
|
|
|
area->r_ybot -= (CurCifLayer->min_width - height)/2;
|
|
|
|
|
}
|
|
|
|
|
if ((width < height) || expand_side)
|
|
|
|
|
{
|
|
|
|
|
if(width >= CurCifLayer->min_width) return 0;
|
|
|
|
|
area->r_xtop += (CurCifLayer->min_width - width)/2;
|
|
|
|
|
area->r_xbot -= (CurCifLayer->min_width - width)/2;
|
|
|
|
|
}
|
|
|
|
|
printf("created sliver %d %d %d %d \n",
|
|
|
|
|
area->r_xtop, area->r_xbot, area->r_ytop, area->r_ybot);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierPaintArrayFunc --
|
|
|
|
|
*
|
|
|
|
|
* This function is used to paint in interaction tiles from an
|
|
|
|
|
* array. It is called once for each tile to be copied, and
|
|
|
|
|
* paints the tile into cifHierCurPlane. Then the tile is
|
|
|
|
|
* offset by cifHierXSpacing and cifHierYSpacing, and copied
|
|
|
|
|
* again and again, cifHierCount times in all. The caller must
|
|
|
|
|
* set up these shared variables.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 0 to keep the search alive.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The plane pointed to by cifHierCurPlane gets modified.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierPaintArrayFunc(
|
|
|
|
|
Tile *tile)
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
Rect area;
|
|
|
|
|
int i, j, xbot, xtop;
|
|
|
|
|
|
|
|
|
|
TiToRect(tile, &area);
|
|
|
|
|
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
|
|
|
|
|
xbot = area.r_xbot;
|
|
|
|
|
xtop = area.r_xtop;
|
|
|
|
|
for (i=0; i<cifHierYCount; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j=0; j<cifHierXCount; j++)
|
|
|
|
|
{
|
|
|
|
|
DBPaintPlane(cifHierCurPlane, &area, CIFPaintTable,
|
|
|
|
|
(PaintUndoInfo *) NULL);
|
|
|
|
|
CIFTileOps += 1;
|
|
|
|
|
area.r_xbot += cifHierXSpacing;
|
|
|
|
|
area.r_xtop += cifHierXSpacing;
|
|
|
|
|
}
|
|
|
|
|
area.r_xbot = xbot;
|
|
|
|
|
area.r_xtop = xtop;
|
|
|
|
|
area.r_ybot += cifHierYSpacing;
|
|
|
|
|
area.r_ytop += cifHierYSpacing;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* cifHierArrayFunc --
|
|
|
|
|
*
|
|
|
|
|
* This procedure is called once for each array that we
|
|
|
|
|
* are to generate interaction CIF for. It computes all
|
|
|
|
|
* the CIF that must be present in the parent to compensate
|
|
|
|
|
* for the interactions between array elements.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* Always returns 2, to skip the remaining instances in the
|
|
|
|
|
* current array.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* CIF is added to the set of planes indicated by output.
|
|
|
|
|
*
|
|
|
|
|
* Design:
|
|
|
|
|
* This procedure is something like a cross between drcArrayFunc
|
|
|
|
|
* and DRCGenSubcells. It computes interaction CIF in the four
|
|
|
|
|
* areas of the array shown below, then replicates it over all
|
|
|
|
|
* the other elements of the array.
|
|
|
|
|
*
|
|
|
|
|
* ------------------------------CCCCC--------------
|
|
|
|
|
* | | CCCCC |
|
|
|
|
|
* | | CCCCC |
|
|
|
|
|
* | | CCCCC |
|
|
|
|
|
* | | CCCCCDDDDDDDDDDDDDD
|
|
|
|
|
* ------------------------------CCCCCDDDDDDDDDDDDDD
|
|
|
|
|
* | | CCCCCDDDDDDDDDDDDDD
|
|
|
|
|
* | | | |
|
|
|
|
|
* | | | |
|
|
|
|
|
* AAAAAAAAAAAAAAAAAAA | |
|
|
|
|
|
* AAAAAAAAAAAAAAAAAAA------------------------------
|
|
|
|
|
* AAAAAAAAAAAAAAAAAAA | |
|
|
|
|
|
* | BBBBB | |
|
|
|
|
|
* | BBBBB | |
|
|
|
|
|
* | BBBBB | |
|
|
|
|
|
* --------------BBBBB------------------------------
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
cifHierArrayFunc(
|
|
|
|
|
SearchContext *scx, /* Information about the search. */
|
|
|
|
|
Plane **output) /* Array of planes to hold results. */
|
2017-04-25 14:41:48 +02:00
|
|
|
{
|
|
|
|
|
Rect childArea, parentArea, A, B, C, D, expandedArea;
|
|
|
|
|
CellUse *use;
|
|
|
|
|
int radius, xsep, ysep, xsize, ysize, nx, ny, i, oldTileOps;
|
|
|
|
|
bool anyInteractions = FALSE;
|
|
|
|
|
|
|
|
|
|
use = scx->scx_use;
|
|
|
|
|
radius = CIFCurStyle->cs_radius;
|
|
|
|
|
if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi))
|
|
|
|
|
return 2;
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2021-06-07 22:38:12 +02:00
|
|
|
/* We only want interactions between neighboring cells, so only */
|
|
|
|
|
/* look at the bottom-left 2x2 set when calculating A and B, and */
|
|
|
|
|
/* only look at the top-right 2x2 set when calculating C and D. */
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/* Compute the sizes and separations of elements, in coordinates
|
|
|
|
|
* of the parent. If the array is 1-dimensional, we set the
|
|
|
|
|
* corresponding spacing to an impossibly large distance.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
childArea.r_xbot = 0;
|
|
|
|
|
childArea.r_ybot = 0;
|
|
|
|
|
|
|
|
|
|
/* Ensure that array width or height 1 corresponds to a separation */
|
|
|
|
|
/* large enough not to satisfy any conditions A, B, C, or D. */
|
|
|
|
|
|
|
|
|
|
if (use->cu_xlo == use->cu_xhi)
|
|
|
|
|
childArea.r_xtop = radius +
|
|
|
|
|
(use->cu_def->cd_bbox.r_xtop - use->cu_def->cd_bbox.r_xbot);
|
|
|
|
|
else childArea.r_xtop = use->cu_xsep;
|
|
|
|
|
if (use->cu_ylo == use->cu_yhi)
|
|
|
|
|
childArea.r_ytop = radius +
|
|
|
|
|
(use->cu_def->cd_bbox.r_ytop - use->cu_def->cd_bbox.r_ybot);
|
|
|
|
|
|
|
|
|
|
else childArea.r_ytop = use->cu_ysep;
|
|
|
|
|
GeoTransRect(&use->cu_transform, &childArea, &parentArea);
|
|
|
|
|
xsep = parentArea.r_xtop - parentArea.r_xbot;
|
|
|
|
|
ysep = parentArea.r_ytop - parentArea.r_ybot;
|
|
|
|
|
GeoTransRect(&use->cu_transform, &use->cu_def->cd_bbox, &parentArea);
|
|
|
|
|
xsize = parentArea.r_xtop - parentArea.r_xbot;
|
|
|
|
|
ysize = parentArea.r_ytop - parentArea.r_ybot;
|
|
|
|
|
nx = (use->cu_bbox.r_xtop - use->cu_bbox.r_xbot - xsize)/xsep;
|
|
|
|
|
nx += 1;
|
|
|
|
|
ny = (use->cu_bbox.r_ytop - use->cu_bbox.r_ybot - ysize)/ysep;
|
|
|
|
|
ny += 1;
|
|
|
|
|
|
|
|
|
|
/* Process each of the four areas A, B, C, and D. For each one,
|
|
|
|
|
* do three things: yank the relevant material into cell
|
|
|
|
|
* __CIF__, and generate a piece of CIF corresponding to each
|
|
|
|
|
* child area contributing to the overlap. This is all handled
|
|
|
|
|
* by the procedure cifHierElementFunc. Then generate the CIF
|
|
|
|
|
* for the combined information that was yanked into __CIF__.
|
|
|
|
|
* Collect all of the combined CIF from all four areas together
|
|
|
|
|
* into CIFTotalPlanes. Note: in each case we have to yank a larger
|
|
|
|
|
* area than we check, in order to include material that will be
|
|
|
|
|
* bloated or shrunk.
|
2021-06-07 22:38:12 +02:00
|
|
|
*
|
|
|
|
|
* (Updated 6/7/2021) A and B should be calculated and processed
|
|
|
|
|
* completely independently of C and D, or else if the array is
|
|
|
|
|
* small and the radius is large, then results from one will get
|
|
|
|
|
* picked up when making copies of the other, resulting in things
|
|
|
|
|
* getting painted out-of-bounds.
|
2017-04-25 14:41:48 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* A */
|
|
|
|
|
|
|
|
|
|
if (ysep < ysize + radius)
|
|
|
|
|
{
|
|
|
|
|
A.r_xbot = use->cu_bbox.r_xbot - radius;
|
|
|
|
|
A.r_xtop = use->cu_bbox.r_xbot + xsize + radius;
|
|
|
|
|
A.r_ybot = use->cu_bbox.r_ybot + ysep - radius;
|
|
|
|
|
A.r_ytop = use->cu_bbox.r_ybot + ysize + radius;
|
|
|
|
|
GEO_EXPAND(&A, CIFCurStyle->cs_radius, &expandedArea);
|
2021-06-07 22:38:12 +02:00
|
|
|
(void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
|
2017-04-25 14:41:48 +02:00
|
|
|
(ClientData) &A);
|
|
|
|
|
CIFErrorDef = use->cu_parent;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFTotalDef, use->cu_def, &A, CIFTotalPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
anyInteractions = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-07 22:38:12 +02:00
|
|
|
if ((xsep < xsize + radius) && (ysep < ysize + radius))
|
|
|
|
|
{
|
|
|
|
|
/* B */
|
|
|
|
|
|
|
|
|
|
B.r_xbot = use->cu_bbox.r_xbot + xsep - radius;
|
|
|
|
|
B.r_xtop = use->cu_bbox.r_xbot + xsize + radius;
|
|
|
|
|
B.r_ybot = use->cu_bbox.r_ybot - radius;
|
|
|
|
|
B.r_ytop = use->cu_bbox.r_ybot + ysep - radius;
|
|
|
|
|
GEO_EXPAND(&B, CIFCurStyle->cs_radius, &expandedArea);
|
|
|
|
|
(void) DBArraySr(use, &expandedArea, cifHierElementFuncLow,
|
|
|
|
|
(ClientData) &B);
|
|
|
|
|
CIFErrorDef = use->cu_parent;
|
|
|
|
|
CIFGen(CIFTotalDef, use->cu_def, &B, CIFTotalPlanes,
|
|
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (anyInteractions)
|
|
|
|
|
{
|
|
|
|
|
/* Remove redundant CIF that's already in the children, and
|
|
|
|
|
* make sure everything in the kids is in the parent too.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CIFErrorDef = use->cu_parent;
|
|
|
|
|
cifCheckAndErase(CIFCurStyle);
|
|
|
|
|
|
|
|
|
|
/* Lastly, paint everything back from our local planes into
|
|
|
|
|
* the planes of the caller. In doing this, stuff has to
|
|
|
|
|
* be replicated many times over to cover each of the array
|
|
|
|
|
* interaction areas.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
oldTileOps = CIFTileOps;
|
|
|
|
|
for (i=0; i<CIFCurStyle->cs_nLayers; i++)
|
|
|
|
|
{
|
|
|
|
|
int scale = CIFCurStyle->cs_scaleFactor;
|
|
|
|
|
Rect cifArea;
|
|
|
|
|
|
|
|
|
|
cifHierCurPlane = output[i];
|
|
|
|
|
CurCifLayer = CIFCurStyle->cs_layers[i]; /* for growSliver */
|
|
|
|
|
|
|
|
|
|
/* The left edge of the array (from A). */
|
|
|
|
|
|
|
|
|
|
if ((ny > 1) && (ysep < ysize + radius))
|
|
|
|
|
{
|
|
|
|
|
cifHierYSpacing = ysep * scale;
|
|
|
|
|
cifHierXSpacing = 0;
|
|
|
|
|
cifHierXCount = 1;
|
|
|
|
|
cifHierYCount = ny-1;
|
|
|
|
|
SCALE(&A, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((nx > 1) && (ny > 1) && (xsep < xsize + radius)
|
|
|
|
|
&& (ysep < ysize + radius))
|
|
|
|
|
{
|
|
|
|
|
/* The bottom edge of the array (from B). */
|
|
|
|
|
|
|
|
|
|
cifHierXSpacing = xsep * scale;
|
|
|
|
|
cifHierYSpacing = 0;
|
|
|
|
|
cifHierXCount = nx-1;
|
|
|
|
|
cifHierYCount = 1;
|
|
|
|
|
SCALE(&B, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
|
|
|
|
|
/* The core of the array (copied from A and B). Copy area
|
|
|
|
|
* from A, but not to exceed 1/2 Y array separation, into the
|
|
|
|
|
* inside area of the array. If the expanded area is > 1/2
|
|
|
|
|
* the array separation, then there is no need to copy from
|
|
|
|
|
* area B. Otherwise, copy area from B, extending up to
|
|
|
|
|
* the bottom of the area just copied, and not to exceed
|
|
|
|
|
* 1/2 the X array separation.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
cifHierXSpacing = xsep * scale;
|
|
|
|
|
cifHierYSpacing = ysep * scale;
|
|
|
|
|
cifHierXCount = nx-1;
|
|
|
|
|
cifHierYCount = ny-1;
|
|
|
|
|
|
|
|
|
|
/* Find top edge of cell */
|
|
|
|
|
A.r_xbot = use->cu_bbox.r_xbot;
|
|
|
|
|
A.r_xtop = use->cu_bbox.r_xbot + xsep;
|
|
|
|
|
A.r_ybot = use->cu_bbox.r_ybot + ysep;
|
|
|
|
|
A.r_ytop = use->cu_bbox.r_ybot + ysize;
|
|
|
|
|
/* Expand up/down but not by more than 1/2 ysep */
|
|
|
|
|
if ((2 * radius) > ysep)
|
|
|
|
|
{
|
|
|
|
|
A.r_ybot -= (ysep >> 1);
|
|
|
|
|
A.r_ytop += (ysep >> 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
A.r_ybot -= radius;
|
|
|
|
|
A.r_ytop += radius;
|
|
|
|
|
}
|
|
|
|
|
SCALE(&A, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
|
|
|
|
|
/* If the radius is more than half of ysep then there */
|
|
|
|
|
/* is nothing left that needs to be copied. */
|
|
|
|
|
|
|
|
|
|
if ((2 * radius) < ysep)
|
|
|
|
|
{
|
|
|
|
|
/* Find right edge of cell */
|
|
|
|
|
B.r_ybot = use->cu_bbox.r_ybot;
|
|
|
|
|
B.r_ytop = use->cu_bbox.r_ybot + ysep;
|
|
|
|
|
|
|
|
|
|
if (B.r_ytop > A.r_ybot) B.r_ytop = A.r_ybot;
|
|
|
|
|
|
|
|
|
|
B.r_xbot = use->cu_bbox.r_xbot + xsep;
|
|
|
|
|
B.r_xtop = use->cu_bbox.r_xbot + xsize;
|
|
|
|
|
/* Expand left/right but not by more than 1/2 xsep */
|
|
|
|
|
if ((2 * radius) > xsep)
|
|
|
|
|
{
|
|
|
|
|
B.r_xbot -= (xsep >> 1);
|
|
|
|
|
B.r_xtop += (xsep >> 1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
B.r_xbot -= radius;
|
|
|
|
|
B.r_xtop += radius;
|
|
|
|
|
}
|
|
|
|
|
SCALE(&B, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CIFHierRects += CIFTileOps - oldTileOps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clean up from areas A and B */
|
|
|
|
|
cifHierCleanup();
|
|
|
|
|
anyInteractions = FALSE;
|
|
|
|
|
|
|
|
|
|
/* Now do areas C and D */
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* C */
|
|
|
|
|
|
|
|
|
|
if (xsep < xsize + radius)
|
|
|
|
|
{
|
|
|
|
|
C.r_xbot = use->cu_bbox.r_xtop - xsize - radius;
|
|
|
|
|
C.r_xtop = use->cu_bbox.r_xtop - xsep + radius;
|
|
|
|
|
C.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
|
|
|
|
|
C.r_ytop = use->cu_bbox.r_ytop + radius;
|
|
|
|
|
GEO_EXPAND(&C, CIFCurStyle->cs_radius, &expandedArea);
|
2021-06-07 22:38:12 +02:00
|
|
|
(void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh,
|
2017-04-25 14:41:48 +02:00
|
|
|
(ClientData) &C);
|
|
|
|
|
CIFErrorDef = use->cu_parent;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFTotalDef, use->cu_def, &C, CIFTotalPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
anyInteractions = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((xsep < xsize + radius) && (ysep < ysize + radius))
|
|
|
|
|
{
|
|
|
|
|
/* D */
|
|
|
|
|
|
|
|
|
|
D.r_xbot = use->cu_bbox.r_xtop - xsep + radius;
|
|
|
|
|
D.r_xtop = use->cu_bbox.r_xtop + radius;
|
|
|
|
|
D.r_ybot = use->cu_bbox.r_ytop - ysize - radius;
|
|
|
|
|
D.r_ytop = use->cu_bbox.r_ytop - ysep + radius;
|
|
|
|
|
GEO_EXPAND(&D, CIFCurStyle->cs_radius, &expandedArea);
|
2021-06-07 22:38:12 +02:00
|
|
|
(void) DBArraySr(use, &expandedArea, cifHierElementFuncHigh,
|
2017-04-25 14:41:48 +02:00
|
|
|
(ClientData) &D);
|
|
|
|
|
CIFErrorDef = use->cu_parent;
|
2020-05-26 20:29:36 +02:00
|
|
|
CIFGen(CIFTotalDef, use->cu_def, &D, CIFTotalPlanes,
|
2020-11-12 16:34:27 +01:00
|
|
|
&CIFCurStyle->cs_hierLayers, FALSE, TRUE, TRUE,
|
|
|
|
|
(ClientData)NULL);
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (anyInteractions)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* Remove redundant CIF that's already in the children, and
|
|
|
|
|
* make sure everything in the kids is in the parent too.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
CIFErrorDef = use->cu_parent;
|
|
|
|
|
cifCheckAndErase(CIFCurStyle);
|
|
|
|
|
|
|
|
|
|
/* Lastly, paint everything back from our local planes into
|
|
|
|
|
* the planes of the caller. In doing this, stuff has to
|
|
|
|
|
* be replicated many times over to cover each of the array
|
|
|
|
|
* interaction areas.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
oldTileOps = CIFTileOps;
|
|
|
|
|
for (i=0; i<CIFCurStyle->cs_nLayers; i++)
|
|
|
|
|
{
|
|
|
|
|
int scale = CIFCurStyle->cs_scaleFactor;
|
|
|
|
|
Rect cifArea;
|
|
|
|
|
|
|
|
|
|
cifHierCurPlane = output[i];
|
|
|
|
|
CurCifLayer = CIFCurStyle->cs_layers[i]; /* for growSliver */
|
|
|
|
|
|
|
|
|
|
/* The top edge of the array (from C). */
|
|
|
|
|
|
|
|
|
|
if ((nx > 1) && (xsep < xsize + radius))
|
|
|
|
|
{
|
|
|
|
|
cifHierXSpacing = -xsep * scale;
|
|
|
|
|
cifHierYSpacing = 0;
|
|
|
|
|
cifHierXCount = nx-1;
|
|
|
|
|
cifHierYCount = 1;
|
|
|
|
|
SCALE(&C, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((nx > 1) && (ny > 1) && (xsep < xsize + radius)
|
|
|
|
|
&& (ysep < ysize + radius))
|
|
|
|
|
{
|
|
|
|
|
/* The right edge of the array (from D). */
|
|
|
|
|
|
|
|
|
|
cifHierXSpacing = 0;
|
|
|
|
|
cifHierYSpacing = -ysep * scale;
|
|
|
|
|
cifHierXCount = 1;
|
|
|
|
|
cifHierYCount = ny-1;
|
|
|
|
|
SCALE(&D, scale, &cifArea);
|
|
|
|
|
(void) DBSrPaintArea((Tile *) NULL, CIFTotalPlanes[i],
|
|
|
|
|
&cifArea, &CIFSolidBits, cifHierPaintArrayFunc,
|
|
|
|
|
(ClientData) NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CIFHierRects += CIFTileOps - oldTileOps;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cifHierCleanup();
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* CIFGenArrays --
|
|
|
|
|
*
|
|
|
|
|
* This procedure computes all of the CIF that must be added to
|
|
|
|
|
* a given area of a parent to compensate for interactions between
|
|
|
|
|
* elements of arrays in that area.
|
|
|
|
|
*
|
|
|
|
|
* Results:
|
|
|
|
|
* None.
|
|
|
|
|
*
|
|
|
|
|
* Side effects:
|
|
|
|
|
* The parameter output is modified (by OR'ing) to hold all
|
|
|
|
|
* the CIF that was generated for array interactions.
|
|
|
|
|
*
|
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
K&R: cif/*.c bulk function implementation conversion
Beware of the MISMATCH with the prototype found in original
source, with the type declaration below.
External call sites checked to confirm argument order is
correct with the argument name order.
// nedges <> dir
bool
cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */
int dir[], /* Array to hold directions. */
int nedges) /* Size of arrays. */
// spacing <> border
int
CIFGetContactSize(type, edge, spacing, border)
TileType type,
int *edge,
int *border,
int *spacing)
K&R obsolete syntax removal for C23 compatibility series
2024-10-04 12:34:19 +02:00
|
|
|
CIFGenArrays(
|
|
|
|
|
CellDef *def, /* Parent cell for which CIF is computed. */
|
|
|
|
|
Rect *area, /* All CIF in this area is interesting. */
|
|
|
|
|
Plane **output) /* Array of pointers to planes into which
|
2017-04-25 14:41:48 +02:00
|
|
|
* the CIF output will be OR'ed (real CIF
|
|
|
|
|
* only, temp layers won't appear). If
|
|
|
|
|
* output is NULL, then CIF is stored in
|
|
|
|
|
* CIFPlanes, and the planes are initially
|
|
|
|
|
* cleared.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
SearchContext scx;
|
|
|
|
|
int i, oldTileOps;
|
|
|
|
|
|
|
|
|
|
UndoDisable();
|
|
|
|
|
CIFInitCells();
|
|
|
|
|
|
|
|
|
|
/* Bill all tile operations here to hierarchical processing in
|
|
|
|
|
* addition to adding to the total.
|
|
|
|
|
*/
|
2020-05-23 23:13:14 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
oldTileOps = CIFTileOps;
|
|
|
|
|
|
|
|
|
|
if (output == NULL)
|
|
|
|
|
{
|
|
|
|
|
output = CIFPlanes;
|
|
|
|
|
for (i=0; i<CIFCurStyle->cs_nLayers; i++)
|
|
|
|
|
{
|
|
|
|
|
if (output[i] == NULL)
|
|
|
|
|
output[i] = DBNewPlane((ClientData) TT_SPACE);
|
|
|
|
|
else DBClearPaintPlane(output[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scx.scx_area = *area;
|
|
|
|
|
scx.scx_use = CIFDummyUse;
|
|
|
|
|
CIFDummyUse->cu_def = def;
|
|
|
|
|
(void) DBCellSrArea(&scx, cifHierArrayFunc, (ClientData) output);
|
|
|
|
|
|
|
|
|
|
CIFHierTileOps += CIFTileOps - oldTileOps;
|
|
|
|
|
UndoEnable();
|
|
|
|
|
}
|