fix unintended move operation start when clicking a launcher that starts a new schematic and returning to the originating schematic containing the launcher. Added support for direct JPG image import (no JPG->PNG filters)

This commit is contained in:
stefan schippers 2024-03-14 11:09:49 +01:00
parent b1b2c3797b
commit 6c0398a8b6
8 changed files with 55 additions and 13 deletions

View File

@ -553,7 +553,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> add_graph</kbd></li><pre>
Start a GUI placement of a graph object </pre>
<li><kbd> add_png</kbd></li><pre>
Ask user to choose a png file and start a GUI placement of the image </pre>
Ask user to choose a png/jpg file and start a GUI placement of the image </pre>
<li><kbd> align</kbd></li><pre>
Align currently selected objects to current snap setting </pre>
<li><kbd> annotate_op [raw_file] [level]</kbd></li><pre>
@ -720,11 +720,13 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
Get C variable/constant 'var' </pre>
<ul>
<li><kbd> backlayer </kbd> number of background layer </li>
<li><kbd> bbox </kbd> bounding box schematic </li>
<li><kbd> bbox_hilighted </kbd> bounding box of highlinhted objects </li>
<li><kbd> bbox_selected </kbd> bounding box of selected objects </li>
<li><kbd> cadlayers </kbd> number of layers </li>
<li><kbd> case_insensitive </kbd> case_insensitive symbol matching </li>
<li><kbd> color_ps </kbd> color postscript flag </li>
<li><kbd> constr_mv </kbd> color postscript flag </li>
<li><kbd> current_dirname </kbd> directory name of current design </li>
<li><kbd> current_name </kbd> name of current design (no library path) </li>
<li><kbd> current_win_path </kbd> path of current tab/window (.drw, .x1.drw, ...) </li>
@ -1341,7 +1343,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
<li><kbd> cadgrid </kbd> set cad grid (default: 20) </li>
<li><kbd> cadsnap </kbd> set mouse snap (default: 10) </li>
<li><kbd> color_ps </kbd> set color psoscript (1 or 0) </li>
<li><kbd> constrained_move </kbd> set constrained move (1=horiz, 2=vert, 0=none) </li>
<li><kbd> constr_mv </kbd> set constrained move (1=horiz, 2=vert, 0=none) </li>
<li><kbd> cursor1_x </kbd> set graph cursor1 position </li>
<li><kbd> cursor2_x </kbd> set graph cursor2 position </li>
<li><kbd> draw_window </kbd> set drawing to window (1 or 0) </li>

View File

@ -933,7 +933,9 @@ int set_rect_extraptr(int what, xRect *drptr)
if(drptr->flags & 1024) { /* embedded image */
if(drptr->extraptr) {
xEmb_image *d = drptr->extraptr;
if(d->image) cairo_surface_destroy(d->image);
if(d->image) {
cairo_surface_destroy(d->image);
}
my_free(_ALLOC_ID_, &drptr->extraptr);
}
}

View File

@ -375,8 +375,10 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_mem(void *data, size_t len
(void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
/* Stefan: commented out since this assumes static lifetime of 'data' buffer
* that I don't assume. I consider this a bug */
/* set jpeg mime data */
cairo_surface_set_mime_data(sfc, CAIRO_MIME_TYPE_JPEG, data, len, free, data);
/* cairo_surface_set_mime_data(sfc, CAIRO_MIME_TYPE_JPEG, data, len, free, data);*/
return sfc;
}

View File

@ -3529,7 +3529,7 @@ int rstate; /* (reduced state, without ShiftMask) */
move_objects(START,0,0,0);
}
else if(state == ShiftMask) copy_objects(START);
else move_objects(START,0,0,0);
else if( !(state & ControlMask) ) move_objects(START,0,0,0);
}
#ifndef __unix__

View File

