add macro DRAW_ALL_CAIRO: if set to 1 graphics primitives will use cairo instead of Xlib. Currently work in progress, as of now only the grid and the final XCopyArea done in draw() will use Cairo if macro is set

This commit is contained in:
stefan schippers 2022-11-30 00:59:45 +01:00
parent 4b05d996e5
commit 7ae10bd7da
3 changed files with 80 additions and 17 deletions

View File

@ -28,6 +28,9 @@
#define xDashType LineDoubleDash
#else
#define xDashType LineOnOffDash
#endif
#if !defined(__unix__)
#if defined(HAS_CAIRO)
static void clear_cairo_surface(cairo_t *cr, double x, double y, double width, double height)
{
@ -738,30 +741,70 @@ static void drawgrid()
{
double x,y;
double delta,tmp;
#if DRAW_ALL_CAIRO==0
int i=0;
int big_gr;
dbg(1, "drawgrid(): draw grid\n");
big_gr = tclgetboolvar("big_grid_points");
#endif
dbg(1, "drawgrid(): draw grid\n");
if( !tclgetboolvar("draw_grid") || !has_x) return;
delta=tclgetdoublevar("cadgrid")*xctx->mooz;
#if DRAW_ALL_CAIRO==1
set_cairo_color(GRIDLAYER);
#endif
while(delta < CADGRIDTHRESHOLD) delta*=CADGRIDMULTIPLY; /* <-- to be improved,but works */
x = xctx->xorigin*xctx->mooz; y = xctx->yorigin*xctx->mooz;
if(y > xctx->areay1 && y < xctx->areay2) {
if(xctx->draw_window)
if(xctx->draw_window) {
#if DRAW_ALL_CAIRO==1
cairo_move_to(xctx->cairo_ctx, xctx->areax1+1, y);
cairo_line_to(xctx->cairo_ctx, xctx->areax2-1, y);
#else
XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
if(xctx->draw_pixmap)
#endif
}
if(xctx->draw_pixmap) {
#if DRAW_ALL_CAIRO==1
cairo_move_to(xctx->cairo_save_ctx, xctx->areax1+1, y);
cairo_line_to(xctx->cairo_save_ctx, xctx->areax2-1, y);
#else
XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],xctx->areax1+1,(int)y, xctx->areax2-1, (int)y);
#endif
}
}
if(x > xctx->areax1 && x < xctx->areax2) {
if(xctx->draw_window)
if(xctx->draw_window) {
#if DRAW_ALL_CAIRO==1
cairo_move_to(xctx->cairo_ctx, x, xctx->areay1+1);
cairo_line_to(xctx->cairo_ctx, x, xctx->areay2-1);
#else
XDrawLine(display, xctx->window, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
if(xctx->draw_pixmap)
#endif
}
if(xctx->draw_pixmap) {
#if DRAW_ALL_CAIRO==1
cairo_move_to(xctx->cairo_save_ctx, x, xctx->areay1+1);
cairo_line_to(xctx->cairo_save_ctx, x, xctx->areay2-1);
#else
XDrawLine(display, xctx->save_pixmap, xctx->gc[GRIDLAYER],(int)x,xctx->areay1+1, (int)x, xctx->areay2-1);
#endif
}
}
tmp = floor((xctx->areay1+1)/delta)*delta-fmod(-xctx->yorigin*xctx->mooz,delta);
for(x=floor((xctx->areax1+1)/delta)*delta-fmod(-xctx->xorigin*xctx->mooz,delta); x < xctx->areax2; x += delta) {
for(y=tmp; y < xctx->areay2; y += delta) {
#if DRAW_ALL_CAIRO==1
if(xctx->draw_window) {
cairo_move_to(xctx->cairo_ctx, x, y);
/* cairo_line_to(xctx->cairo_ctx, x, y); */
cairo_close_path(xctx->cairo_ctx);
}
if(xctx->draw_pixmap) {
cairo_move_to(xctx->cairo_save_ctx, x, y);
/* cairo_line_to(xctx->cairo_save_ctx, x, y); */
cairo_close_path(xctx->cairo_save_ctx);
}
#else
if(i>=CADMAXGRIDPOINTS) {
if(xctx->draw_window) {
if(big_gr) {
@ -788,8 +831,10 @@ static void drawgrid()
xctx->gridpoint[i].y=(short)(y);
i++;
}
#endif
}
}
#if DRAW_ALL_CAIRO==0
if(xctx->draw_window) {
if(big_gr) {
XDrawSegments(display,xctx->window,xctx->gc[GRIDLAYER],xctx->biggridpoint,i);
@ -804,6 +849,12 @@ static void drawgrid()
XDrawPoints(display,xctx->save_pixmap,xctx->gc[GRIDLAYER],xctx->gridpoint,i,CoordModeOrigin);
}
}
#endif
#if DRAW_ALL_CAIRO==1
if(xctx->draw_pixmap) cairo_stroke(xctx->cairo_save_ctx);
if(xctx->draw_window) cairo_stroke(xctx->cairo_ctx);
#endif
}
#if !defined(__unix__) && defined(HAS_CAIRO)
@ -3472,7 +3523,8 @@ void draw(void)
}
#if !defined(__unix__) && defined(HAS_CAIRO)
else
my_cairo_fill(xctx->cairo_sfc, xctx->xrect[0].x, xctx->xrect[0].y, xctx->xrect[0].width, xctx->xrect[0].height);
my_cairo_fill(xctx->cairo_sfc, xctx->xrect[0].x, xctx->xrect[0].y,
xctx->xrect[0].width, xctx->xrect[0].height);
#endif
}
draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */
@ -3495,9 +3547,14 @@ int XSetTile(Display* display, GC gc, Pixmap s_pixmap)
void MyXCopyArea(Display* display, Drawable src, Drawable dest, GC gc, int src_x, int src_y,
unsigned int width, unsigned int height, int dest_x, int dest_y)
{
XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
#if !defined(__unix__) && defined(HAS_CAIRO)
#if !defined(__unix__) && defined(HAS_CAIRO)
my_cairo_fill(xctx->cairo_save_sfc, dest_x, dest_y, width, height);
#endif
#elif (defined(__unix__) && defined(HAS_CAIRO)) || DRAW_ALL_CAIRO==1
cairo_set_source_surface(xctx->cairo_ctx, xctx->cairo_save_sfc, 0, 0);
cairo_paint(xctx->cairo_ctx);
#else
XCopyArea(display, src, dest, gc, src_x, src_y, width, height, dest_x, dest_y);
#endif
}

