This is a patch to allow Pgui to draw ellipses in PGFX.  I implemented two
 different algorithms, and have left them both, one is used to draw  "unfilled" 
ellipses,
 the other is used to draw filled ellipses.  The one that 
draws filled ellipses is more advanced and faster.  But the one that does the 
"unfilled ellipses" used to be able to draw larger ellipses and is arguably 
more elegant looking.  (I don't really know how large an elipse they could 
draw now, they each draw larger than 640,480, the constraint on the second algo 
is the "dd" variable if you want to check it out)  I wanted to leave both in for you
guys to look at, and see which one performs better on your target platforms.  I
didn't optimize the one for the unfilled ellipses very much though, if you're planning
on testing it, I'll go in and do some static differential seperation stuff.

I spent a couple hours hunched over my HS calc book and the De Silva abstract,
so please let me know if you make any optimizations to it.

ChangeLog Entry:

2001-05-30    Shane Nay <[EMAIL PROTECTED]>

Added ellipse, and filled elipse drawing to pgfx for use on canvases.

      * pgserver/gcore/render.c: Added the mapping for rendering of ellipses.
      * pgserver/include/pgserver/video.h: Added function pointers for fellipse
         and ellipse to struct vidlib.
      * pgserver/include/picogui/constants.h: Added PG_GROP_ELLIPSE and
         PG_GROP_FELLIPSE.
      * pgserver/vidbase/defaultvbl.c: Added def_ellipse & def_fellipse.  Nicely
         optimized, with personal permanent loss of several IQ points caused by
         over exposure.  :)

Here's the pgserver patch:

Index: gcore/render.c
===================================================================
RCS file: /cvsroot/pgui/pgserver/gcore/render.c,v
retrieving revision 1.4
diff -u -r1.4 render.c
--- gcore/render.c      2001/05/05 20:54:16     1.4
+++ gcore/render.c      2001/05/31 02:32:42
@@ -679,6 +679,26 @@
                     n->param[2],
                     r->lgop);      
       break;
+   case PG_GROP_ELLIPSE:
+     VID(ellipse) (r->output,
+                  n->r.x,
+                  n->r.y,
+                  n->r.w,
+                  n->r.h,
+                  c,
+                  r->lgop
+                  );
+     break;
+   case PG_GROP_FELLIPSE:
+     VID(fellipse) (r->output,
+                   n->r.x,
+                   n->r.y,
+                   n->r.w,
+                   n->r.h,
+                   c,
+                   r->lgop
+                   );
+     break;
     }
 }
 
Index: include/pgserver/video.h
===================================================================
RCS file: /cvsroot/pgui/pgserver/include/pgserver/video.h,v
retrieving revision 1.40
diff -u -r1.40 video.h
--- include/pgserver/video.h    2001/05/13 06:04:13     1.40
+++ include/pgserver/video.h    2001/05/31 02:32:43
@@ -299,6 +299,9 @@
   void (*charblit)(hwrbitmap dest, u8 *chardat, s16 x, s16 y, s16 w, s16 h,
                   s16 lines, s16 angle, hwrcolor c, struct quad *clip,
                   bool fill, hwrcolor bg, s16 lgop);
+
+  void (*ellipse) (hwrbitmap dest, s16 x, s16 y, s16 w, s16 h, hwrcolor c, s16 lgop);
+  void (*fellipse) (hwrbitmap dest, s16 x, s16 y, s16 w, s16 h, hwrcolor c, s16 lgop);
    
   /***************** Bitmaps */
 
Index: include/picogui/constants.h
===================================================================
RCS file: /cvsroot/pgui/pgserver/include/picogui/constants.h,v
retrieving revision 1.55
diff -u -r1.55 constants.h
--- include/picogui/constants.h 2001/05/17 04:50:29     1.55
+++ include/picogui/constants.h 2001/05/31 02:32:44
@@ -534,6 +534,8 @@
 #define PG_GROP_BAR        0x30   
 #define PG_GROP_PIXEL      0x40
 #define PG_GROP_LINE              0x50
+#define PG_GROP_ELLIPSE    0x60
+#define PG_GROP_FELLIPSE   0x70
 #define PG_GROP_TEXT       0x04   //!< Param: string 
 #define PG_GROP_BITMAP     0x14   //!< Param: bitmap 
 #define PG_GROP_TILEBITMAP 0x24   //!< Param: bitmap 
Index: vidbase/defaultvbl.c
===================================================================
RCS file: /cvsroot/pgui/pgserver/vidbase/defaultvbl.c,v
retrieving revision 1.39
diff -u -r1.39 defaultvbl.c
--- vidbase/defaultvbl.c        2001/05/10 04:12:28     1.39
+++ vidbase/defaultvbl.c        2001/05/31 02:32:44
@@ -391,6 +391,111 @@
   for (;h;h--,y++) (*vid->slab) (dest,x,y,w,c,lgop);
 }
 
+#define SYMMETRY(X,Y) (*vid->pixel) (dest,xoff+X,yoff+Y,c,lgop); \
+                      (*vid->pixel) (dest,xoff-X,yoff+Y,c,lgop); \
+                      (*vid->pixel) (dest,xoff-X,yoff-Y,c,lgop); \
+                      (*vid->pixel) (dest,xoff+X,yoff-Y,c,lgop)
+
+void def_ellipse(hwrbitmap dest, s16 x, s16 y, s16 w, s16 h, hwrcolor c, s16 lgop) {
+  s16 xoff, yoff;
+  int w2, h2, S, T;
+  w=--w>>1;
+  h=--h>>1;
+  w2 = w*w;
+  h2 = h*h;
+  S = w2*(1-(h<<1)) + (h2<<1);
+  T = h2 - (w2*((h<<1)-1)<<1);
+  xoff=x+w;
+  yoff=y+h;
+  x=0;
+  y=h;
+  do
+    {
+      if (S<0)
+       {
+         S += h2*((x<<1)+3)<<1;
+         T += h2*(x+1)<<2;
+         x++;
+       }
+      else if (T<0)
+       {
+         S += (h2*((x<<1)+3)<<1) - (w2*(y-1)<<2);
+         T += (h2*(x+1)<<2) - (w2*((y<<1)-3)<<1);
+         x++;
+         y--;
+       }
+      else
+       {
+         S -= w2*(y-1)<<2;
+         T -= w2*((y<<1)-3)<<1;
+         y--;
+       }
+      SYMMETRY(x,y);
+
+    }
+  while (y>0);
+}
+#undef SYMMETRY
+
+
+#define SYMLINE(X,Y)  (*vid->slab) (dest,xoff-X,yoff+Y,(X<<1)+1,c,lgop); \
+                      (*vid->slab) (dest,xoff-X,yoff-Y,(X<<1)+1,c,lgop)
+/* De Silva elliptical drawing algorithm, with lots of other optimizations :) */
+
+void def_fellipse(hwrbitmap dest, s16 x, s16 y, s16 w, s16 h, hwrcolor c, s16 lgop) {
+  s16 xoff, yoff;
+  long int conda, condb, ddinc0, ddinc1;
+  /* Change following var's to long long if you want to draw *huge* ellipses */
+  long int dd, w22, h22, w2, h2;
+  w=--w>>1;
+  h=--h>>1;
+  w2 = w*w;
+  h2 = h*h;
+  w22 = w2<<1;
+  h22 = h2<<1;
+  xoff=x+w;
+  yoff=y+h;
+  x=0;
+  y=h;
+  ddinc0=(h2<<1)+h2;
+  ddinc1=(2-(y<<1))*w2;
+  dd=h2-w2*h+h2>>2;
+  conda=w2*y-(w2>>1);
+  condb=h2;
+  while(conda>condb) {
+    if(dd>=0) {
+      dd+=ddinc1;
+      conda-=w2;
+      y--;
+      ddinc1+=w22;
+    }
+    dd+=ddinc0;
+    x++;
+    condb+=h2;
+    ddinc0+=h22;
+    SYMLINE(x,y);
+  }
+  if(h2 > 10000 && w2 > 10000) { /* Get around using long long */
+    dd=(((h2>>6)*((x<<1)+1)*((x<<1)+1))>>2) + ((w2>>6)*(y-1)*(y-1) - (w2>>6)*h2);
+    dd=dd<<6;
+  }
+  else
+    dd=((h2*((x<<1)+1)*((x<<1)+1))>>2) + (w2*(y-1)*(y-1) - w2*h2);
+  ddinc0=w2*(3-(y<<1));
+  ddinc1=h2*((x<<1)+2);
+  while (y>0) {
+    if(dd<0) {
+      dd += ddinc1;
+      x++;
+      ddinc1+=h22;
+    }
+    dd += ddinc0;
+    y--;
+    ddinc0+=w22;
+  }
+}
+#undef SYMLINE
+
 void def_gradient(hwrbitmap dest,s16 x,s16 y,s16 w,s16 h,s16 angle,
                  pgcolor c1, pgcolor c2, s16 lgop) {
   /*
@@ -1279,6 +1384,8 @@
   vid->gradient = &def_gradient;
   vid->charblit = &def_charblit;
   vid->tileblit = &def_tileblit;
+  vid->ellipse = &def_ellipse;
+  vid->fellipse = &def_fellipse;
 #ifdef CONFIG_FORMAT_XBM
   vid->bitmap_loadxbm = &def_bitmap_loadxbm;
 #endif

_______________________________________________
Pgui-devel mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/pgui-devel

Reply via email to