Bill Allombert on Mon, 12 Sep 2005 19:42:16 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: object-oriented graphic engine


On Fri, Aug 26, 2005 at 02:06:23PM +0200, Bill Allombert wrote:
> 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.
> 
> Once this patch is accepted, we should use gen_rectdraw0 for the
> other graphic output.

Since Karim has commited this patch, I propose the sequel for
plotfltk and  plotQt. Warning: they are C++ files and I am not fluent
in this idiom...

Maybe we could clean up the interface by letting gen_rectdraw computing 
xs and ys.

We should probably rename gen_rectdraw.

Cheers,
Bill.
Index: src/graph/plotfltk.c
===================================================================
RCS file: /home/cvs/pari/src/graph/plotfltk.c,v
retrieving revision 1.10
diff -u -r1.10 plotfltk.c
--- src/graph/plotfltk.c	5 Dec 2004 18:35:16 -0000	1.10
+++ src/graph/plotfltk.c	12 Sep 2005 17:37:01 -0000
@@ -29,21 +29,14 @@
 #include <FL/Fl_Window.H>
 #include <FL/fl_draw.H>
 
-typedef struct Point_s {long x, y;} Point;
-typedef struct Rectangle_s {long x, y, width, height;} Rectangle;
-typedef struct Segment_s {long x1, y1, x2, y2;} Segment;
-typedef char* String;
-
 class Plotter: public Fl_Window {
 
 public:
     //Plotter(int x, int y, int w, int h, const char
     //   *label = 0);
     Plotter( long *w, long *x, long *y, long lw, const char* name = 0);
-    ~Plotter();
 
 private:
-    void alloc();
     void draw();
     int handle(int event);
 
@@ -52,17 +45,7 @@
     long *my_x;                        // x, y: array of x,y-coordinates of the
     long *my_y;                        // top left corners of the rectwindows
     long my_lw;                        // lw: number of rectwindows
-    col_counter rcolcnt;
-    long rcnt[ROt_MAX+1];
-    Point *points[MAX_COLORS];
-    Segment *seg[MAX_COLORS];
-    Point **lines[MAX_COLORS];
-    Rectangle *rec[MAX_COLORS];
-    Point *textPos[MAX_COLORS];
-    String *texts[MAX_COLORS];
     Fl_Color color[MAX_COLORS];
-    long *numpoints[MAX_COLORS];
-    long *numtexts[MAX_COLORS];
 };
 
 Fl_Color rgb_color(int R, int G, int B)
@@ -78,7 +61,6 @@
 {
 
     this->my_w=w; this->my_x=x; this->my_y=y; this->my_lw=lw;
-    alloc();
     color[0]         = FL_WHITE;
     color[BLACK]     = FL_BLACK;
     color[BLUE]      = FL_BLUE;
@@ -89,177 +71,71 @@
     color[GAINSBORO] = rgb_color( 220, 220, 220);
 }
 
