cairo layer renderer
This commit is contained in:
parent
2a615367d7
commit
59ec0c5a10
@ -29,6 +29,119 @@ struct cairo_layer {
|
|||||||
struct layer_info *linfo;
|
struct layer_info *linfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void revert_inherited_transform(struct cairo_layer *layers)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_LAYERS; i++) {
|
||||||
|
if (layers[i].cr == NULL)
|
||||||
|
continue;
|
||||||
|
cairo_restore(layers[i].cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
|
||||||
|
const struct gds_point *origin,
|
||||||
|
double magnification,
|
||||||
|
gboolean flipping,
|
||||||
|
double rotation,
|
||||||
|
double scale)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
cairo_t *temp_layer_cr;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_LAYERS; i++) {
|
||||||
|
temp_layer_cr = layers[i].cr;
|
||||||
|
if (temp_layer_cr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Save the state and apply transformation */
|
||||||
|
cairo_save(temp_layer_cr);
|
||||||
|
cairo_translate(temp_layer_cr, (double)origin->x/scale, (double)origin->y/scale);
|
||||||
|
cairo_rotate(temp_layer_cr, M_PI*rotation/180.0);
|
||||||
|
cairo_scale(temp_layer_cr, magnification,
|
||||||
|
(flipping == TRUE ? -magnification : magnification));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, double scale)
|
||||||
|
{
|
||||||
|
GList *instance_list;
|
||||||
|
struct gds_cell *temp_cell;
|
||||||
|
struct gds_cell_instance *cell_instance;
|
||||||
|
GList *gfx_list;
|
||||||
|
struct gds_graphics *gfx;
|
||||||
|
GList *vertex_list;
|
||||||
|
struct gds_point *vertex;
|
||||||
|
cairo_t *cr;
|
||||||
|
|
||||||
|
/* Render child cells */
|
||||||
|
for (instance_list = cell->child_cells; instance_list != NULL; instance_list = instance_list->next) {
|
||||||
|
cell_instance = (struct gds_cell_instance *)instance_list->data;
|
||||||
|
if ((temp_cell = cell_instance->cell_ref) != NULL) {
|
||||||
|
apply_inherited_transform_to_all_layers(layers,
|
||||||
|
&cell_instance->origin,
|
||||||
|
cell_instance->magnification,
|
||||||
|
cell_instance->flipped,
|
||||||
|
cell_instance->angle,
|
||||||
|
scale);
|
||||||
|
render_cell(temp_cell, layers, scale);
|
||||||
|
revert_inherited_transform(layers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render graphics */
|
||||||
|
for (gfx_list = cell->graphic_objs; gfx_list != NULL; gfx_list = gfx_list->next) {
|
||||||
|
gfx = (struct gds_graphics *)gfx_list->data;
|
||||||
|
|
||||||
|
/* Get layer renderer */
|
||||||
|
if (gfx->layer >= MAX_LAYERS)
|
||||||
|
continue;
|
||||||
|
if ((cr = layers[gfx->layer].cr) == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Apply settings */
|
||||||
|
cairo_set_line_width(cr, (gfx->width_absolute ? gfx->width_absolute : 1));
|
||||||
|
|
||||||
|
switch (gfx->path_render_type) {
|
||||||
|
case PATH_FLUSH:
|
||||||
|
cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
|
||||||
|
break;
|
||||||
|
case PATH_ROUNDED:
|
||||||
|
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
|
||||||
|
break;
|
||||||
|
case PATH_SQUARED:
|
||||||
|
cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add vertices */
|
||||||
|
for (vertex_list = gfx->vertices; vertex_list != NULL; vertex_list = vertex_list->next) {
|
||||||
|
vertex = (struct gds_point *)vertex_list->data;
|
||||||
|
|
||||||
|
/* If first point -> move to, else line to */
|
||||||
|
if (vertex_list->prev == NULL)
|
||||||
|
cairo_move_to(cr, vertex->x/scale, vertex->y/scale);
|
||||||
|
else
|
||||||
|
cairo_line_to(cr, vertex->x/scale, vertex->y/scale);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create graphics object */
|
||||||
|
switch (gfx->gfx_type) {
|
||||||
|
case GRAPHIC_PATH:
|
||||||
|
cairo_stroke(cr);
|
||||||
|
break;
|
||||||
|
case GRAPHIC_POLYGON:
|
||||||
|
cairo_close_path(cr);
|
||||||
|
cairo_fill(cr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale)
|
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
@ -56,7 +169,8 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
|
|||||||
lay->rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
|
lay->rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
NULL);
|
NULL);
|
||||||
lay->cr = cairo_create(layers[(unsigned int)linfo->layer].rec);
|
lay->cr = cairo_create(layers[(unsigned int)linfo->layer].rec);
|
||||||
cairo_scale(lay->cr, 1/scale, 1/scale);
|
cairo_scale(lay->cr, 1, -1); // Fix coordinate system
|
||||||
|
cairo_set_source_rgb(lay->cr, 1, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
printf("Layer number (%d) too high!\n", linfo->layer);
|
printf("Layer number (%d) too high!\n", linfo->layer);
|
||||||
goto ret_clear_layers;
|
goto ret_clear_layers;
|
||||||
@ -64,6 +178,11 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render_cell(cell, layers, scale);
|
||||||
|
|
||||||
|
/* Todo: Tranfer all layers in order to output file */
|
||||||
|
|
||||||
|
|
||||||
ret_clear_layers:
|
ret_clear_layers:
|
||||||
for (i = 0; i < MAX_LAYERS; i++) {
|
for (i = 0; i < MAX_LAYERS; i++) {
|
||||||
lay = &layers[i];
|
lay = &layers[i];
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "../layer-selector.h"
|
#include "../layer-selector.h"
|
||||||
#include "../gds-parser/gds-types.h"
|
#include "../gds-parser/gds-types.h"
|
||||||
|
|
||||||
#define MAX_LAYERS (2048)
|
#define MAX_LAYERS (300)
|
||||||
|
|
||||||
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale);
|
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user