Compare commits
8 Commits
v1.0-rc1
...
4c04ce3614
Author | SHA1 | Date | |
---|---|---|---|
4c04ce3614 | |||
a2bc980c64 | |||
73ea4d6838 | |||
526785cffd | |||
6a8b359f3d | |||
7734467ea9 | |||
7d66ca1280 | |||
542737622f |
@@ -2,17 +2,18 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_search_module(GLIB REQUIRED glib-2.0)
|
pkg_search_module(GLIB REQUIRED glib-2.0)
|
||||||
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
||||||
|
pkg_check_modules(CAIRO REQUIRED cairo)
|
||||||
|
|
||||||
project(gds-render)
|
project(gds-render)
|
||||||
|
|
||||||
add_subdirectory(glade)
|
add_subdirectory(glade)
|
||||||
|
|
||||||
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS})
|
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS})
|
||||||
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS})
|
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
|
||||||
add_definitions(${GLIB2_CFLAGS_OTHER})
|
add_definitions(${GLIB2_CFLAGS_OTHER})
|
||||||
|
|
||||||
|
|
||||||
aux_source_directory("layer-widget" LAYER_SOURCES)
|
aux_source_directory("widgets" LAYER_SOURCES)
|
||||||
aux_source_directory("tree-renderer" RENDERER_SOURCES)
|
aux_source_directory("tree-renderer" RENDERER_SOURCES)
|
||||||
aux_source_directory("gds-parser" PARSER_SOURCES)
|
aux_source_directory("gds-parser" PARSER_SOURCES)
|
||||||
aux_source_directory("latex-output" LATEX_SOURCES)
|
aux_source_directory("latex-output" LATEX_SOURCES)
|
||||||
@@ -32,5 +33,5 @@ add_compile_options(-Wall)
|
|||||||
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
|
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
|
||||||
add_dependencies(${PROJECT_NAME} glib-resources)
|
add_dependencies(${PROJECT_NAME} glib-resources)
|
||||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
|
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
|
||||||
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} m)
|
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m)
|
||||||
|
|
||||||
|
@@ -33,9 +33,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
|
||||||
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__)
|
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__)
|
||||||
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__)
|
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__)
|
||||||
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
enum record {
|
enum record {
|
||||||
INVALID = 0x0000,
|
INVALID = 0x0000,
|
||||||
@@ -223,6 +226,7 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
|
|||||||
cell->child_cells = NULL;
|
cell->child_cells = NULL;
|
||||||
cell->graphic_objs = NULL;
|
cell->graphic_objs = NULL;
|
||||||
cell->name[0] = 0;
|
cell->name[0] = 0;
|
||||||
|
cell->bounding_box.scanned = FALSE;
|
||||||
} else
|
} else
|
||||||
return NULL;
|
return NULL;
|
||||||
/* return cell */
|
/* return cell */
|
||||||
@@ -347,6 +351,221 @@ 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 calculate_bounding_path_box(struct gds_graphics *path, struct gds_bounding_box *box)
|
||||||
|
{
|
||||||
|
cairo_surface_t *surf;
|
||||||
|
cairo_t *cr;
|
||||||
|
GList *vertex_list;
|
||||||
|
struct gds_point *vertex;
|
||||||
|
|
||||||
|
double x0, y0, width, height;
|
||||||
|
|
||||||
|
if (path == NULL || box == NULL)
|
||||||
|
return;
|
||||||
|
if (path->vertices == NULL)
|
||||||
|
return;
|
||||||
|
if (path->vertices->data == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
box->scanned = FALSE;
|
||||||
|
|
||||||
|
/* Check path length */
|
||||||
|
if (g_list_length(path->vertices) < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
surf = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
|
||||||
|
cr = cairo_create(surf);
|
||||||
|
|
||||||
|
/* Prepare line properties */
|
||||||
|
switch (path->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;
|
||||||
|
default:
|
||||||
|
cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_set_line_width(cr, path->width_absolute);
|
||||||
|
cairo_set_source_rgba(cr, 1, 1 , 0, 0.5);
|
||||||
|
|
||||||
|
/* Start at first point */
|
||||||
|
vertex = (struct gds_point *)path->vertices->data;
|
||||||
|
cairo_move_to(cr, (double)vertex->x, (double)vertex->y);
|
||||||
|
|
||||||
|
/* Remaining points */
|
||||||
|
for (vertex_list = path->vertices->next; vertex_list != NULL; vertex_list = vertex_list->next) {
|
||||||
|
vertex = (struct gds_point *)vertex_list->data;
|
||||||
|
cairo_line_to(cr, (double)vertex->x, (double)vertex->y);
|
||||||
|
}
|
||||||
|
cairo_stroke(cr);
|
||||||
|
|
||||||
|
cairo_recording_surface_ink_extents(surf, &x0, &y0, &width, &height);
|
||||||
|
box->coords[0].x = x0;
|
||||||
|
box->coords[0].y = y0;
|
||||||
|
box->coords[1].x = (x0+width);
|
||||||
|
box->coords[1].y = (y0+height);
|
||||||
|
box->scanned = TRUE;
|
||||||
|
cairo_destroy(cr);
|
||||||
|
cairo_surface_destroy(surf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_bounding_box_with_gfx(struct gds_graphics *gfx, double *xlow,
|
||||||
|
double *ylow, double *xhigh, double *yhigh)
|
||||||
|
{
|
||||||
|
GList *vertex_list;
|
||||||
|
struct gds_point *vertex;
|
||||||
|
struct gds_bounding_box path_box;
|
||||||
|
|
||||||
|
path_box.scanned = FALSE;
|
||||||
|
|
||||||
|
if (gfx->gfx_type == GRAPHIC_POLYGON) {
|
||||||
|
for (vertex_list = gfx->vertices; vertex_list != NULL; vertex_list = vertex_list->next) {
|
||||||
|
vertex = (struct gds_point *)vertex_list->data;
|
||||||
|
|
||||||
|
*xlow = MIN(*xlow, (double)vertex->x);
|
||||||
|
*ylow = MIN(*ylow, (double)vertex->y);
|
||||||
|
*xhigh = MAX(*xhigh, (double)vertex->x);
|
||||||
|
*yhigh = MAX(*yhigh, (double)vertex->y);
|
||||||
|
}
|
||||||
|
} else if (gfx->gfx_type == GRAPHIC_PATH) {
|
||||||
|
calculate_bounding_path_box(gfx, &path_box);
|
||||||
|
if (path_box.scanned == TRUE) {
|
||||||
|
*xlow = MIN(*xlow, path_box.coords[0].x);
|
||||||
|
*ylow = MIN(*ylow, path_box.coords[0].y);
|
||||||
|
*xhigh = MAX(*xhigh, path_box.coords[1].x);
|
||||||
|
*yhigh = MAX(*yhigh, path_box.coords[1].y);
|
||||||
|
} else
|
||||||
|
GDS_WARN("Bounding box of path not calculated");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cell_create_bounding_box(struct gds_cell *cell)
|
||||||
|
{
|
||||||
|
GList *ref;
|
||||||
|
GList *gfx_list;
|
||||||
|
|
||||||
|
struct gds_bounding_box box_transform;
|
||||||
|
struct gds_cell_instance *cell_inst;
|
||||||
|
struct gds_graphics *gfx;
|
||||||
|
|
||||||
|
double xlow=INT_MAX, xhigh=INT_MIN, ylow=INT_MAX, yhigh=INT_MIN;
|
||||||
|
|
||||||
|
if (cell->bounding_box.scanned == TRUE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Generate bounding boxes of child cells and update current box*/
|
||||||
|
for (ref = cell->child_cells; ref != NULL; ref = ref->next) {
|
||||||
|
cell_inst = (struct gds_cell_instance *)ref->data;
|
||||||
|
if (cell_inst->cell_ref) {
|
||||||
|
if (cell_inst->cell_ref->bounding_box.scanned == FALSE)
|
||||||
|
cell_create_bounding_box(cell_inst->cell_ref);
|
||||||
|
|
||||||
|
/* Apply transforms of cell in current cell to calculate the box of the specific instance */
|
||||||
|
if (cell_inst->cell_ref->bounding_box.scanned == TRUE) {
|
||||||
|
apply_transforms_on_bounding_box(cell_inst, &box_transform);
|
||||||
|
xlow = MIN(xlow, box_transform.coords[0].x);
|
||||||
|
ylow = MIN(ylow, box_transform.coords[0].y);
|
||||||
|
xhigh = MAX(xhigh, box_transform.coords[1].x);
|
||||||
|
yhigh = MAX(yhigh, box_transform.coords[1].y);
|
||||||
|
} else
|
||||||
|
GDS_WARN("Unscanned cells present: %s. This should not happen", cell_inst->ref_name);
|
||||||
|
} else
|
||||||
|
GDS_WARN("Cell referenced that does not exist: %s. Bounding box might be incorrect.",
|
||||||
|
cell_inst->ref_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate update box using graphic objects*/
|
||||||
|
for (gfx_list = cell->graphic_objs; gfx_list != NULL; gfx_list = gfx_list->next) {
|
||||||
|
gfx = (struct gds_graphics *)gfx_list->data;
|
||||||
|
|
||||||
|
update_bounding_box_with_gfx(gfx, &xlow, &ylow, &xhigh, &yhigh);
|
||||||
|
}
|
||||||
|
|
||||||
|
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].y = ylow;
|
||||||
|
cell->bounding_box.coords[1].x = xhigh;
|
||||||
|
cell->bounding_box.coords[1].y = yhigh;
|
||||||
|
cell->bounding_box.scanned = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void library_create_bounding_boxes(gpointer library_list_item, gpointer user)
|
||||||
|
{
|
||||||
|
GList *cell_list;
|
||||||
|
struct gds_library *lib = (struct gds_library *)library_list_item;
|
||||||
|
if (!lib)
|
||||||
|
return;
|
||||||
|
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next) {
|
||||||
|
cell_create_bounding_box((struct gds_cell *)cell_list->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date)
|
void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -727,8 +946,13 @@ int parse_gds_from_file(const char *filename, GList **library_list)
|
|||||||
if (!run) {
|
if (!run) {
|
||||||
/* Iterate and find references to cells */
|
/* Iterate and find references to cells */
|
||||||
g_list_foreach(lib_list, scan_library_references, NULL);
|
g_list_foreach(lib_list, scan_library_references, NULL);
|
||||||
|
/* Create bounding boxes */
|
||||||
|
g_list_foreach(lib_list, library_create_bounding_boxes, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*library_list = lib_list;
|
*library_list = lib_list;
|
||||||
|
|
||||||
free(workbuff);
|
free(workbuff);
|
||||||
|
@@ -9,6 +9,21 @@
|
|||||||
enum graphics_type {GRAPHIC_PATH = 0, GRAPHIC_POLYGON = 1};
|
enum graphics_type {GRAPHIC_PATH = 0, GRAPHIC_POLYGON = 1};
|
||||||
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2};
|
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2};
|
||||||
|
|
||||||
|
struct gds_point {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_dpoint {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gds_bounding_box {
|
||||||
|
gboolean scanned;
|
||||||
|
struct gds_dpoint coords[2];
|
||||||
|
};
|
||||||
|
|
||||||
struct gds_time_field {
|
struct gds_time_field {
|
||||||
uint16_t year;
|
uint16_t year;
|
||||||
uint16_t month;
|
uint16_t month;
|
||||||
@@ -18,11 +33,6 @@ struct gds_time_field {
|
|||||||
uint16_t second;
|
uint16_t second;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gds_point {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gds_graphics {
|
struct gds_graphics {
|
||||||
enum graphics_type gfx_type;
|
enum graphics_type gfx_type;
|
||||||
GList *vertices;
|
GList *vertices;
|
||||||
@@ -47,6 +57,7 @@ struct gds_cell {
|
|||||||
struct gds_time_field access_time;
|
struct gds_time_field access_time;
|
||||||
GList *child_cells;
|
GList *child_cells;
|
||||||
GList *graphic_objs;
|
GList *graphic_objs;
|
||||||
|
struct gds_bounding_box bounding_box;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gds_library {
|
struct gds_library {
|
||||||
|
@@ -2,6 +2,7 @@ add_custom_target(glib-resources DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
|||||||
add_custom_command(DEPENDS
|
add_custom_command(DEPENDS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/resources.xml
|
${CMAKE_CURRENT_SOURCE_DIR}/resources.xml
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/main.glade
|
${CMAKE_CURRENT_SOURCE_DIR}/main.glade
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/dialog.glade
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/layer-widget.glade
|
${CMAKE_CURRENT_SOURCE_DIR}/layer-widget.glade
|
||||||
OUTPUT
|
OUTPUT
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
||||||
|
62
glade/dialog.glade
Normal file
62
glade/dialog.glade
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.22.1 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.20"/>
|
||||||
|
<object class="GtkAdjustment" id="adjustment1">
|
||||||
|
<property name="lower">1</property>
|
||||||
|
<property name="upper">2000</property>
|
||||||
|
<property name="value">1000</property>
|
||||||
|
<property name="step_increment">10</property>
|
||||||
|
<property name="page_increment">1000</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkBox" id="dialog-box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRadioButton" id="latex-radio">
|
||||||
|
<property name="label" translatable="yes">Generate LaTeX/TikZ output</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="active">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkRadioButton" id="cairo-radio">
|
||||||
|
<property name="label" translatable="yes">Render PDF using Cairographics</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">False</property>
|
||||||
|
<property name="active">True</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<property name="group">latex-radio</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScale" id="dialog-scale">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="adjustment">adjustment1</property>
|
||||||
|
<property name="round_digits">0</property>
|
||||||
|
<property name="digits">0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
@@ -3,6 +3,7 @@
|
|||||||
<gresource prefix="/">
|
<gresource prefix="/">
|
||||||
<file compressed="true">main.glade</file>
|
<file compressed="true">main.glade</file>
|
||||||
<file>layer-widget.glade</file>
|
<file>layer-widget.glade</file>
|
||||||
|
<file>dialog.glade</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|
||||||
|
@@ -157,6 +157,11 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
/* Draw polygons of childs */
|
/* Draw polygons of childs */
|
||||||
for (list_child = cell->child_cells; list_child != NULL; list_child = list_child->next) {
|
for (list_child = cell->child_cells; list_child != NULL; list_child = list_child->next) {
|
||||||
inst = (struct gds_cell_instance *)list_child->data;
|
inst = (struct gds_cell_instance *)list_child->data;
|
||||||
|
|
||||||
|
/* Abort if cell has no reference */
|
||||||
|
if (!inst->cell_ref)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* generate translation scope */
|
/* generate translation scope */
|
||||||
g_string_printf(buffer, "\\begin{scope}[shift={(%lf pt,%lf pt)}]\n",
|
g_string_printf(buffer, "\\begin{scope}[shift={(%lf pt,%lf pt)}]\n",
|
||||||
((double)inst->origin.x)/1000.0,((double)inst->origin.y)/1000.0);
|
((double)inst->origin.x)/1000.0,((double)inst->origin.y)/1000.0);
|
||||||
@@ -165,10 +170,10 @@ 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);
|
||||||
|
|
||||||
if (inst->cell_ref)
|
|
||||||
render_cell(inst->cell_ref, layer_infos, tex_file, buffer);
|
render_cell(inst->cell_ref, layer_infos, tex_file, buffer);
|
||||||
|
|
||||||
g_string_printf(buffer, "\\end{scope}\n");
|
g_string_printf(buffer, "\\end{scope}\n");
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "layer-selector.h"
|
#include "layer-selector.h"
|
||||||
#include "gds-parser/gds-parser.h"
|
#include "gds-parser/gds-parser.h"
|
||||||
#include "layer-widget/layer-element.h"
|
#include "widgets/layer-element.h"
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
7
main.c
7
main.c
@@ -20,10 +20,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "gds-parser/gds-parser.h"
|
#include "gds-parser/gds-parser.h"
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include "layer-widget/layer-element.h"
|
|
||||||
#include "layer-selector.h"
|
#include "layer-selector.h"
|
||||||
#include "tree-renderer/tree-store.h"
|
#include "tree-renderer/tree-store.h"
|
||||||
#include "latex-output/latex-output.h"
|
#include "latex-output/latex-output.h"
|
||||||
|
#include "widgets/conv-settings-dialog.h"
|
||||||
|
|
||||||
struct open_button_data {
|
struct open_button_data {
|
||||||
GtkWindow *main_window;
|
GtkWindow *main_window;
|
||||||
@@ -169,9 +169,14 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
|||||||
struct gds_cell *cell_to_render;
|
struct gds_cell *cell_to_render;
|
||||||
FILE *tex_file;
|
FILE *tex_file;
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
|
RendererSettingsDialog *settings;
|
||||||
gint res;
|
gint res;
|
||||||
char *file_name;
|
char *file_name;
|
||||||
|
|
||||||
|
settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window));
|
||||||
|
gtk_dialog_run(GTK_DIALOG(settings));
|
||||||
|
gtk_widget_destroy(GTK_WIDGET(settings));
|
||||||
|
|
||||||
/* Get selected cell */
|
/* Get selected cell */
|
||||||
selection = gtk_tree_view_get_selection(data->tree_view);
|
selection = gtk_tree_view_get_selection(data->tree_view);
|
||||||
if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
|
if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
|
||||||
|
75
widgets/conv-settings-dialog.c
Normal file
75
widgets/conv-settings-dialog.c
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*
|
||||||
|
* This file is part of GDSII-Converter.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "conv-settings-dialog.h"
|
||||||
|
|
||||||
|
struct _RendererSettingsDialog {
|
||||||
|
GtkDialog parent;
|
||||||
|
/* Private loot */
|
||||||
|
GtkWidget *radio_latex; // Only Latex-radio. Other one is implicit
|
||||||
|
GtkWidget *scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE(RendererSettingsDialog, renderer_settings_dialog, GTK_TYPE_DIALOG)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void renderer_settings_dialog_class_init(RendererSettingsDialogClass *klass)
|
||||||
|
{
|
||||||
|
/* No special code needed. Child cells are destroyed automatically due to reference counter */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void renderer_settings_dialog_init(RendererSettingsDialog *self)
|
||||||
|
{
|
||||||
|
GtkBuilder *builder;
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkDialog *dialog;
|
||||||
|
|
||||||
|
|
||||||
|
dialog = &(self->parent);
|
||||||
|
|
||||||
|
builder = gtk_builder_new_from_resource("/dialog.glade");
|
||||||
|
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
|
||||||
|
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio"));
|
||||||
|
self->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale"));
|
||||||
|
gtk_dialog_add_buttons(dialog, "Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL);
|
||||||
|
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dialog)), box);
|
||||||
|
g_object_unref(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
|
||||||
|
{
|
||||||
|
RendererSettingsDialog *res;
|
||||||
|
|
||||||
|
res = RENDERER_SETTINGS_DIALOG(g_object_new(RENDERER_TYPE_SETTINGS_DIALOG, NULL));
|
||||||
|
if (res && parent) {
|
||||||
|
gtk_window_set_transient_for(GTK_WINDOW(res), parent);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
|
||||||
|
{
|
||||||
|
if (!settings)
|
||||||
|
return;
|
||||||
|
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
|
||||||
|
settings->renderer = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE ? RENDERER_LATEX_TIKZ : RENDERER_CAIROGRAPHICS);
|
||||||
|
}
|
||||||
|
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
|
46
widgets/conv-settings-dialog.h
Normal file
46
widgets/conv-settings-dialog.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*
|
||||||
|
* This file is part of GDSII-Converter.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CONV_SETTINGS_DIALOG_H__
|
||||||
|
#define __CONV_SETTINGS_DIALOG_H__
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
enum output_renderer {RENDERER_LATEX_TIKZ, RENDERER_CAIROGRAPHICS};
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE(RendererSettingsDialog, renderer_settings_dialog, RENDERER, SETTINGS_DIALOG, GtkDialog)
|
||||||
|
|
||||||
|
RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent);
|
||||||
|
|
||||||
|
#define RENDERER_TYPE_SETTINGS_DIALOG (renderer_settings_dialog_get_type())
|
||||||
|
|
||||||
|
struct render_settings {
|
||||||
|
double scale;
|
||||||
|
enum output_renderer renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
|
||||||
|
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
|
||||||
|
|
||||||
|
#endif /* __CONV_SETTINGS_DIALOG_H__ */
|
@@ -38,12 +38,12 @@ typedef struct _LayerElementPriv {
|
|||||||
GtkCheckButton *export;
|
GtkCheckButton *export;
|
||||||
} LayerElementPriv;
|
} LayerElementPriv;
|
||||||
|
|
||||||
typedef struct _LayerElement {
|
struct _LayerElement {
|
||||||
/* Inheritance */
|
/* Inheritance */
|
||||||
GtkListBoxRow parent;
|
GtkListBoxRow parent;
|
||||||
/* Custom Elements */
|
/* Custom Elements */
|
||||||
LayerElementPriv priv;
|
LayerElementPriv priv;
|
||||||
} LayerElement;
|
};
|
||||||
|
|
||||||
GtkWidget *layer_element_new(void);
|
GtkWidget *layer_element_new(void);
|
||||||
|
|
Reference in New Issue
Block a user