@ -3865,7 +3865,7 @@ cairo_status_t png_reader(void *in_closure, unsigned char *out_data, unsigned in
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t png_writer(void *in_closure, const unsigned char *in_data, unsigned int length)
cairo_status_t png_writer(void *in_closure, const unsigned char *in_data, unsigned int length)
{
png_to_byte_closure_t *closure = (png_to_byte_closure_t *) in_closure;
if(!in_data) return CAIRO_STATUS_WRITE_ERROR;
@ -3898,6 +3898,7 @@ void draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2
double xx1, yy1, scalex, scaley;
png_to_byte_closure_t closure;
xEmb_image *emb_ptr;
int jpg = 0; /* set to 1 if image_data attribute contains base64 encoded JPEG */
if(xctx->only_probes) return;
xx1 = *x1; yy1 = *y1; /* image anchor point */
@ -3934,11 +3935,24 @@ void draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2
filter_data(filterdata, filtersize, (char **)&closure.buffer, &data_size, filter);
my_free(_ALLOC_ID_, &filterdata);
} else {
if(!strncmp(attr, "/9j/4", 5)) jpg = 1;
else if(!strncmp(attr, "iVBOR", 5)) jpg = 0;
else jpg = -1; /* some invalid data */
closure.buffer = base64_decode(attr, strlen(attr), &data_size);
}
closure.pos = 0;
closure.size = data_size; /* should not be necessary */
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
if(jpg == 0) {
emb_ptr->image = cairo_image_surface_create_from_png_stream(png_reader, &closure);
} else {
emb_ptr->image = cairo_image_surface_create_from_jpeg_mem(closure.buffer, closure.size);
}
if(cairo_surface_status(emb_ptr->image) != CAIRO_STATUS_SUCCESS) {
my_free(_ALLOC_ID_, &filter);
my_free(_ALLOC_ID_, &closure.buffer);
return;
}
if(closure.buffer == NULL) dbg(0, "draw_image(): image creation failed\n");
my_free(_ALLOC_ID_, &closure.buffer);
dbg(1, "draw_image(): length2 = %d\n", closure.pos);
@ -3969,12 +3983,33 @@ void draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2
image_data = base64_encode((unsigned char *)filterdata, filtersize, &olength, 0);
my_free(_ALLOC_ID_, &filterdata);
} else {
FILE *fd;
size_t size = (size_t)buf.st_size >= 5 ? 5 : (size_t)buf.st_size;
char header[5];
header[0] = '\0';
fd = fopen(filename, "r");
if(fd) {
fread(header, size, 1, fd);
fclose(fd);
}
if(!strncmp(header, "\x89PNG", 4)) jpg = 0;
else if(!strncmp(header, "\xFF\xD8\xFF", 3)) jpg = 1;
else jpg = -1;
closure.buffer = NULL;
closure.size = 0;
closure.pos = 0;
emb_ptr->image = cairo_image_surface_create_from_png(filename);
/* write PNG to in-memory buffer */
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
if(jpg == 0) {
emb_ptr->image = cairo_image_surface_create_from_png(filename);
/* write PNG to in-memory buffer */
cairo_surface_write_to_png_stream(emb_ptr->image, png_writer, &closure);
} else {
emb_ptr->image = cairo_image_surface_create_from_jpeg(filename);
/* write JPG to in-memory buffer */
cairo_image_surface_write_to_jpeg_mem(emb_ptr->image, &closure.buffer, &closure.pos, 75);
}
image_data = base64_encode(closure.buffer, closure.pos, &olength, 0);
my_free(_ALLOC_ID_, &closure.buffer);
}

View File

@ -220,13 +220,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
/* add_png
* Ask user to choose a png file and start a GUI placement of the image */
* Ask user to choose a png/jpg file and start a GUI placement of the image */
else if(!strcmp(argv[1], "add_png"))
{
char str[PATH_MAX+100];
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
unselect_all(1);
tcleval("tk_getOpenFile -filetypes { {{Png} {.png}} {{All files} *} }");
tcleval("tk_getOpenFile -filetypes {{{Png} {.png}} {{Jpg} {.jpg .jpeg}} {{All files} *} }");
if(tclresult()[0]) {
my_snprintf(str, S(str), "flags=image,unscaled\nalpha=0.8\nimage=%s\n", tclresult());
storeobject(-1, xctx->mousex_snap-100, xctx->mousey_snap-100, xctx->mousex_snap+100, xctx->mousey_snap+100,

View File

@ -1349,6 +1349,7 @@ extern void hash_objects(void); /* hash all objects */
#if HAS_CAIRO==1
extern cairo_status_t png_reader(void* in_closure, unsigned char* out_data, unsigned int length);
extern cairo_status_t png_writer(void *in_closure, const unsigned char *in_data, unsigned int length);
extern int text_bbox_nocairo(const char * str,double xscale, double yscale,
short rot, short flip, int hcenter, int vcenter,
double x1,double y1, double *rx1, double *ry1,

View File

@ -7735,7 +7735,7 @@ proc build_widgets { {topwin {} } } {
toolbar_add ToolInsertArc "xschem arc" "Insert Arc" $topwin
$topwin.menubar.tools.menu add command -label "Insert circle" -command "xschem circle" -accelerator Ctrl+Shift+C
toolbar_add ToolInsertCircle "xschem circle" "Insert Circle" $topwin
$topwin.menubar.tools.menu add command -label "Insert PNG image" -command "xschem add_png"
$topwin.menubar.tools.menu add command -label "Insert JPG/PNG image" -command "xschem add_png"
$topwin.menubar.tools.menu add command -label "Search" -accelerator Ctrl+F -command property_search
toolbar_add ToolSearch property_search "Search" $topwin
$topwin.menubar.tools.menu add command -label "Align to Grid" -accelerator Alt+U -command "xschem align"