View File

@ -1723,6 +1723,7 @@ void change_linewidth(double w)
XSetLineAttributes (display, xctx->gc[i], INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound);
}
XSetLineAttributes (display, xctx->gctiled, INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound);
}
if(!xctx->only_probes) {
xctx->areax1 = -2*INT_WIDTH(xctx->lw);
@ -1732,6 +1733,10 @@ void change_linewidth(double w)
xctx->areaw = xctx->areax2-xctx->areax1;
xctx->areah = xctx->areay2 - xctx->areay1;
}
#if HAS_CAIRO==1
cairo_set_line_width(xctx->cairo_ctx, INT_WIDTH(xctx->lw));
cairo_set_line_width(xctx->cairo_save_ctx, INT_WIDTH(xctx->lw));
#endif
}
/* clears and creates cairo_sfc, cairo_ctx, cairo_save_sfc, cairo_save_ctx
@ -1756,10 +1761,11 @@ static void resetcairo(int create, int clear, int force_or_resize)
cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_SLIGHT);
/***** Create Cairo save buffer drawing area *****/
#ifdef __unix__
xctx->cairo_save_sfc =
cairo_xlib_surface_create(display, xctx->save_pixmap, visual, xctx->xrect[0].width, xctx->xrect[0].height);
xctx->cairo_save_sfc = cairo_xlib_surface_create(display, xctx->save_pixmap,
visual, xctx->xrect[0].width, xctx->xrect[0].height);
#else
xctx->cairo_save_sfc = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_RGB24, xctx->xrect[0].width, xctx->xrect[0].height);
xctx->cairo_save_sfc = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_RGB24,
xctx->xrect[0].width, xctx->xrect[0].height);
#endif
if(cairo_surface_status(xctx->cairo_save_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo xcb surface\n");
@ -1772,7 +1778,6 @@ static void resetcairo(int create, int clear, int force_or_resize)
cairo_set_font_options(xctx->cairo_save_ctx, options);
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);
/***** Create Cairo main drawing window structures *****/
@ -1780,7 +1785,8 @@ static void resetcairo(int create, int clear, int force_or_resize)
xctx->cairo_sfc = cairo_xlib_surface_create(display, xctx->window, visual,
xctx->xrect[0].width, xctx->xrect[0].height);
#else
xctx->cairo_sfc = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_RGB24, xctx->xrect[0].width, xctx->xrect[0].height);
xctx->cairo_sfc = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_RGB24,
xctx->xrect[0].width, xctx->xrect[0].height);
#endif
if(cairo_surface_status(xctx->cairo_sfc)!=CAIRO_STATUS_SUCCESS) {
fprintf(errfp, "ERROR: invalid cairo surface\n");
@ -1792,7 +1798,6 @@ static void resetcairo(int create, int clear, int force_or_resize)
cairo_set_font_options(xctx->cairo_ctx, options);
cairo_set_line_width(xctx->cairo_ctx, 1);
cairo_set_line_join(xctx->cairo_ctx, CAIRO_LINE_JOIN_ROUND);
cairo_set_line_cap(xctx->cairo_ctx, CAIRO_LINE_CAP_ROUND);
cairo_font_options_destroy(options);
@ -1871,8 +1876,8 @@ void resetwin(int create_pixmap, int clear_pixmap, int force, int w, int h)
XSetTile(display,xctx->gctiled, xctx->save_pixmap);
XSetFillStyle(display,xctx->gctiled,FillTiled);
/* whenever a pixmap is recreated all GC attributes must be reissued */
change_linewidth(-1.0);
resetcairo(1, 0, 1); /* create, clear, force */
change_linewidth(-1.0);
}
}
}

View File

@ -102,6 +102,7 @@ extern char win_temp_dir[PATH_MAX];
#endif
#if HAS_CAIRO==1
#define DRAW_ALL_CAIRO 0 /* use cairo for all graphics. Work in progress! */
#include <cairo.h>
#ifdef __unix__
#include <cairo-xlib.h>