Bill Allombert on Fri, 26 Aug 2005 14:17:13 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
object-oriented graphic engine |
Hello PARI-dev, I would like to propose a rewrite of the graphic code in an object-oriented fashion to avoid duplication. This one follow more closely the RectObj code. struct plot_eng { /*Set color*/ void (*sc)(void *data, long col); /*Point*/ void (*pt)(void *data, long x, long y); /*Line*/ void (*ln)(void *data, long x1, long y1, long x2, long y2); /*Box*/ void (*bx)(void *data, long x, long y, long w, long h); /*Multi-point*/ void (*mp)(void *data, long n, struct plot_points *points); /*Multi-line*/ void (*ml)(void *data, long n, struct plot_points *points); /*Text*/ void (*st)(void *data, long x, long y, char *s, long l); }; and a function: void gen_rectdraw0(struct plot_eng *eng, void *data, long *w, long *x, long *y, long lw, double xs, double ys); The attached patch implement gen_rectdraw0 and use it for the X11 display. Once this patch is accepted, we should use gen_rectdraw0 for the other graphic output. A possible change would be to handle color using a new atom (set color) instead of hard-coding colors in each nodes. Cheers, Bill
Index: pari/src/graph/plotX.c =================================================================== --- pari.orig/src/graph/plotX.c 2004-11-30 16:15:47.000000000 +0100 +++ pari/src/graph/plotX.c 2005-08-26 11:50:20.000000000 +0200 @@ -48,6 +48,73 @@ static XColor *PARI_Colors; static XColor *PARI_ExactColors; +struct data_x +{ + Display *display; + Window win; + GC gc; +}; + +static void SetForeground(void *data, long col) +{ + struct data_x *dx = (struct data_x *) data; + XSetForeground(dx->display,dx->gc, PARI_Colors[col].pixel); +} + + +static void DrawPoint(void *data, long x, long y) +{ + struct data_x *dx = (struct data_x *) data; + XDrawPoint(dx->display,dx->win,dx->gc, x,y); +} + +static void DrawLine(void *data, long x1, long y1, long x2, long y2) +{ + struct data_x *dx = (struct data_x *) data; + XDrawLine(dx->display,dx->win,dx->gc, x1,y1, x2,y2); +} + +static void DrawRectangle(void *data, long x, long y, long w, long h) +{ + struct data_x *dx = (struct data_x *) data; + XDrawRectangle(dx->display,dx->win,dx->gc, x,y, w,h); +} + +static void DrawPoints(void *data, long nb, struct plot_points *p) +{ + struct data_x *dx = (struct data_x *) data; + XPoint *xp=(XPoint*)gpmalloc(sizeof(xp)*nb); + long i; + for (i=0;i<nb;i++) + { + xp[i].x=p[i].x; + xp[i].y=p[i].y; + } + XDrawPoints(dx->display,dx->win,dx->gc, xp, nb, 0); + free(xp); +} + +static void DrawLines(void *data, long nb, struct plot_points *p) +{ + struct data_x *dx = (struct data_x *) data; + XPoint *xp=(XPoint*)gpmalloc(sizeof(xp)*nb); + long i; + for (i=0;i<nb;i++) + { + xp[i].x=p[i].x; + xp[i].y=p[i].y; + } + XDrawLines(dx->display,dx->win,dx->gc, xp, nb, 0); + free(xp); +} + +static void DrawString(void *data, long x, long y, char *text, long numtext) +{ + struct data_x *dx = (struct data_x *) data; + XDrawString(dx->display,dx->win,dx->gc, x,y, text, numtext); +} + + static char *PARI_DefaultColors[MAX_COLORS] = { " ", @@ -111,18 +178,10 @@ void rectdraw0(long *w, long *x, long *y, long lw, long do_free) { - double *ptx,*pty; - long *c, shift; - long *numpoints[MAX_COLORS],*numtexts[MAX_COLORS]; - long *xtexts[MAX_COLORS],*ytexts[MAX_COLORS]; - col_counter rcolcnt; - long col,i,j,x0,y0,oldwidth,oldheight; - long hjust, vjust, hgap, vgap, hgapsize = h_unit, vgapsize = v_unit; - char **texts[MAX_COLORS]; - PariRect *e; - RectObj *p1; + long oldwidth,oldheight; + struct plot_eng plotX; + struct data_x dx; double xs = 1, ys = 1; - int screen; Display *display; GC gc; @@ -131,9 +190,6 @@ XSizeHints size_hints; XFontStruct *font_info; XSetWindowAttributes attrib; - XPoint *points[MAX_COLORS],**lines[MAX_COLORS]; - XSegment *seg[MAX_COLORS]; - XRectangle *rec[MAX_COLORS]; Atom wm_delete_window, wm_protocols; if (fork()) return; /* parent process returns */ @@ -150,28 +206,6 @@ XSetIOErrorHandler(IOerror); PARI_ColorSetUp(display,PARI_DefaultColors,MAX_COLORS); - plot_count(w, lw, rcolcnt); - for (col=1; col<MAX_COLORS; col++) - { - char *m; - long *c = rcolcnt[col]; - points[col]=(XPoint*)zmalloc(c[ROt_PT]*sizeof(XPoint)); - seg[col]=(XSegment*)zmalloc(c[ROt_LN]*sizeof(XSegment)); - rec[col]=(XRectangle*)zmalloc(c[ROt_BX]*sizeof(XRectangle)); - - i = c[ROt_ML]; m = zmalloc(i * (sizeof(long) + sizeof(XPoint*))); - numpoints[col]=(long*)m; i *= sizeof(XPoint*); - m += i; lines[col]=(XPoint**)m; - - i = c[ROt_ST]; m = zmalloc(i * (sizeof(char*) + 3*sizeof(long))); - texts[col]=(char**)m; i *= sizeof(long); - m += i; numtexts[col]=(long*)m; - m += i; xtexts[col]=(long*)m; - m += i; ytexts[col]=(long*)m; - - c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0; - } - screen = DefaultScreen(display); win = XCreateSimpleWindow (display, RootWindow(display, screen), 0, 0, w_width, w_height, @@ -204,6 +238,16 @@ XMapWindow(display, win); oldwidth = w_width; oldheight = w_height; + dx.display= display; + dx.win =win; + dx.gc=gc; + plotX.sc=&SetForeground; + plotX.pt=&DrawPoint; + plotX.ln=&DrawLine; + plotX.bx=&DrawRectangle; + plotX.mp=&DrawPoints; + plotX.ml=&DrawLines; + plotX.st=&DrawString; for(;;) { @@ -216,14 +260,6 @@ case ButtonPress: case DestroyNotify: XUnloadFont(display,font_info->fid); XFreeGC(display,gc); -#define myfree(x) if (x) free(x) - for(col=1;col<MAX_COLORS;col++) - { - myfree(points[col]); myfree(seg[col]); myfree(rec[col]); - for(i=0;i<rcolcnt[col][ROt_ML];i++) myfree(lines[col][i]); - myfree(numpoints[col]); myfree(texts[col]); - } -#undef myfree free_graph(); if (do_free) { free(w); free(x); free(y); } XCloseDisplay(display); exit(0); @@ -240,90 +276,7 @@ xs = ((double)width)/w_width; ys=((double)height)/w_height; } case Expose: - for(i=0; i<lw; i++) - { - e=rectgraph[w[i]]; x0=x[i]; y0=y[i]; - for (p1 = RHead(e); p1; p1 = RoNext(p1)) - { - col = RoCol(p1); - c = rcolcnt[col]; - switch(RoType(p1)) - { - case ROt_PT: - points[col][c[ROt_PT]].x = DTOL((RoPTx(p1)+x0)*xs); - points[col][c[ROt_PT]].y = DTOL((RoPTy(p1)+y0)*ys); - c[ROt_PT]++;break; - case ROt_LN: - seg[col][c[ROt_LN]].x1 = DTOL((RoLNx1(p1)+x0)*xs); - seg[col][c[ROt_LN]].y1 = DTOL((RoLNy1(p1)+y0)*ys); - seg[col][c[ROt_LN]].x2 = DTOL((RoLNx2(p1)+x0)*xs); - seg[col][c[ROt_LN]].y2 = DTOL((RoLNy2(p1)+y0)*ys); - c[ROt_LN]++;break; - case ROt_BX: - rec[col][c[ROt_BX]].x = DTOL((RoBXx1(p1)+x0)*xs); - rec[col][c[ROt_BX]].y = DTOL((RoBXy1(p1)+y0)*ys); - rec[col][c[ROt_BX]].width = DTOL((RoBXx2(p1)-RoBXx1(p1))*xs); - rec[col][c[ROt_BX]].height = DTOL((RoBXy2(p1)-RoBXy1(p1))*ys); - c[ROt_BX]++;break; - case ROt_MP: - ptx = RoMPxs(p1); pty = RoMPys(p1); - for(j=0;j<RoMPcnt(p1);j++) - { - points[col][c[ROt_PT]+j].x = DTOL((ptx[j]+x0)*xs); - points[col][c[ROt_PT]+j].y = DTOL((pty[j]+y0)*ys); - } - c[ROt_PT]+=RoMPcnt(p1);break; - case ROt_ML: - ptx=RoMLxs(p1); pty=RoMLys(p1); - numpoints[col][c[ROt_ML]] = RoMLcnt(p1); - lines[col][c[ROt_ML]] = - (XPoint*)zmalloc(RoMLcnt(p1)*sizeof(XPoint)); - for(j=0;j<RoMLcnt(p1);j++) - { - lines[col][c[ROt_ML]][j].x = DTOL((ptx[j]+x0)*xs); - lines[col][c[ROt_ML]][j].y = DTOL((pty[j]+y0)*ys); - } - c[ROt_ML]++;break; - case ROt_ST: - hjust = RoSTdir(p1) & RoSTdirHPOS_mask; - vjust = RoSTdir(p1) & RoSTdirVPOS_mask; - hgap = RoSTdir(p1) & RoSTdirHGAP; - if (hgap) - hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize; - vgap = RoSTdir(p1) & RoSTdirVGAP; - if (vgap) - vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize; - if (vjust != RoSTdirBOTTOM) - vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(f_height - 1); - texts[col][c[ROt_ST]]=RoSTs(p1); - numtexts[col][c[ROt_ST]]=RoSTl(p1); - shift = (hjust == RoSTdirLEFT ? 0 : - (hjust == RoSTdirRIGHT ? 2 : 1)); - xtexts[col][c[ROt_ST]] - = DTOL(( RoSTx(p1) + x0 + hgap - - (strlen(RoSTs(p1)) * pari_plot.fwidth - * shift)/2)*xs); - ytexts[col][c[ROt_ST]] = DTOL((RoSTy(p1)+y0-vgap/2)*ys); - c[ROt_ST]++;break; - default: break; - } - } - } - for(col=1; col<MAX_COLORS; col++) - { - long *c = rcolcnt[col]; - XSetForeground(display, gc, PARI_Colors[col].pixel); - if(c[ROt_PT]) XDrawPoints(display,win,gc,points[col],c[ROt_PT],0); - if(c[ROt_LN]) XDrawSegments(display,win,gc,seg[col],c[ROt_LN]); - if(c[ROt_BX]) XDrawRectangles(display,win,gc,rec[col],c[ROt_BX]); - for(i=0;i<c[ROt_ML];i++) - XDrawLines(display,win,gc,lines[col][i],numpoints[col][i],0); - for(i=0;i<c[ROt_ST];i++) - XDrawString(display,win,gc, xtexts[col][i],ytexts[col][i], - texts[col][i],numtexts[col][i]); - - c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0; - } + gen_rectdraw0(&plotX, (void *)&dx, w, x, y,lw,xs,ys); } } } @@ -357,3 +310,4 @@ void set_pointsize(double d) { (void)d; } + Index: pari/src/graph/plotport.c =================================================================== --- pari.orig/src/graph/plotport.c 2005-08-25 23:14:20.000000000 +0200 +++ pari/src/graph/plotport.c 2005-08-26 11:52:15.000000000 +0200 @@ -2164,3 +2164,98 @@ ((dir & RoSTdirHPOS_mask) == RoSTdirLEFT ? "L" : ((dir & RoSTdirHPOS_mask) == RoSTdirRIGHT ? "R" : "C"))); } + +void +gen_rectdraw0(struct plot_eng *eng, void *data, long *w, long *x, long *y, long lw, double xs, double ys) +{ + long i, j; + long hgapsize = h_unit, vgapsize = v_unit; + for(i=0; i<lw; i++) + { + PariRect *e=rectgraph[w[i]]; + RectObj *p1=RHead(e); + long x0=x[i],y0=y[i]; + for (p1 = RHead(e); p1; p1 = RoNext(p1)) + { + switch(RoType(p1)) + { + case ROt_PT: + eng->sc(data,RoCol(p1)); + eng->pt(data, DTOL((RoPTx(p1)+x0)*xs), DTOL((RoPTy(p1)+y0)*ys)); + break; + case ROt_LN: + eng->sc(data,RoCol(p1)); + eng->ln(data, DTOL((RoLNx1(p1)+x0)*xs), DTOL((RoLNy1(p1)+y0)*ys), + DTOL((RoLNx2(p1)+x0)*xs), DTOL((RoLNy2(p1)+y0)*ys)); + break; + case ROt_BX: + eng->sc(data,RoCol(p1)); + eng->bx(data, DTOL((RoBXx1(p1)+x0)*xs), DTOL((RoBXy1(p1)+y0)*ys), + DTOL((RoBXx2(p1)-RoBXx1(p1))*xs), + DTOL((RoBXy2(p1)-RoBXy1(p1))*ys)); + break; + case ROt_MP: + { + double *ptx = RoMPxs(p1); + double *pty = RoMPys(p1); + long nb = RoMPcnt(p1); + struct plot_points *points = + (struct plot_points *) gpmalloc(sizeof(*points)*nb); + for(j=0;j<nb;j++) + { + points[j].x = DTOL((ptx[j]+x0)*xs); + points[j].y = DTOL((pty[j]+y0)*ys); + } + eng->sc(data,RoCol(p1)); + eng->mp(data, nb, points); + free(points); + break; + } + case ROt_ML: + { + double *ptx = RoMLxs(p1); + double *pty = RoMLys(p1); + long nb = RoMLcnt(p1); + struct plot_points *points = + (struct plot_points *) gpmalloc(sizeof(*points)*nb); + for(j=0;j<nb;j++) + { + points[j].x = DTOL((ptx[j]+x0)*xs); + points[j].y = DTOL((pty[j]+y0)*ys); + } + eng->sc(data,RoCol(p1)); + eng->ml(data, nb, points); + free(points); + break; + } + case ROt_ST: + { + long hjust = RoSTdir(p1) & RoSTdirHPOS_mask; + long vjust = RoSTdir(p1) & RoSTdirVPOS_mask; + char *text = RoSTs(p1); + long l = RoSTl(p1); + long x, y; + long hgap = RoSTdir(p1) & RoSTdirHGAP; + long vgap = RoSTdir(p1) & RoSTdirVGAP; + long shift = (hjust == RoSTdirLEFT ? 0 : + (hjust == RoSTdirRIGHT ? 2 : 1)); + if (hgap) + hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize; + if (vgap) + vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize; + if (vjust != RoSTdirBOTTOM) + vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(f_height - 1); + x = DTOL(( RoSTx(p1) + x0 + hgap + - (strlen(RoSTs(p1)) * pari_plot.fwidth + * shift)/2)*xs); + y = DTOL((RoSTy(p1)+y0-vgap/2)*ys); + eng->sc(data,RoCol(p1)); + eng->st(data, x, y, text, l); + break; + } + default: + break; + } + } + } +} Index: pari/src/graph/rect.h =================================================================== --- pari.orig/src/graph/rect.h 2005-08-25 23:14:20.000000000 +0200 +++ pari/src/graph/rect.h 2005-08-26 10:12:26.000000000 +0200 @@ -110,6 +110,23 @@ double size; } RectObjPS; +struct plot_points +{ + long x, y; +}; + +struct plot_eng +{ + void (*sc)(void *data, long col); + void (*pt)(void *data, long x, long y); + void (*ln)(void *data, long x1, long y1, long x2, long y2); + void (*bx)(void *data, long x, long y, long w, long h); + void (*mp)(void *data, long n, struct plot_points *points); + void (*ml)(void *data, long n, struct plot_points *points); + void (*st)(void *data, long x, long y, char *s, long l); +}; + + #define BLACK 1 /* Default */ #define BLUE 2 /* Axes */ #define VIOLET 3 /* Odd numbered curves in ploth */ @@ -296,6 +313,8 @@ void free_graph(void); +void gen_rectdraw0(struct plot_eng *eng, void *data, long *w, long *x, long *y, long lw, double xs, double ys); + /* architecture-dependent plot file (plotX.c, plognuplot.c...) */ void PARI_get_plot(long fatal); long plot_outfile_set(char *s);