-Plotter::~Plotter() {
-
-    for( int col = 1; col < MAX_COLORS; col++) {
-        delete[] points[col];
-        delete[] seg[col];
-	delete[] rec[col];
-        for(int i=0;i<rcolcnt[col][ROt_ML];i++) delete lines[col][i];
-        delete[] lines[col];
-        delete[] texts[col];
-        delete[] numpoints[col];
-        delete[] numtexts[col];
-    }
+static void SetForeground(void *data, long col)
+{
+   Fl_Color *color=(Fl_Color*) data;
+   fl_color(color[col]);
 }
 
-void DrawPoints(Point *points,long n)
+static void DrawPoint(void *data, long x, long y) 
 {
-  for(int i=0;i<n;i++)
-    fl_point(points[i].x, points[i].y);
+  fl_point(x, y);
+}
+
+static void DrawLine(void *data, long x1, long y1, long x2, long y2)
+{ 
+  fl_line(x1, y1, x2, y2);
 }
 
-void DrawSegments(Segment *seg,long n)
+static void DrawRectangle(void *data, long x, long y, long w, long h)
 {
-  for(int i=0;i<n;i++)
-    fl_line(seg[i].x1, seg[i].y1, seg[i].x2, seg[i].y2);
+  fl_rect(x,y, w,h);
 }
 
-void DrawRectangles(Rectangle *rec, long n)
+static void DrawPoints(void *data, long nb, struct plot_points *p)
 {
-  for(int i=0;i<n;i++)
-    fl_rect(rec[i].x,rec[i].y,rec[i].width,rec[i].height);
+  long i;
+   for (i=0;i<nb;i++)
+     fl_point(p[i].x, p[i].y);
 }
 
-void DrawLines(Point *lines, long n)
+static void DrawLines(void *data, long nb, struct plot_points *p)
 {
-  for(int i=1;i<n;i++)
-    fl_line(lines[i-1].x, lines[i-1].y, lines[i].x, lines[i].y);
+  long i;
+  for (i=1; i<nb; i++)
+    fl_line(p[i-1].x, p[i-1].y, p[i].x, p[i].y);
 }
 
-void DrawString(Point textPos, String text, long n)
+static void DrawString(void *data, long x, long y, char *text, long numtext)
 {
-  fl_draw(text,n,textPos.x,textPos.y);
+  fl_draw(text,numtext,x,y);
 }
 
 void Plotter::draw() 
 {
-  long shift;
-  long j;
-  long hjust, vjust, hgap, vgap, hgapsize, vgapsize;
+  long hgapsize, vgapsize;
   long *w=my_w;                        // map into rectgraph indexes
   long *x=my_x;                        // x, y: array of x,y-coorinates of the
   long *y=my_y;                        //   top left corners of the rectwindows
   long lw=my_lw;                       // lw: number of rectwindows
-  long *c;
-  long col;
 
   double xs = double(this->w())/pari_plot.width;
   double ys = double(this->h())/pari_plot.height;
 
-  for( int col = 1; col < MAX_COLORS; col++) {
-    c = rcolcnt[col];
-    c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0;
-  }
   hgapsize = h_unit;  vgapsize = v_unit;
-  for(int i=0; i<lw; i++)
-  {
-    PariRect *e=rectgraph[w[i]];
-    RectObj *p1=RHead(e);
-    long x0=x[i],y0=y[i];
-    while(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:
-        {
-          double *ptx = RoMPxs(p1), *pty = RoMPys(p1);
-          for(int 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:
-        {
-          double *ptx=RoMLxs(p1), *pty=RoMLys(p1);
-          numpoints[col][c[ROt_ML]] = RoMLcnt(p1);
-          lines[col][c[ROt_ML]] = new Point[RoMLcnt(p1)];
-          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));
-          textPos[col][c[ROt_ST]].x
-            = DTOL(( RoSTx(p1) + x0 + hgap
-                  - (strlen(RoSTs(p1)) * pari_plot.fwidth
-                    * shift)/2)*xs);
-          textPos[col][c[ROt_ST]].y = DTOL((RoSTy(p1)+y0-vgap/2)*ys);
-          c[ROt_ST]++;break;
-        default: break;
-        }
-        p1=RoNext(p1);
-      }
-    }
-    fl_font(FL_COURIER, int(pari_plot.fheight * xs));
-    fl_color(FL_WHITE); // transparent window on Windows otherwise
-    fl_rectf(0, 0, this->w(), this->h());
-    for(col=1; col<MAX_COLORS; col++)
-    {
-      c = rcolcnt[col];
-      fl_color(color[col]);
-      if(c[ROt_PT]) DrawPoints(points[col],c[ROt_PT]);
-      if(c[ROt_LN]) DrawSegments(seg[col],c[ROt_LN]);
-      if(c[ROt_BX]) DrawRectangles(rec[col],c[ROt_BX]);
-      for(long i=0;i<c[ROt_ML];i++)
-        DrawLines(lines[col][i],numpoints[col][i]);
-      for(long i=0;i<c[ROt_ST];i++)
-        DrawString(textPos[col][i],texts[col][i],numtexts[col][i]);
-      c[ROt_PT]=c[ROt_LN]=c[ROt_BX]=c[ROt_ML]=c[ROt_ST]=0;
-    }
-}
-
-void Plotter::alloc() {
-    long *c;
-    plot_count(my_w, my_lw, rcolcnt);
-    for (int col = 1; col<MAX_COLORS; col++)
-    {
-      c = rcolcnt[col];
-      points[col]=new Point[c[ROt_PT]];
-      seg[col] = new Segment[c[ROt_LN]];
-      rec[col] = new Rectangle[c[ROt_BX]];
-      lines[col] = new Point*[c[ROt_ML]];
-      textPos[col] = new Point[c[ROt_ST]];
-      texts[col] = new String[c[ROt_ST]];
-      numpoints[col] = new long[c[ROt_ML]];
-      numtexts [col] = new long[c[ROt_ST]];
-    }
+  fl_font(FL_COURIER, int(pari_plot.fheight * xs));
+  fl_color(FL_WHITE); // transparent window on Windows otherwise
+  fl_rectf(0, 0, this->w(), this->h());
+  struct plot_eng plotfltk;
+  plotfltk.sc=&SetForeground;
+  plotfltk.pt=&DrawPoint;
+  plotfltk.ln=&DrawLine;
+  plotfltk.bx=&DrawRectangle;
+  plotfltk.mp=&DrawPoints;
+  plotfltk.ml=&DrawLines;
+  plotfltk.st=&DrawString;
+  plotfltk.pl=&pari_plot;
+  gen_rectdraw0(&plotfltk, color, w, x, y,lw,xs,ys);
 }
 
 int Plotter::handle(int event)

Attachment: patch.Qt
Description: QuickTime movie