put cairo save surface and context into xctx, faster and smoother preview (avoid unload/load if no filename change)

This commit is contained in:
Stefan Frederik 2020-12-03 18:21:23 +01:00
parent 66a73e4e99
commit 3732bd8d01
12 changed files with 237 additions and 224 deletions

View File

@ -198,42 +198,46 @@ const char *add_ext(const char *f, const char *ext)
static void reset_cairo(int create, int clear)
{
#ifdef HAS_CAIRO
/* save_sfc is based on pixmap and pixmaps are not resizeable, so on resize
* we must destroy & recreate everything. sfc can be resized using cairo_*_surface_set_size
* being based on window */
cairo_destroy(cairo_save_ctx);
cairo_surface_destroy(save_sfc);
#if HAS_XRENDER==1
#if HAS_XCB==1
save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap,
&format_rgb, xctx->xschem_w, xctx->xschem_h);
#else
save_sfc = cairo_xlib_surface_create_with_xrender_format(display, xctx->save_pixmap,
DefaultScreenOfDisplay(display), format, xctx->xschem_w, xctx->xschem_h);
#endif /* HAS_XCB */
#else
save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xschem_w, xctx->xschem_h);
#endif /* HAS_XRENDER */
if(cairo_surface_status(save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo xcb surface\n");
exit(-1);
if(clear) {
/* xctx->save_sfc is based on pixmap and pixmaps are not resizeable, so on resize
* we must destroy & recreate everything. sfc can be resized using cairo_*_surface_set_size
* being based on window */
cairo_destroy(xctx->cairo_save_ctx);
cairo_surface_destroy(xctx->save_sfc);
}
if(create) {
#if HAS_XRENDER==1
#if HAS_XCB==1
xctx->save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap,
&format_rgb, xctx->xschem_w, xctx->xschem_h);
#else
xctx->save_sfc = cairo_xlib_surface_create_with_xrender_format(display, xctx->save_pixmap,
DefaultScreenOfDisplay(display), format, xctx->xschem_w, xctx->xschem_h);
#endif /* HAS_XCB */
#else
xctx->save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xschem_w, xctx->xschem_h);
#endif /* HAS_XRENDER */
if(cairo_surface_status(xctx->save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo xcb surface\n");
exit(-1);
}
xctx->cairo_save_ctx = cairo_create(xctx->save_sfc);
cairo_set_line_width(xctx->cairo_save_ctx, 1);
cairo_set_line_join(xctx->cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(xctx->cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (xctx->cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (xctx->cairo_save_ctx, 20);
}
cairo_save_ctx = cairo_create(save_sfc);
cairo_set_line_width(cairo_save_ctx, 1);
cairo_set_line_join(cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cairo_save_ctx, 20);
/* 20171125 select xlib or xcb :-) */
#if HAS_XCB==1 && HAS_XRENDER==1
cairo_xcb_surface_set_size(sfc, xctx->xschem_w, xctx->xschem_h);
#else
cairo_xlib_surface_set_size(sfc, xctx->xschem_w, xctx->xschem_h);
#endif /* HAS_XCB */
#endif /* HAS_XCB && HAS_XRENDER */
#endif /* HAS_CAIRO */
}
void resetwin(int create_pixmap, int clear_pixmap, int preview_window)
void resetwin(int create_pixmap, int clear_pixmap, int force)
{
int i;
XWindowAttributes wattr;
@ -255,9 +259,8 @@ void resetwin(int create_pixmap, int clear_pixmap, int preview_window)
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2-xctx->areay1;
/* if no preview_window or create_pixmap==1 avoid unnecessary work if no resize */
/* !create_pixmap ensures the XSetTile is executed when done with the preview */
if( preview_window || xctx->xschem_w !=xctx->xrect[0].width || xctx->xschem_h !=xctx->xrect[0].height) {
/* if no force avoid unnecessary work if no resize */
if( force || xctx->xschem_w !=xctx->xrect[0].width || xctx->xschem_h !=xctx->xrect[0].height) {
dbg(1, "resetwin(): x=%d y=%d xctx->xschem_w=%d xctx->xschem_h=%d\n",
wattr.x, wattr.y, xctx->xschem_w,xctx->xschem_h);
dbg(1, "resetwin(): changing size\n\n");
@ -278,11 +281,11 @@ void resetwin(int create_pixmap, int clear_pixmap, int preview_window)
xctx->save_pixmap = XCreatePixmap(display, xctx->window, xctx->xschem_w, xctx->xschem_h, depth);
}
XSetTile(display,gctiled, xctx->save_pixmap);
reset_cairo(create_pixmap, clear_pixmap);
}
reset_cairo(create_pixmap, clear_pixmap);
#else
HWND hwnd;
if (preview_window) {
if (force) {
hwnd = Tk_GetHWND(pre_window);
}
else {
@ -302,9 +305,8 @@ void resetwin(int create_pixmap, int clear_pixmap, int preview_window)
xctx->areay1 = -2 * INT_WIDTH(xctx->lw);
xctx->areaw = xctx->areax2 - xctx->areax1;
xctx->areah = xctx->areay2 - xctx->areay1;
/* if no preview_window or create_pixmap==1 avoid unnecessary work if no resize */
/* !create_pixmap ensures the XSetTile is executed when done with the preview */
if( preview_window || xctx->xschem_w !=xctx->xrect[0].width ||
/* if no force avoid unnecessary work if no resize */
if( force || xctx->xschem_w !=xctx->xrect[0].width ||
xctx->xschem_h !=xctx->xrect[0].height) {
dbg(1, "resetwin(): x=%d y=%d xctx->xschem_w=%d xctx->xschem_h=%d\n",
rct.right, rct.bottom, xctx->xschem_w, xctx->xschem_h);
@ -2358,9 +2360,9 @@ void place_text(int draw_text, double mx, double my)
if(t->flags & TEXT_ITALIC) slant = CAIRO_FONT_SLANT_ITALIC;
if(t->flags & TEXT_OBLIQUE) slant = CAIRO_FONT_SLANT_OBLIQUE;
cairo_save(cairo_ctx);
cairo_save(cairo_save_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face (cairo_ctx, textfont, slant, weight);
cairo_select_font_face (cairo_save_ctx, textfont, slant, weight);
cairo_select_font_face (xctx->cairo_save_ctx, textfont, slant, weight);
}
#endif
save_draw=draw_window;
@ -2372,7 +2374,7 @@ void place_text(int draw_text, double mx, double my)
#ifdef HAS_CAIRO
if((textfont && textfont[0]) || t->flags) {
cairo_restore(cairo_ctx);
cairo_restore(cairo_save_ctx);
cairo_restore(xctx->cairo_save_ctx);
}
#endif
select_text(xctx->texts, SELECTED, 0);

View File

@ -108,30 +108,30 @@ void print_image()
XSetTile(display, gctiled, xctx->save_pixmap);
#ifdef HAS_CAIRO
cairo_destroy(cairo_save_ctx);
cairo_surface_destroy(save_sfc);
cairo_destroy(xctx->cairo_save_ctx);
cairo_surface_destroy(xctx->save_sfc);
#if HAS_XRENDER==1
#if HAS_XCB==1
save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, &format_rgb, w, h);
xctx->save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, &format_rgb, w, h);
#else
save_sfc = cairo_xlib_surface_create_with_xrender_format(display,
xctx->save_sfc = cairo_xlib_surface_create_with_xrender_format(display,
xctx->save_pixmap, DefaultScreenOfDisplay(display), format, w, h);
#endif /*HAS_XCB */
#else
save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, w, h);
xctx->save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, w, h);
#endif /*HAS_XRENDER */
if(cairo_surface_status(save_sfc)!=CAIRO_STATUS_SUCCESS) {
if(cairo_surface_status(xctx->save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo xcb surface\n");
exit(-1);
}
cairo_save_ctx = cairo_create(save_sfc);
cairo_set_line_width(cairo_save_ctx, 1);
cairo_set_line_join(cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (cairo_save_ctx, cairo_font_name,
xctx->cairo_save_ctx = cairo_create(xctx->save_sfc);
cairo_set_line_width(xctx->cairo_save_ctx, 1);
cairo_set_line_join(xctx->cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(xctx->cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (xctx->cairo_save_ctx, cairo_font_name,
CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cairo_save_ctx, 20);
cairo_set_font_size (xctx->cairo_save_ctx, 20);
#endif /*HAS_CAIRO */
for(tmp=0;tmp<cadlayers;tmp++)
{
@ -184,29 +184,29 @@ void print_image()
#ifdef HAS_CAIRO
cairo_destroy(cairo_save_ctx);
cairo_surface_destroy(save_sfc);
cairo_destroy(xctx->cairo_save_ctx);
cairo_surface_destroy(xctx->save_sfc);
#if HAS_XRENDER==1
#if HAS_XCB==1
save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, &format_rgb, w, h);
xctx->save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn, screen_xcb, xctx->save_pixmap, &format_rgb, w, h);
#else
save_sfc = cairo_xlib_surface_create_with_xrender_format (display,
xctx->save_sfc = cairo_xlib_surface_create_with_xrender_format (display,
xctx->save_pixmap, DefaultScreenOfDisplay(display), format, w, h);
#endif /*HAS_XCB */
#else
save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, w, h);
xctx->save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, w, h);
#endif /*HAS_XRENDER */
if(cairo_surface_status(save_sfc)!=CAIRO_STATUS_SUCCESS) {
if(cairo_surface_status(xctx->save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo xcb surface\n");
exit(-1);
}
cairo_save_ctx = cairo_create(save_sfc);
cairo_set_line_width(cairo_save_ctx, 1);
cairo_set_line_join(cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cairo_save_ctx, 20);
xctx->cairo_save_ctx = cairo_create(xctx->save_sfc);
cairo_set_line_width(xctx->cairo_save_ctx, 1);
cairo_set_line_join(xctx->cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(xctx->cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_select_font_face (xctx->cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (xctx->cairo_save_ctx, 20);
#endif /*HAS_CAIRO */
for(tmp=0;tmp<cadlayers;tmp++)
@ -230,7 +230,7 @@ void set_cairo_color(int layer)
(double)xcolor_array[layer].red/65535.0,
(double)xcolor_array[layer].green/65535.0,
(double)xcolor_array[layer].blue/65535.0);
cairo_set_source_rgb(cairo_save_ctx,
cairo_set_source_rgb(xctx->cairo_save_ctx,
(double)xcolor_array[layer].red/65535.0,
(double)xcolor_array[layer].green/65535.0,
(double)xcolor_array[layer].blue/65535.0);
@ -265,7 +265,7 @@ int set_text_custom_font(xText *txt)
#ifdef HAS_CAIRO
static void cairo_draw_string_line(cairo_t *cairo_ctx, char *s,
static void cairo_draw_string_line(cairo_t *c_ctx, char *s,
double x, double y, int rot, int flip,
int lineno, double fontheight, double fontascent, double fontdescent, int llength)
{
@ -301,13 +301,13 @@ static void cairo_draw_string_line(cairo_t *cairo_ctx, char *s,
else if(rot==2 && flip==1) {iy=iy-fontheight-lines+line_delta+fontascent+vc;}
else if(rot==3 && flip==1) {iy=iy+line_offset;ix+=line_delta+fontascent-vc;}
cairo_save(cairo_ctx);
cairo_translate(cairo_ctx, ix, iy);
cairo_rotate(cairo_ctx, XSCH_PI/2*rot1);
cairo_save(c_ctx);
cairo_translate(c_ctx, ix, iy);
cairo_rotate(c_ctx, XSCH_PI/2*rot1);
cairo_move_to(cairo_ctx, 0,0);
cairo_show_text(cairo_ctx, s);
cairo_restore(cairo_ctx);
cairo_move_to(c_ctx, 0,0);
cairo_show_text(c_ctx, s);
cairo_restore(c_ctx);
}
/* CAIRO version */
@ -356,7 +356,7 @@ void draw_string(int layer, int what, const char *str, int rot, int flip, int hc
set_cairo_color(layer);
cairo_set_font_size (cairo_ctx, size*xctx->mooz);
cairo_set_font_size (cairo_save_ctx, size*xctx->mooz);
cairo_set_font_size (xctx->cairo_save_ctx, size*xctx->mooz);
cairo_font_extents(cairo_ctx, &fext);
dbg(1, "draw_string(): size * mooz=%g height=%g ascent=%g descent=%g\n",
size * xctx->mooz, fext.height, fext.ascent, fext.descent);
@ -370,7 +370,7 @@ void draw_string(int layer, int what, const char *str, int rot, int flip, int hc
/*fprintf(errfp, "cairo_draw_string(): tt=%s, longest line: %d\n", tt, cairo_longest_line); */
if(draw_window) cairo_draw_string_line(cairo_ctx, tt, x, y, rot, flip,
lineno, fext.height, fext.ascent, fext.descent, llength);
if(draw_pixmap) cairo_draw_string_line(cairo_save_ctx, tt, x, y, rot, flip,
if(draw_pixmap) cairo_draw_string_line(xctx->cairo_save_ctx, tt, x, y, rot, flip,
lineno, fext.height, fext.ascent, fext.descent, llength);
lineno++;
if(c==0) break;
@ -603,9 +603,9 @@ void draw_symbol(int what,int c, int n,int layer,int tmp_flip, int rot,
if(symptr->text[j].flags & TEXT_OBLIQUE) slant = CAIRO_FONT_SLANT_OBLIQUE;
cairo_save(cairo_ctx);
cairo_save(cairo_save_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face (cairo_ctx, textfont, slant, weight);
cairo_select_font_face (cairo_save_ctx, textfont, slant, weight);
cairo_select_font_face (xctx->cairo_save_ctx, textfont, slant, weight);
}
#endif
dbg(1, "drawing string: str=%s prop=%s\n", txtptr, text.prop_ptr);
@ -620,7 +620,7 @@ void draw_symbol(int what,int c, int n,int layer,int tmp_flip, int rot,
#ifdef HAS_CAIRO
if( (textfont && textfont[0]) || symptr->text[j].flags) {
cairo_restore(cairo_ctx);
cairo_restore(cairo_save_ctx);
cairo_restore(xctx->cairo_save_ctx);
}
#endif
}
@ -1736,9 +1736,9 @@ void draw(void)
if(xctx->text[i].flags & TEXT_OBLIQUE) slant = CAIRO_FONT_SLANT_OBLIQUE;
cairo_save(cairo_ctx);
cairo_save(cairo_save_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face (cairo_ctx, textfont, slant, weight);
cairo_select_font_face (cairo_save_ctx, textfont, slant, weight);
cairo_select_font_face (xctx->cairo_save_ctx, textfont, slant, weight);
}
#endif
@ -1749,7 +1749,7 @@ void draw(void)
#ifdef HAS_CAIRO
if((textfont && textfont[0]) || xctx->text[i].flags ) {
cairo_restore(cairo_ctx);
cairo_restore(cairo_save_ctx);
cairo_restore(xctx->cairo_save_ctx);
}
#endif
#ifndef HAS_CAIRO

View File

@ -103,9 +103,9 @@ XPoint *gridpoint; /* pointer to array of gridpoints, used in draw() */
XColor xcolor_array[256];
Visual *visual;
#ifdef HAS_CAIRO
cairo_surface_t *sfc, *save_sfc;
cairo_t *cairo_ctx, *cairo_save_ctx;
XRenderPictFormat *format;
cairo_surface_t *sfc;
cairo_t *cairo_ctx;
#if HAS_XCB==1
xcb_connection_t *xcbconn;
@ -200,7 +200,6 @@ int head_undo_ptr=0;
int max_undo=MAX_UNDO;
int draw_dots=1;
int draw_single_layer=-1;
int check_version = 0; /* if set ensures 'v' version header line is present before loading file */
int yyparse_error = 0;
int *enable_layer;
int n_active_layers=0;

View File

@ -849,9 +849,9 @@ void copy_objects(int what)
if(flags & TEXT_ITALIC) slant = CAIRO_FONT_SLANT_ITALIC;
if(flags & TEXT_OBLIQUE) slant = CAIRO_FONT_SLANT_OBLIQUE;
cairo_save(cairo_ctx);
cairo_save(cairo_save_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face (cairo_ctx, textfont, slant, weight);
cairo_select_font_face (cairo_save_ctx, textfont, slant, weight);
cairo_select_font_face (xctx->cairo_save_ctx, textfont, slant, weight);
}
#endif
draw_string(textlayer, ADD, xctx->text[xctx->texts].txt_ptr, /* draw moved txt */
@ -866,7 +866,7 @@ void copy_objects(int what)
#ifdef HAS_CAIRO
if( (textfont && textfont[0]) || xctx->text[xctx->texts].flags) {
cairo_restore(cairo_ctx);
cairo_restore(cairo_save_ctx);
cairo_restore(xctx->cairo_save_ctx);
}
#endif
xctx->sel_array[i].n=xctx->texts;
@ -1383,9 +1383,9 @@ void move_objects(int what, int merge, double dx, double dy)
if(xctx->text[n].flags & TEXT_ITALIC) slant = CAIRO_FONT_SLANT_ITALIC;
if(xctx->text[n].flags & TEXT_OBLIQUE) slant = CAIRO_FONT_SLANT_OBLIQUE;
cairo_save(cairo_ctx);
cairo_save(cairo_save_ctx);
cairo_save(xctx->cairo_save_ctx);
cairo_select_font_face (cairo_ctx, textfont, slant, weight);
cairo_select_font_face (cairo_save_ctx, textfont, slant, weight);
cairo_select_font_face (xctx->cairo_save_ctx, textfont, slant, weight);
}
#endif
draw_string(textlayer, ADD, xctx->text[n].txt_ptr, /* draw moved txt */
@ -1399,7 +1399,7 @@ void move_objects(int what, int merge, double dx, double dy)
#ifdef HAS_CAIRO
if( (textfont && textfont[0]) || xctx->text[n].flags) {
cairo_restore(cairo_ctx);
cairo_restore(cairo_save_ctx);
cairo_restore(xctx->cairo_save_ctx);
}
#endif
break;

View File

@ -1043,7 +1043,6 @@ int sym_vs_sch_pins()
char *pin_dir=NULL;
double tmpd;
FILE *fd;
int version_found;
int tmpi;
int endfile;
char tag[1];
@ -1061,7 +1060,6 @@ int sym_vs_sch_pins()
fd = fopen(filename, "r");
pin_cnt = 0;
endfile = 0;
version_found=0;
xctx->file_version[0] = '\0';
while(!endfile) {
if(fscanf(fd," %c",tag)==EOF) break;
@ -1070,7 +1068,6 @@ int sym_vs_sch_pins()
load_ascii_string(&xctx->version_string, fd);
my_snprintf(xctx->file_version, S(xctx->file_version), "%s",
get_tok_value(xctx->version_string, "file_version", 0));
version_found = 1;
break;
case 'E':
@ -1206,7 +1203,6 @@ int sym_vs_sch_pins()
break;
}
read_line(fd, 0); /* discard any remaining characters till (but not including) newline */
if(check_version && !version_found) break;
if(!xctx->file_version[0]) {
my_snprintf(xctx->file_version, S(xctx->file_version), "1.0");
dbg(1, "sym_vs_sch_pins(): no file_version, assuming file_version=%s\n", xctx->file_version);

View File

@ -738,7 +738,6 @@ void read_xschem_file(FILE *fd)
char name_embedded[PATH_MAX];
char tag[1];
int inst_cnt;
int version_found = 0;
int ty=0;
dbg(2, "read_xschem_file(): start\n");
@ -754,7 +753,6 @@ void read_xschem_file(FILE *fd)
if(xctx->version_string) {
my_snprintf(xctx->file_version, S(xctx->file_version), "%s",
get_tok_value(xctx->version_string, "file_version", 0));
version_found = 1;
}
dbg(1, "read_xschem_file(): file_version=%s\n", xctx->file_version);
break;
@ -846,7 +844,6 @@ void read_xschem_file(FILE *fd)
xctx->schvhdlprop = str;
}
}
if(check_version && !version_found) return;
if(!xctx->file_version[0]) {
my_snprintf(xctx->file_version, S(xctx->file_version), "1.0");
dbg(1, "read_xschem_file(): no file_version, assuming file_version=%s\n", xctx->file_version);

View File

@ -2096,7 +2096,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if( strlen(argv[3]) < sizeof(cairo_font_name) ) {
my_strncpy(cairo_font_name, argv[3], S(cairo_font_name));
cairo_select_font_face(cairo_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_select_font_face(cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_select_font_face(xctx->cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
}
} else
#endif

View File

@ -452,7 +452,7 @@ void bbox(int what,double x1,double y1, double x2, double y2)
}
#ifdef HAS_CAIRO
cairo_reset_clip(cairo_ctx);
cairo_reset_clip(cairo_save_ctx);
cairo_reset_clip(xctx->cairo_save_ctx);
#endif
sem=0;
break;
@ -482,8 +482,8 @@ void bbox(int what,double x1,double y1, double x2, double y2)
#ifdef HAS_CAIRO
cairo_rectangle(cairo_ctx, xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
cairo_clip(cairo_ctx);
cairo_rectangle(cairo_save_ctx, xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
cairo_clip(cairo_save_ctx);
cairo_rectangle(xctx->cairo_save_ctx, xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
cairo_clip(xctx->cairo_save_ctx);
#endif
break;
default:

View File

@ -562,10 +562,6 @@ void alloc_xschem_data()
if(xctx->sel_array==NULL){
fprintf(errfp, "Tcl_AppInit(): calloc error\n");tcleval( "exit");
}
pixmap=my_calloc(636, cadlayers, sizeof(Pixmap));
if(pixmap==NULL){
fprintf(errfp, "Tcl_AppInit(): calloc error\n");tcleval( "exit");
}
}
@ -619,6 +615,10 @@ void alloc_data()
}
}
enable_layer=my_calloc(87, cadlayers, sizeof(int));
pixmap=my_calloc(636, cadlayers, sizeof(Pixmap));
if(pixmap==NULL){
fprintf(errfp, "Tcl_AppInit(): calloc error\n");tcleval( "exit");
}
}
void xwin_exit(void)
@ -636,9 +636,9 @@ void xwin_exit(void)
if(has_x) {
#ifdef HAS_CAIRO
cairo_destroy(cairo_ctx);
cairo_destroy(cairo_save_ctx);
cairo_destroy(xctx->cairo_save_ctx);
cairo_surface_destroy(sfc);
cairo_surface_destroy(save_sfc);
cairo_surface_destroy(xctx->save_sfc);
#endif
dbg(1, "xwin_exit(): Releasing pixmaps\n");
for(i=0;i<cadlayers;i++)
@ -833,53 +833,67 @@ int source_tcl_file(char *s)
return TCL_OK;
}
void preview_clear(void)
{
dbg(1, "preview_clear()\n");
unselect_all();
remove_symbols();
clear_drawing();
resetwin(0, 1, 1); /* delete preview pixmap */
free_xschem_data();
}
void preview_window(const char *what, const char *tk_win_path, const char *filename)
{
static char *current_file = NULL;
static Xschem_ctx *save_xctx = NULL; /* save pointer to current schematic context structure */
static Xschem_ctx *preview_xctx = NULL; /* save pointer to current schematic context structure */
dbg(1, "------\n");
if(!strcmp(what, "create")) {
dbg(1, "preview_window() create, save ctx\n");
tkpre_window = Tk_NameToWindow(interp, tk_win_path, mainwindow);
Tk_MakeWindowExist(tkpre_window);
pre_window = Tk_WindowId(tkpre_window);
save_xctx = xctx; /* save current schematic */
}
else if(!strcmp(what, "draw")) {
Xschem_ctx *save_xctx = NULL; /* save pointer to current schematic context structure */
int save_show_pin;
save_xctx = xctx; /* save current schematic */
xctx = NULL; /* reset for preview */
alloc_xschem_data(); /* alloc data into xctx */
/* save some relevant global context */
save_show_pin = show_pin_net_names;
show_pin_net_names = 0;
/* preview */
check_version = 0; /* if set refuse to load and preview anything if not a rel 1.1+ xschem file */
/* if not set heuristics is done in xschem.tcl to ensure it is an xschem file */
load_schematic(1,filename, 0);
xctx->window = pre_window;
resetwin(1, 0, 1); /* create preview pixmap resetwin(create_pixmap, clear_pixmap, preview_window) */
dbg(1, "preview_window() draw\n");
xctx = preview_xctx;
if(!current_file || strcmp(filename, current_file) ) {
if(current_file) {
preview_clear();
}
my_strdup(117, &current_file, filename);
xctx = NULL; /* reset for preview */
alloc_xschem_data(); /* alloc data into xctx */
preview_xctx = xctx;
/* save some relevant global context */
/* preview */
dbg(1, "preview_window() draw, load schematic\n");
load_schematic(1,filename, 0);
preview_xctx->window = pre_window;
resetwin(1, 0, 1); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force) */
}
resetwin(1, 1, 0); /* handle resize. resetwin(create_pixmap, clear_pixmap, force) */
XSetTile(display,gctiled, xctx->save_pixmap);
zoom_full(1, 0); /* draw */
check_version = 0;
/* restore context */
unselect_all();
remove_symbols();
clear_drawing();
show_pin_net_names = save_show_pin;
resetwin(0, 1, 1); /* delete preview pixmap */
free_xschem_data();
xctx = save_xctx; /* restore schematic */
resetwin(0, 0, 0); /* set window size info back to original value */
set_modify(xctx->modified);
change_linewidth(-1.);
/* not needed: event loop takes care of this and don't need to regenerate xctx->save_pixmap. */
/* draw(); */
xctx = save_xctx;
XSetTile(display,gctiled, xctx->save_pixmap);
}
else if(!strcmp(what, "destroy")) {
dbg(1, "preview_window() destroy\n");
xctx = preview_xctx;
if(current_file) {
preview_clear();
preview_xctx = NULL;
}
Tk_DestroyWindow(tkpre_window);
my_free(1144, &current_file);
xctx = save_xctx; /* restore schematic */
save_xctx = NULL;
XSetTile(display,gctiled, xctx->save_pixmap);
set_modify(xctx->modified);
}
}
@ -896,7 +910,6 @@ void change_to_unix_fn(char* fn)
if (fn[i]!='\\') fn[ii++] = fn[i];
else { fn[ii++] = '/'; if (fn[i + 1] == '\\') ++i; }
}
}
#endif
@ -1362,29 +1375,29 @@ int Tcl_AppInit(Tcl_Interp *inter)
#if HAS_XCB==1
sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn,
screen_xcb, xctx->window, &format_rgb, 1 , 1);
save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn,
xctx->save_sfc = cairo_xcb_surface_create_with_xrender_format(xcbconn,
screen_xcb, xctx->save_pixmap, &format_rgb, 1 , 1);
#else
format = XRenderFindStandardFormat(display, PictStandardRGB24);
sfc = cairo_xlib_surface_create_with_xrender_format (display,
xctx->window, DefaultScreenOfDisplay(display), format, 1, 1);
save_sfc = cairo_xlib_surface_create_with_xrender_format(
xctx->save_sfc = cairo_xlib_surface_create_with_xrender_format(
display, xctx->save_pixmap, DefaultScreenOfDisplay(display), format, 1, 1);
#endif
#else
sfc = cairo_xlib_surface_create(display, xctx->window, visual, wattr.width, wattr.height);
save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, wattr.width, wattr.height);
xctx->save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap, visual, wattr.width, wattr.height);
#endif
if(cairo_surface_status(sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo surface\n");
return 1;
}
if(cairo_surface_status(save_sfc)!=CAIRO_STATUS_SUCCESS) {
if(cairo_surface_status(xctx->save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo surface\n");
return 1;
}
cairo_ctx = cairo_create(sfc);
cairo_save_ctx = cairo_create(save_sfc);
xctx->cairo_save_ctx = cairo_create(xctx->save_sfc);
#if 0
{
@ -1392,7 +1405,7 @@ int Tcl_AppInit(Tcl_Interp *inter)
cfo = cairo_font_options_create ();
cairo_font_options_set_antialias(cfo, CAIRO_ANTIALIAS_DEFAULT); /* CAIRO_ANTIALIAS_NONE */
cairo_set_font_options (cairo_ctx, cfo);
cairo_set_font_options (cairo_save_ctx, cfo);
cairo_set_font_options (xctx->cairo_save_ctx, cfo);
}
#endif
@ -1402,14 +1415,14 @@ int Tcl_AppInit(Tcl_Interp *inter)
tclsetvar("has_cairo","1");
cairo_select_font_face(cairo_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cairo_ctx, 20);
cairo_select_font_face(cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cairo_save_ctx, 20);
cairo_select_font_face(xctx->cairo_save_ctx, cairo_font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(xctx->cairo_save_ctx, 20);
cairo_set_line_width(cairo_ctx, 1);
cairo_set_line_width(cairo_save_ctx, 1);
cairo_set_line_width(xctx->cairo_save_ctx, 1);
cairo_set_line_join(cairo_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cairo_ctx, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join(cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
cairo_set_line_join(xctx->cairo_save_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(xctx->cairo_save_ctx, CAIRO_LINE_CAP_ROUND);
}
#endif /* HAS_CAIRO */

View File

@ -533,6 +533,10 @@ typedef struct {
Window window;
Pixmap save_pixmap;
XRectangle xrect[1];
#ifdef HAS_CAIRO
cairo_surface_t *save_sfc;
cairo_t *cairo_save_ctx;
#endif
} Xschem_ctx;
struct Lcc { /* used for symbols containing schematics as instances (LCC, Local Custom Cell) */
@ -669,7 +673,6 @@ extern int head_undo_ptr;
extern int max_undo;
extern int draw_dots;
extern int draw_single_layer;
extern int check_version;
extern int yyparse_error;
extern char *xschem_executable;
extern int depth;
@ -733,9 +736,10 @@ extern Pixmap cad_icon_pixmap, cad_icon_mask, *pixmap;
extern XColor xcolor_array[];
extern Visual *visual;
#ifdef HAS_CAIRO
extern cairo_surface_t *sfc, *save_sfc;
extern cairo_t *cairo_ctx, *cairo_save_ctx;
extern XRenderPictFormat *format;
extern cairo_surface_t *sfc;
extern cairo_t *cairo_ctx;
#if HAS_XCB==1
extern xcb_connection_t *xcbconn;
extern xcb_screen_t *screen_xcb;
@ -820,7 +824,7 @@ extern int Tcl_AppInit(Tcl_Interp *interp);
extern int source_tcl_file(char *s);
extern int callback(int event, int mx, int my, KeySym key,
int button, int aux, int state);
extern void resetwin(int create_pixmap, int clear_pixmap, int preview_window);
extern void resetwin(int create_pixmap, int clear_pixmap, int force);
extern void find_closest_net(double mx,double my);
extern void find_closest_box(double mx,double my);
extern void find_closest_arc(double mx,double my);

View File

@ -1352,7 +1352,9 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} {init
if { [winfo exists .dialog] } {
.dialog.l.paneright.pre configure -background {}
xschem preview_window draw .dialog.l.paneright.pre "$myload_dir1/$myload_dir2"
bind .dialog.l.paneright.pre <Expose> {xschem preview_window draw .dialog.l.paneright.pre "$myload_dir1/$myload_dir2"}
bind .dialog.l.paneright.pre <Expose> {
xschem preview_window draw .dialog.l.paneright.pre "$myload_dir1/$myload_dir2"
}
}
} else {
bind .dialog.l.paneright.pre <Expose> {}
@ -1389,8 +1391,9 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} {init
}
set t [is_xschem_file "$myload_dir1/$myload_retval"]
if { $t eq {0} } {
set answer [tk_messageBox -message "$myload_dir1/$myload_retval does not seem to be an xschem file...\nContinue?" \
-icon warning -parent . -type yesno]
set answer [
tk_messageBox -message "$myload_dir1/$myload_retval does not seem to be an xschem file...\nContinue?" \
-icon warning -parent . -type yesno]
if { $answer eq "no"} {
set myload_retval {}
return {}
@ -1398,7 +1401,8 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} {init
return "$myload_dir1/$myload_retval"
}
} elseif { $t ne {SYMBOL} && ($ext eq {.sym}) } {
set answer [tk_messageBox -message "$myload_dir1/$myload_retval does not seem to be a SYMBOL file...\nContinue?" \
set answer [
tk_messageBox -message "$myload_dir1/$myload_retval does not seem to be a SYMBOL file...\nContinue?" \
-icon warning -parent . -type yesno]
if { $answer eq "no"} {
set myload_retval {}
@ -3136,6 +3140,65 @@ proc toolbar_hide {} {
set $toolbar_visible 0
}
proc set_bindings {window_path} {
global env no_x
###
### Tk event handling
###
# bind . <Enter> {
# if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
# raise .dialog $window_path
# }
# }
bind . <Expose> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog $window_path
}
}
bind . <Visibility> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog $window_path
}
}
bind . <FocusIn> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog $window_path
}
}
bind $window_path <Double-Button-1> {xschem callback -3 %x %y 0 %b 0 %s}
bind $window_path <Double-Button-2> {xschem callback -3 %x %y 0 %b 0 %s}
bind $window_path <Double-Button-3> {xschem callback -3 %x %y 0 %b 0 %s}
bind $window_path <Expose> {xschem callback %T %x %y 0 %w %h %s}
bind $window_path <Configure> {xschem windowid; xschem callback %T %x %y 0 %w %h 0}
bind $window_path <ButtonPress> {xschem callback %T %x %y 0 %b 0 %s}
if {$::OS == "Windows"} {
bind $window_path <MouseWheel> {
if {%D<0} {
xschem callback 4 %x %y 0 5 0 %s
} else {
xschem callback 4 %x %y 0 4 0 %s
}
}
}
bind $window_path <ButtonRelease> {xschem callback %T %x %y 0 %b 0 %s}
# on Windows Alt key mask is reported as 131072 (1<<17) so build masks manually with values passed from C code
if {$::OS == "Windows" } {
bind $window_path <Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$Mod1Mask}]}
bind $window_path <Control-Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$ControlMask + $Mod1Mask}]}
bind $window_path <Shift-Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$ShiftMask + $Mod1Mask}]}
}
bind $window_path <KeyPress> {xschem callback %T %x %y %N 0 0 %s}
bind $window_path <KeyRelease> {xschem callback %T %x %y %N 0 0 %s} ;# 20161118
bind $window_path <Motion> {xschem callback %T %x %y 0 0 0 %s}
bind $window_path <Enter> {xschem callback %T %x %y 0 0 0 0 }
bind $window_path <Leave> {}
bind $window_path <Unmap> {
wm withdraw .infotext
set show_infowindow 0
}
bind $window_path "?" { textwindow "${XSCHEM_SHAREDIR}/xschem.help" }
}
## this function sets up all tk windows and binds X events. It is executed by xinit.c after completing
## all X initialization. This avoids race conditions.
@ -3143,9 +3206,8 @@ proc toolbar_hide {} {
## this could lead to crashes on some (may be slow) systems due to Configure/Expose events being delivered
## before xschem being ready to handle them.
proc build_windows {} {
global env
if { ( $::OS== "Windows" || [string length [lindex [array get env DISPLAY] 1] ] > 0 )
&& ![info exists no_x]} {
global env no_x
if {($::OS== "Windows" || [string length [lindex [array get env DISPLAY] 1] ] > 0 ) && ![info exists no_x]} {
pack .statusbar.2 -side left
pack .statusbar.3 -side left
pack .statusbar.4 -side left
@ -3160,67 +3222,7 @@ proc build_windows {} {
pack .statusbar -after .drw -anchor sw -fill x
bind .statusbar.5 <Leave> { xschem set cadgrid $grid; focus .drw}
bind .statusbar.3 <Leave> { xschem set cadsnap $snap; focus .drw}
###
### Tk event handling
###
# bind . <Enter> {
# if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
# raise .dialog .drw
# }
# }
bind . <Expose> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog .drw
}
}
bind . <Visibility> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog .drw
}
}
bind . <FocusIn> {
if { [winfo exists .dialog] && [winfo ismapped .dialog] && [winfo ismapped .] && [wm stackorder .dialog isbelow . ]} {
raise .dialog .drw
}
}
bind .drw <Double-Button-1> {xschem callback -3 %x %y 0 %b 0 %s}
bind .drw <Double-Button-2> {xschem callback -3 %x %y 0 %b 0 %s}
bind .drw <Double-Button-3> {xschem callback -3 %x %y 0 %b 0 %s}
bind .drw <Expose> {xschem callback %T %x %y 0 %w %h %s}
bind .drw <Configure> {xschem windowid; xschem callback %T %x %y 0 %w %h 0}
bind .drw <ButtonPress> {xschem callback %T %x %y 0 %b 0 %s}
if {$::OS == "Windows"} {
bind .drw <MouseWheel> {
if {%D<0} {
xschem callback 4 %x %y 0 5 0 %s
} else {
xschem callback 4 %x %y 0 4 0 %s
}
}
}
bind .drw <ButtonRelease> {xschem callback %T %x %y 0 %b 0 %s}
# on Windows Alt key mask is reported as 131072 (1<<17) so build masks manually with values passed from C code
if {$::OS == "Windows" } {
bind .drw <Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$Mod1Mask}]}
bind .drw <Control-Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$ControlMask + $Mod1Mask}]}
bind .drw <Shift-Alt-KeyPress> {xschem callback %T %x %y %N 0 0 [expr {$ShiftMask + $Mod1Mask}]}
}
bind .drw <KeyPress> {xschem callback %T %x %y %N 0 0 %s}
bind .drw <KeyRelease> {xschem callback %T %x %y %N 0 0 %s} ;# 20161118
bind .drw <Motion> {xschem callback %T %x %y 0 0 0 %s}
bind .drw <Enter> {xschem callback %T %x %y 0 0 0 0 }
bind .drw <Leave> {}
bind .drw <Unmap> {
wm withdraw .infotext
set show_infowindow 0
}
bind .drw "?" { textwindow "${XSCHEM_SHAREDIR}/xschem.help" }
set_bindings {.drw}
}
}

View File

@ -299,7 +299,7 @@ C {ngspice_get_expr.sym} 800 -970 0 1 {name=r1
node="[ngspice::get_current \{q4[ib]\}]"
descr = Ib
}
C {ngspice_get_expr.sym} 570 -460 0 0 {name=r11
C {ngspice_get_expr.sym} 580 -460 0 0 {name=r11
node="[format %.4g [expr ([ngspice::get_voltage e8] - [ngspice::get_voltage c8]) * [ngspice::get_current \{q8[ic]\}]]] W"
descr = power
}