Support for magnification, bounding boxes fully implemented
This commit is contained in:
parent
542737622f
commit
7d66ca1280
@ -350,18 +350,76 @@ void scan_library_references(gpointer library_list_item, gpointer user)
|
|||||||
g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib);
|
g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void apply_transforms_on_bounding_box(struct gds_cell_instance *cell_inst, struct gds_bounding_box *result)
|
||||||
|
{
|
||||||
|
struct gds_dpoint vertices[4];
|
||||||
|
int i;
|
||||||
|
double xmin= INT_MAX, xmax=INT_MIN, ymin=INT_MAX, ymax= INT_MIN;
|
||||||
|
double temp;
|
||||||
|
|
||||||
|
double phi = M_PI * cell_inst->angle / 180;
|
||||||
|
|
||||||
|
if (cell_inst->cell_ref->bounding_box.scanned == FALSE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Calculate all 4 bounding box points */
|
||||||
|
vertices[0].x = cell_inst->cell_ref->bounding_box.coords[0].x;
|
||||||
|
vertices[0].y = cell_inst->cell_ref->bounding_box.coords[0].y;
|
||||||
|
vertices[1].x = cell_inst->cell_ref->bounding_box.coords[0].x;
|
||||||
|
vertices[1].y = cell_inst->cell_ref->bounding_box.coords[1].y;
|
||||||
|
vertices[2].x = cell_inst->cell_ref->bounding_box.coords[1].x;
|
||||||
|
vertices[2].y = cell_inst->cell_ref->bounding_box.coords[1].y;
|
||||||
|
vertices[3].x = cell_inst->cell_ref->bounding_box.coords[1].x;
|
||||||
|
vertices[3].y = cell_inst->cell_ref->bounding_box.coords[0].y;
|
||||||
|
|
||||||
|
/* Apply flipping and magnification */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
vertices[i].x = (vertices[i].x * cell_inst->magnification);
|
||||||
|
vertices[i].y = (vertices[i].y * cell_inst->magnification * (cell_inst->flipped ? -1 : 1));
|
||||||
|
}
|
||||||
|
/* Apply rotation */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
temp =(cos(phi) * vertices[i].x - sin(phi) * vertices[i].y);
|
||||||
|
vertices[i].y =(sin(phi) * vertices[i].x + cos(phi) * vertices[i].y);
|
||||||
|
vertices[i].x = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Translate origin */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
vertices[i].x += (double)cell_inst->origin.x;
|
||||||
|
vertices[i].y += (double)cell_inst->origin.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate new bounding box */
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
xmin = MIN(xmin, vertices[i].x);
|
||||||
|
ymin = MIN(ymin, vertices[i].y);
|
||||||
|
ymax = MAX(ymax, vertices[i].y);
|
||||||
|
xmax = MAX(xmax, vertices[i].x);
|
||||||
|
}
|
||||||
|
|
||||||
|
result->scanned = TRUE;
|
||||||
|
result->coords[0].x = xmin;
|
||||||
|
result->coords[0].y = ymin;
|
||||||
|
result->coords[1].x = xmax;
|
||||||
|
result->coords[1].y = ymax;
|
||||||
|
}
|
||||||
|
|
||||||
static void cell_create_bounding_box(struct gds_cell *cell)
|
static void cell_create_bounding_box(struct gds_cell *cell)
|
||||||
{
|
{
|
||||||
GList *ref;
|
GList *ref;
|
||||||
GList *gfx_list;
|
GList *gfx_list;
|
||||||
GList *vertex_list;
|
GList *vertex_list;
|
||||||
|
|
||||||
|
struct gds_bounding_box box_transform;
|
||||||
struct gds_cell_instance *cell_inst;
|
struct gds_cell_instance *cell_inst;
|
||||||
struct gds_graphics *gfx;
|
struct gds_graphics *gfx;
|
||||||
struct gds_point *vertex;
|
struct gds_point *vertex;
|
||||||
|
|
||||||
int xlow=0, xhigh=0, ylow=0, yhigh=0;
|
double xlow=INT_MAX, xhigh=INT_MIN, ylow=INT_MAX, yhigh=INT_MIN;
|
||||||
gboolean first = TRUE;
|
|
||||||
|
|
||||||
if (cell->bounding_box.scanned == TRUE)
|
if (cell->bounding_box.scanned == TRUE)
|
||||||
return;
|
return;
|
||||||
@ -372,30 +430,16 @@ static void cell_create_bounding_box(struct gds_cell *cell)
|
|||||||
if (cell_inst->cell_ref) {
|
if (cell_inst->cell_ref) {
|
||||||
if (cell_inst->cell_ref->bounding_box.scanned == FALSE)
|
if (cell_inst->cell_ref->bounding_box.scanned == FALSE)
|
||||||
cell_create_bounding_box(cell_inst->cell_ref);
|
cell_create_bounding_box(cell_inst->cell_ref);
|
||||||
/* TODO: calculate rotation and inversion to process size correctly */
|
|
||||||
|
/* Apply transforms of cell in current cell to calculate the box of the specific instance */
|
||||||
if (cell_inst->cell_ref->bounding_box.scanned == TRUE) {
|
if (cell_inst->cell_ref->bounding_box.scanned == TRUE) {
|
||||||
if (first == TRUE) {
|
apply_transforms_on_bounding_box(cell_inst, &box_transform);
|
||||||
xlow = cell_inst->cell_ref->bounding_box.coords[0].x +
|
xlow = MIN(xlow, box_transform.coords[0].x);
|
||||||
cell_inst->origin.x;
|
ylow = MIN(ylow, box_transform.coords[0].y);
|
||||||
ylow = cell_inst->cell_ref->bounding_box.coords[0].y +
|
xhigh = MAX(xhigh, box_transform.coords[1].x);
|
||||||
cell_inst->origin.y;
|
yhigh = MAX(yhigh, box_transform.coords[1].y);
|
||||||
xhigh = cell_inst->cell_ref->bounding_box.coords[1].x +
|
|
||||||
cell_inst->origin.x;
|
|
||||||
yhigh = cell_inst->cell_ref->bounding_box.coords[1].y +
|
|
||||||
cell_inst->origin.y;
|
|
||||||
first = FALSE;
|
|
||||||
} else {
|
|
||||||
xlow = MIN(cell_inst->cell_ref->bounding_box.coords[0].x +
|
|
||||||
cell_inst->origin.x, xlow);
|
|
||||||
ylow = MIN(cell_inst->cell_ref->bounding_box.coords[0].y +
|
|
||||||
cell_inst->origin.y, ylow);
|
|
||||||
xhigh = MAX(cell_inst->cell_ref->bounding_box.coords[1].x +
|
|
||||||
cell_inst->origin.x, xhigh);
|
|
||||||
yhigh = MAX(cell_inst->cell_ref->bounding_box.coords[1].y +
|
|
||||||
cell_inst->origin.y, yhigh);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
GDS_WARN("Unscanned cells present. This should not happen");
|
GDS_WARN("Unscanned cells present: %s. This should not happen", cell_inst->ref_name);
|
||||||
} else
|
} else
|
||||||
GDS_WARN("Cell referenced that does not exist: %s. Bounding box might be incorrect.",
|
GDS_WARN("Cell referenced that does not exist: %s. Bounding box might be incorrect.",
|
||||||
cell_inst->ref_name);
|
cell_inst->ref_name);
|
||||||
@ -407,22 +451,16 @@ static void cell_create_bounding_box(struct gds_cell *cell)
|
|||||||
|
|
||||||
for (vertex_list = gfx->vertices; vertex_list != NULL; vertex_list = vertex_list->next) {
|
for (vertex_list = gfx->vertices; vertex_list != NULL; vertex_list = vertex_list->next) {
|
||||||
vertex = (struct gds_point *)vertex_list->data;
|
vertex = (struct gds_point *)vertex_list->data;
|
||||||
if (first == TRUE) {
|
|
||||||
xlow = vertex->x - (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2: 0);
|
xlow = MIN(xlow, (double)vertex->x - (gfx->gfx_type == GRAPHIC_PATH ? (double)gfx->width_absolute / 2 : 0));
|
||||||
ylow = vertex->y - (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0);
|
ylow = MIN(ylow, (double)vertex->y - (gfx->gfx_type == GRAPHIC_PATH ? (double)gfx->width_absolute / 2 : 0));
|
||||||
xhigh = vertex->x + (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2: 0);
|
xhigh = MAX(xhigh, (double)vertex->x + (gfx->gfx_type == GRAPHIC_PATH ? (double)gfx->width_absolute / 2 : 0));
|
||||||
yhigh = vertex->y + (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0);
|
yhigh = MAX(yhigh, (double)vertex->y + (gfx->gfx_type == GRAPHIC_PATH ? (double)gfx->width_absolute / 2 : 0));
|
||||||
first = FALSE;
|
|
||||||
} else {
|
|
||||||
xlow = MIN(xlow, vertex->x - (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0));
|
|
||||||
ylow = MIN(ylow, vertex->y - (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0));
|
|
||||||
xhigh = MAX(xhigh, vertex->x + (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0));
|
|
||||||
yhigh = MAX(yhigh, vertex->y + (gfx->gfx_type == GRAPHIC_PATH ? gfx->width_absolute / 2 : 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Cell '%s' has size: %d / %d\n", cell->name, xhigh - xlow, yhigh - ylow);
|
printf("Cell '%s' has size: %lf / %lf\n", cell->name, xhigh - xlow, yhigh - ylow);
|
||||||
cell->bounding_box.coords[0].x = xlow;
|
cell->bounding_box.coords[0].x = xlow;
|
||||||
cell->bounding_box.coords[0].y = ylow;
|
cell->bounding_box.coords[0].y = ylow;
|
||||||
cell->bounding_box.coords[1].x = xhigh;
|
cell->bounding_box.coords[1].x = xhigh;
|
||||||
|
@ -14,9 +14,14 @@ struct gds_point {
|
|||||||
int y;
|
int y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gds_dpoint {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
|
||||||
struct gds_bounding_box {
|
struct gds_bounding_box {
|
||||||
gboolean scanned;
|
gboolean scanned;
|
||||||
struct gds_point coords[2];
|
struct gds_dpoint coords[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gds_time_field {
|
struct gds_time_field {
|
||||||
|
@ -170,7 +170,8 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
|
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
g_string_printf(buffer, "\\begin{scope}[yscale=%s]\n", (inst->flipped ? "-1" : "1"));
|
g_string_printf(buffer, "\\begin{scope}[yscale=%lf, xscale=%lf]\n", (inst->flipped ? -1*inst->magnification : inst->magnification),
|
||||||
|
inst->magnification);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
render_cell(inst->cell_ref, layer_infos, tex_file, buffer);
|
render_cell(inst->cell_ref, layer_infos, tex_file, buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user