| 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);