better data struct for embedded image
This commit is contained in:
parent
c8038ffdb8
commit
c3af523559
|
|
@ -570,6 +570,49 @@ void remove_symbols(void)
|
|||
dbg(1, "remove_symbols(): done\n");
|
||||
}
|
||||
|
||||
/* what:
|
||||
* 2: copy: drptr->extraptr <- srptr->extraptr
|
||||
* 1: create
|
||||
* 0: clear
|
||||
*/
|
||||
int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr)
|
||||
{
|
||||
if(what==2) { /* copy */
|
||||
if(drptr->flags & 1024) { /* embedded image */
|
||||
xEmb_image *d, *s;
|
||||
s = srptr->extraptr;
|
||||
if(s) {
|
||||
d = my_malloc(1478, sizeof(xEmb_image));
|
||||
d->data = my_malloc(1479, s->data_size);
|
||||
memcpy(d->data, s->data, s->data_size);
|
||||
d->data_size = s->data_size;
|
||||
drptr->extraptr = d;
|
||||
} else {
|
||||
drptr->extraptr = NULL;
|
||||
}
|
||||
}
|
||||
} else if(what==1) { /* create */
|
||||
if(drptr->flags & 1024) { /* embedded image */
|
||||
if(!drptr->extraptr) {
|
||||
xEmb_image *d;
|
||||
d = my_malloc(1465, sizeof(xEmb_image));
|
||||
d->data = NULL;
|
||||
d->data_size = 0;
|
||||
drptr->extraptr = d;
|
||||
}
|
||||
}
|
||||
} else { /* clear */
|
||||
if(drptr->flags & 1024) { /* embedded image */
|
||||
if(drptr->extraptr) {
|
||||
xEmb_image *d = drptr->extraptr;
|
||||
if(d->data) my_free(1475, &d->data);
|
||||
my_free(1476, &drptr->extraptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear_drawing(void)
|
||||
{
|
||||
int i,j;
|
||||
|
|
@ -612,10 +655,7 @@ void clear_drawing(void)
|
|||
for(j=0;j<xctx->rects[i];j++)
|
||||
{
|
||||
my_free(700, &xctx->rect[i][j].prop_ptr);
|
||||
if(xctx->rect[i][j].data) {
|
||||
my_free(1467, &xctx->rect[i][j].data);
|
||||
xctx->rect[i][j].data_size = 0;
|
||||
}
|
||||
setup_rect_extraptr(0, &xctx->rect[i][j], NULL);
|
||||
}
|
||||
for(j=0;j<xctx->arcs[i];j++)
|
||||
{
|
||||
|
|
|
|||
58
src/draw.c
58
src/draw.c
|
|
@ -2589,7 +2589,6 @@ static cairo_status_t png_writer(void *in_closure, const unsigned char *in_data,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int draw_images_all(void)
|
||||
{
|
||||
#if HAS_CAIRO==1
|
||||
|
|
@ -2598,15 +2597,6 @@ int draw_images_all(void)
|
|||
int save_bbx1, save_bby1, save_bbx2, save_bby2;
|
||||
cairo_surface_t *image;
|
||||
|
||||
if(xctx->sem) {
|
||||
bbox_set = 1;
|
||||
save_bbx1 = xctx->bbx1;
|
||||
save_bby1 = xctx->bby1;
|
||||
save_bbx2 = xctx->bbx2;
|
||||
save_bby2 = xctx->bby2;
|
||||
bbox(END, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(xctx->draw_single_layer==-1 || GRIDLAYER == xctx->draw_single_layer) {
|
||||
if(xctx->enable_layer[GRIDLAYER]) for(i = 0; i < xctx->rects[GRIDLAYER]; i++) {
|
||||
xRect *r = &xctx->rect[GRIDLAYER][i];
|
||||
|
|
@ -2616,23 +2606,37 @@ int draw_images_all(void)
|
|||
const char *filename;
|
||||
double scalex, scaley;
|
||||
png_to_byte_closure_t closure;
|
||||
xEmb_image *emb_ptr;
|
||||
|
||||
if(xctx->sem) {
|
||||
bbox_set = 1;
|
||||
save_bbx1 = xctx->bbx1;
|
||||
save_bby1 = xctx->bby1;
|
||||
save_bbx2 = xctx->bbx2;
|
||||
save_bby2 = xctx->bby2;
|
||||
bbox(END, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if(!r->extraptr) {
|
||||
setup_rect_extraptr(1, r, NULL);
|
||||
}
|
||||
emb_ptr = r->extraptr;
|
||||
cairo_save(xctx->cairo_ctx);
|
||||
cairo_save(xctx->cairo_save_ctx);
|
||||
|
||||
/* read PNG from in-memory buffer ... */
|
||||
if(r->data && r->data_size) {
|
||||
closure.buffer = r->data;
|
||||
if(emb_ptr && emb_ptr->data && emb_ptr->data_size) {
|
||||
closure.buffer = emb_ptr->data;
|
||||
closure.pos = 0;
|
||||
closure.size = r->data_size; /* should not be necessary */
|
||||
closure.size = emb_ptr->data_size; /* should not be necessary */
|
||||
image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
|
||||
dbg(1, "draw_images_all(): length1 = %d\n", closure.pos);
|
||||
/* ... or read PNG from image_data attribute */
|
||||
} else if( (attr = get_tok_value(r->prop_ptr, "image_data", 0))[0] ) {
|
||||
r->data = base64_decode(attr, strlen(attr), &r->data_size);
|
||||
closure.buffer = r->data;
|
||||
emb_ptr->data = base64_decode(attr, strlen(attr), &emb_ptr->data_size);
|
||||
closure.buffer = emb_ptr->data;
|
||||
closure.pos = 0;
|
||||
closure.size = r->data_size; /* should not be necessary */
|
||||
closure.size = emb_ptr->data_size; /* should not be necessary */
|
||||
image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
|
||||
dbg(1, "draw_images_all(): length2 = %d\n", closure.pos);
|
||||
/* ... or read PNG from file (image attribute) */
|
||||
|
|
@ -2647,10 +2651,10 @@ int draw_images_all(void)
|
|||
closure.pos = 0;
|
||||
cairo_surface_write_to_png_stream(image, png_writer, &closure);
|
||||
dbg(1, "draw_images_all(): length3 = %d\n", closure.pos);
|
||||
r->data = closure.buffer;
|
||||
r->data_size = closure.pos;
|
||||
emb_ptr->data = closure.buffer;
|
||||
emb_ptr->data_size = closure.pos;
|
||||
/* put base64 encoded data to rect image_data attrinute */
|
||||
image_data = base64_encode(r->data, r->data_size, &olength);
|
||||
image_data = base64_encode(emb_ptr->data, emb_ptr->data_size, &olength);
|
||||
my_realloc(1466, &image_data, olength + 1);
|
||||
image_data[olength] = '\0';
|
||||
my_strdup2(1473, &r->prop_ptr, subst_token(r->prop_ptr, "image_data", image_data));
|
||||
|
|
@ -2676,17 +2680,17 @@ int draw_images_all(void)
|
|||
cairo_surface_destroy(image);
|
||||
cairo_restore(xctx->cairo_ctx);
|
||||
cairo_restore(xctx->cairo_save_ctx);
|
||||
if(bbox_set) {
|
||||
xctx->bbx1 = save_bbx1;
|
||||
xctx->bby1 = save_bby1;
|
||||
xctx->bbx2 = save_bbx2;
|
||||
xctx->bby2 = save_bby2;
|
||||
xctx->sem = 1;
|
||||
bbox(SET, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bbox_set) {
|
||||
xctx->bbx1 = save_bbx1;
|
||||
xctx->bby1 = save_bby1;
|
||||
xctx->bbx2 = save_bbx2;
|
||||
xctx->bby2 = save_bby2;
|
||||
xctx->sem = 1;
|
||||
bbox(SET, 0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,9 +434,8 @@ static void edit_rect_property(int x)
|
|||
(char *) tclgetvar("retval"));
|
||||
}
|
||||
|
||||
if(xctx->rect[c][n].data) { /* used for images, clear so will be recreated from image attr */
|
||||
my_free(1465, &xctx->rect[c][n].data);
|
||||
xctx->rect[c][n].data_size = 0;
|
||||
if(xctx->rect[c][n].extraptr) { /* used for images, clear so will be recreated from image attr */
|
||||
setup_rect_extraptr(0, &xctx->rect[c][n], NULL);
|
||||
}
|
||||
flags = get_tok_value(xctx->rect[c][n].prop_ptr,"flags",0);
|
||||
if( strcmp(flags, "") ) {
|
||||
|
|
|
|||
|
|
@ -307,10 +307,8 @@ void mem_push_undo(void)
|
|||
xctx->uslot[slot].bptr[c][i] = xctx->rect[c][i];
|
||||
xctx->uslot[slot].bptr[c][i].prop_ptr = NULL;
|
||||
my_strdup(185, &xctx->uslot[slot].bptr[c][i].prop_ptr, xctx->rect[c][i].prop_ptr);
|
||||
if(xctx->rect[c][i].data && xctx->rect[c][i].data_size) {
|
||||
xctx->uslot[slot].bptr[c][i].data_size = xctx->rect[c][i].data_size;
|
||||
xctx->uslot[slot].bptr[c][i].data = my_malloc(1469, xctx->rect[c][i].data_size);
|
||||
memcpy(xctx->uslot[slot].bptr[c][i].data, xctx->rect[c][i].data, xctx->rect[c][i].data_size);
|
||||
if(xctx->rect[c][i].extraptr) {
|
||||
setup_rect_extraptr(2, &xctx->uslot[slot].bptr[c][i], &xctx->rect[c][i]);
|
||||
}
|
||||
}
|
||||
/* arcs */
|
||||
|
|
@ -534,10 +532,8 @@ void mem_pop_undo(int redo, int set_modify_status)
|
|||
xctx->rect[c][i] = xctx->uslot[slot].bptr[c][i];
|
||||
xctx->rect[c][i].prop_ptr = NULL;
|
||||
my_strdup(205, &xctx->rect[c][i].prop_ptr, xctx->uslot[slot].bptr[c][i].prop_ptr);
|
||||
if(xctx->uslot[slot].bptr[c][i].data && xctx->uslot[slot].bptr[c][i].data_size) {
|
||||
xctx->rect[c][i].data_size = xctx->uslot[slot].bptr[c][i].data_size;
|
||||
xctx->rect[c][i].data = my_malloc(1468, xctx->uslot[slot].bptr[c][i].data_size);
|
||||
memcpy(xctx->rect[c][i].data, xctx->uslot[slot].bptr[c][i].data, xctx->uslot[slot].bptr[c][i].data_size);
|
||||
if(xctx->uslot[slot].bptr[c][i].extraptr) {
|
||||
setup_rect_extraptr(2, &xctx->rect[c][i], &xctx->uslot[slot].bptr[c][i]);
|
||||
}
|
||||
}
|
||||
/* arcs */
|
||||
|
|
|
|||
13
src/move.c
13
src/move.c
|
|
@ -145,10 +145,7 @@ void check_collapsing_objects()
|
|||
if(xctx->rect[c][i].x1==xctx->rect[c][i].x2 || xctx->rect[c][i].y1 == xctx->rect[c][i].y2)
|
||||
{
|
||||
my_free(815, &xctx->rect[c][i].prop_ptr);
|
||||
if(xctx->rect[c][i].data) {
|
||||
my_free(1471, &xctx->rect[c][i].data);
|
||||
xctx->rect[c][i].data_size = 0;
|
||||
}
|
||||
setup_rect_extraptr(0, &xctx->rect[c][i], NULL);
|
||||
found=1;
|
||||
j++;
|
||||
continue;
|
||||
|
|
@ -876,10 +873,8 @@ void copy_objects(int what)
|
|||
storeobject(-1, xctx->rx1+xctx->deltax, xctx->ry1+xctx->deltay,
|
||||
xctx->rx2+xctx->deltax, xctx->ry2+xctx->deltay,xRECT, c, SELECTED, xctx->rect[c][n].prop_ptr);
|
||||
l = xctx->rects[c] - 1;
|
||||
if(xctx->rect[c][n].data && xctx->rect[c][n].data_size) {
|
||||
xctx->rect[c][l].data_size = xctx->rect[c][n].data_size;
|
||||
xctx->rect[c][l].data = my_malloc(1470, xctx->rect[c][n].data_size);
|
||||
memcpy(xctx->rect[c][l].data, xctx->rect[c][n].data, xctx->rect[c][n].data_size);
|
||||
if(xctx->rect[c][n].extraptr) {
|
||||
setup_rect_extraptr(2, &xctx->rect[c][l], &xctx->rect[c][n]);
|
||||
}
|
||||
bbox(ADD, xctx->rect[c][l].x1, xctx->rect[c][l].y1, xctx->rect[c][l].x2, xctx->rect[c][l].y2);
|
||||
break;
|
||||
|
|
@ -1097,7 +1092,7 @@ void move_objects(int what, int merge, double dx, double dy)
|
|||
set_modify(1);
|
||||
/* no undo push for MERGE ad PLACE, already done before */
|
||||
if( !xctx->kissing && !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) {
|
||||
dbg(0, "move_objects(): push undo state\n");
|
||||
dbg(1, "move_objects(): push undo state\n");
|
||||
xctx->push_undo();
|
||||
}
|
||||
xctx->ui_state &= ~PLACE_SYMBOL;
|
||||
|
|
|
|||
|
|
@ -111,8 +111,7 @@ void merge_box(FILE *fd)
|
|||
return;
|
||||
}
|
||||
ptr[i].prop_ptr=NULL;
|
||||
ptr[i].data=NULL;
|
||||
ptr[i].data_size=0;
|
||||
ptr[i].extraptr=NULL;
|
||||
RECTORDER(ptr[i].x1, ptr[i].y1, ptr[i].x2, ptr[i].y2);
|
||||
ptr[i].sel=0;
|
||||
load_ascii_string( &ptr[i].prop_ptr, fd);
|
||||
|
|
|
|||
|
|
@ -779,8 +779,7 @@ static void load_box(FILE *fd)
|
|||
return;
|
||||
}
|
||||
RECTORDER(ptr[i].x1, ptr[i].y1, ptr[i].x2, ptr[i].y2);
|
||||
ptr[i].data=NULL;
|
||||
ptr[i].data_size=0;
|
||||
ptr[i].extraptr=NULL;
|
||||
ptr[i].prop_ptr=NULL;
|
||||
ptr[i].sel=0;
|
||||
load_ascii_string( &ptr[i].prop_ptr, fd);
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ static void del_rect_line_arc_poly(void)
|
|||
j++;
|
||||
bbox(ADD, xctx->rect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2);
|
||||
my_free(928, &xctx->rect[c][i].prop_ptr);
|
||||
setup_rect_extraptr(0, &xctx->rect[c][i], NULL);
|
||||
set_modify(1);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,8 +308,7 @@ void storeobject(int pos, double x1,double y1,double x2,double y2,
|
|||
xctx->rect[rectc][n].y1=y1;
|
||||
xctx->rect[rectc][n].y2=y2;
|
||||
xctx->rect[rectc][n].prop_ptr=NULL;
|
||||
xctx->rect[rectc][n].data=NULL;
|
||||
xctx->rect[rectc][n].data_size=0;
|
||||
xctx->rect[rectc][n].extraptr=NULL;
|
||||
my_strdup(413, &xctx->rect[rectc][n].prop_ptr, prop_ptr);
|
||||
xctx->rect[rectc][n].sel=sel;
|
||||
if(prop_ptr && (dash = get_tok_value(prop_ptr,"dash",0))[0]) {
|
||||
|
|
|
|||
10
src/xschem.h
10
src/xschem.h
|
|
@ -395,6 +395,12 @@ typedef struct
|
|||
short bus;
|
||||
} xLine;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *data;
|
||||
size_t data_size;
|
||||
} xEmb_image;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double x1;
|
||||
|
|
@ -403,8 +409,7 @@ typedef struct
|
|||
double y2;
|
||||
unsigned short sel;
|
||||
char *prop_ptr;
|
||||
void *data; /* generic data pointer (images) */
|
||||
size_t data_size; /* generic data pointer (images) */
|
||||
void *extraptr; /* generic data pointer (images) */
|
||||
short dash;
|
||||
/* bit0=1 for graph function, bit1=1 for unlocked x axis
|
||||
* bit10: image embedding (png)
|
||||
|
|
@ -994,6 +999,7 @@ extern int cli_opt_load_initfile;
|
|||
extern Xschem_ctx *xctx;
|
||||
|
||||
/* FUNCTIONS */
|
||||
extern int setup_rect_extraptr(int what, xRect *drptr, xRect *srptr);
|
||||
extern unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
|
||||
extern char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length);
|
||||
extern int get_raw_index(const char *node);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue