diff --git a/gds-parser/gds-parser.c b/gds-parser/gds-parser.c index db344db..b549a91 100644 --- a/gds-parser/gds-parser.c +++ b/gds-parser/gds-parser.c @@ -58,6 +58,7 @@ enum record { STRANS = 0x1A01, BOX = 0x2D00, LAYER = 0x0D02, + WIDTH = 0x0F03, }; static int name_cell_ref(struct gds_cell_instance *cell_inst, @@ -580,6 +581,8 @@ int parse_gds_from_file(const char *filename, GList **library_list) break; case STRANS: break; + case WIDTH: + break; default: //GDS_WARN("Record: %04x, len: %u", (unsigned int)rec_type, (unsigned int)rec_data_length); break; @@ -640,6 +643,12 @@ int parse_gds_from_file(const char *filename, GList **library_list) case SNAME: name_cell_ref(current_s_reference, read, workbuff); break; + case WIDTH: + if (!current_graphics) { + GDS_WARN("Width defined outside of path element"); + } + current_graphics->width_absolute = gds_convert_signed_int(workbuff); + break; case LAYER: if (!current_graphics) { GDS_WARN("Layer has to be defined inside graphics object. Probably unknown object. Implement it yourself!"); diff --git a/latex-output/latex-output.c b/latex-output/latex-output.c index 84fca4d..ac0fdff 100644 --- a/latex-output/latex-output.c +++ b/latex-output/latex-output.c @@ -29,7 +29,9 @@ static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString for (list = layer_infos; list != NULL; list = list->next) { lifo = (struct layer_info *)list->data; - g_string_printf(buffer, "\\pgfdeclarelayer{l%d}\n", lifo->layer); + g_string_printf(buffer, "\\pgfdeclarelayer{l%d}\n\\definecolor{c%d}{rgb}{%lf,%lf,%lf}\n", + lifo->layer, lifo->layer, + lifo->color.red, lifo->color.green, lifo->color.blue); WRITEOUT_BUFFER(buffer); } @@ -49,31 +51,118 @@ static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString fwrite("\n", sizeof(char), 1, tex_file); } -static int sorting_func_stack(struct layer_info *info1, struct layer_info *info2) +/** + * @brief write_layer_env + * @param tex_file + * @param layer + * @param buffer + * @return TRUE if layer is placeable + */ +static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList *linfo, GString *buffer) { - return info1->stacked_position - info2->stacked_position; + GList *temp; + struct layer_info *inf; + + for (temp = linfo; temp != NULL; temp = temp->next) { + inf = (struct layer_info *)temp->data; + if (inf->layer == layer) { + color->alpha = inf->color.alpha; + color->red = inf->color.red; + color->green = inf->color.green; + color->blue = inf->color.blue; + g_string_printf(buffer, "\\begin{pgfonlayer}{l%d}\n", layer); + WRITEOUT_BUFFER(buffer); + return TRUE; + } + } + return FALSE; } -static void sort_layers_for_rendering(GList **layer_infos) + +static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GString *buffer) { - GList *list = *layer_infos; - list = g_list_sort(list, (GCompareFunc)sorting_func_stack); - *layer_infos = list; + GList *temp; + GList *temp_vertex; + struct gds_graphics *gfx; + struct gds_point *pt; + GdkRGBA color; + int width; + gchar *red, *green, *blue, *opacity; + + for (temp = graphics; temp != NULL; temp = temp->next) { + gfx = (struct gds_graphics *)temp->data; + if (write_layer_env(tex_file, &color, (int)gfx->layer, linfo, buffer) == TRUE) { + + /* Layer is defined => create graphics */ + if (gfx->type == GRAPHIC_POLYGON) { + + + g_string_printf(buffer, "\\draw[line width=0.00001 pt, draw={c%d}, fill={c%d}, fill opacity={%lf}] ", + gfx->layer, gfx->layer, color.alpha); + WRITEOUT_BUFFER(buffer); + /* Append vertices */ + for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) { + pt = (struct gds_point *)temp_vertex->data; + g_string_printf(buffer, "(%lf pt, %lf pt) -- ", ((double)pt->x)/1000.0, ((double)pt->y)/1000.0); + WRITEOUT_BUFFER(buffer); + } + g_string_printf(buffer, "cycle;\n"); + WRITEOUT_BUFFER(buffer); + } + + g_string_printf(buffer, "\\end{pgfonlayer}\n"); + WRITEOUT_BUFFER(buffer); + } + + } /* For graphics */ +} + + +static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer) +{ + + GList *list_child; + struct gds_cell_instance *inst; + + /* Draw polygons of current cell */ + generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer); + + /* Draw polygons of childs */ + for (list_child = cell->child_cells; list_child != NULL; list_child = list_child->next) { + inst = (struct gds_cell_instance *)list_child->data; + /* generate translation scope */ + g_string_printf(buffer, "\\begin{scope}[shift={(%lf pt,%lf pt)}, rotate=%lf]\n", + ((double)inst->origin.x)/1000.0,((double)inst->origin.y)/1000.0, + inst->angle); + WRITEOUT_BUFFER(buffer); + + g_string_printf(buffer, "\\begin{scope}[xscale=%s]\n", + (inst->flipped ? "-1" : "1")); + WRITEOUT_BUFFER(buffer); + + if (inst->cell_ref) + render_cell(inst->cell_ref, layer_infos, tex_file, buffer); + + g_string_printf(buffer, "\\end{scope}\n"); + WRITEOUT_BUFFER(buffer); + + g_string_printf(buffer, "\\end{scope}\n"); + WRITEOUT_BUFFER(buffer); + } + } void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file) { GString *working_line; + if (!tex_file || !layer_infos || !cell) return; /* 10 kB Line working buffer should be enough */ working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024); - /* Sort layer according to target layer */ - sort_layers_for_rendering(&layer_infos); - /* Write layer definitions */ write_layer_definitions(tex_file, layer_infos, working_line); @@ -82,7 +171,7 @@ void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_fi WRITEOUT_BUFFER(working_line); /* Generate graphics output */ - + render_cell(cell, layer_infos, tex_file, working_line); g_string_printf(working_line, "\\end{tikzpicture}\n"); diff --git a/layer-selector.c b/layer-selector.c index b3fc654..dc8d336 100644 --- a/layer-selector.c +++ b/layer-selector.c @@ -307,6 +307,7 @@ static void load_layer_mapping_from_file(gchar *file_name) layer_element_set_color(le, &color); layer_element_set_export(le, export); layer_element_set_name(le, name); + g_free(name); /* Dereference and remove from list */ g_object_unref(G_OBJECT(le));