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