aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorinmarket <inmarket@ugfx.org>2016-11-09 16:41:44 +1000
committerinmarket <inmarket@ugfx.org>2016-11-09 16:41:44 +1000
commit545a719db9f706d47d1135c5056faab82e22f230 (patch)
treef883cf9fa6bcc8f5aae4f22465f9c51cf4e44462
parent59917dbe1acd506fcde7a4a7485333c3125da7e1 (diff)
downloaduGFX-545a719db9f706d47d1135c5056faab82e22f230.tar.gz
uGFX-545a719db9f706d47d1135c5056faab82e22f230.tar.bz2
uGFX-545a719db9f706d47d1135c5056faab82e22f230.zip
New dual circle drawing in GDISP
-rw-r--r--docs/releases.txt1
-rw-r--r--gfxconf.example.h1
-rw-r--r--src/gdisp/gdisp.c77
-rw-r--r--src/gdisp/gdisp.h18
-rw-r--r--src/gdisp/gdisp_options.h8
5 files changed, 105 insertions, 0 deletions
diff --git a/docs/releases.txt b/docs/releases.txt
index 0e520252..1ff7828e 100644
--- a/docs/releases.txt
+++ b/docs/releases.txt
@@ -17,6 +17,7 @@ FIX: Fixing and improving arc rendering functions
FIX: Preventing possible crash when no valid GWIN default font has been set
FIX: Updating Windows binaries of the font encoder to improve compatibility
FIX: Fix Progressbar bounds checking and decrementing
+FEATURE: Added a dual circle with the same center drawing routine to GDISP
*** Release 2.6 ***
diff --git a/gfxconf.example.h b/gfxconf.example.h
index 79ca89b2..8b3a53b5 100644
--- a/gfxconf.example.h
+++ b/gfxconf.example.h
@@ -68,6 +68,7 @@
//#define GDISP_NEED_VALIDATION TRUE
//#define GDISP_NEED_CLIP TRUE
//#define GDISP_NEED_CIRCLE FALSE
+//#define GDISP_NEED_DUALCIRCLE FALSE
//#define GDISP_NEED_ELLIPSE FALSE
//#define GDISP_NEED_ARC FALSE
//#define GDISP_NEED_ARCSECTORS FALSE
diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c
index 691cab85..9e7c25e0 100644
--- a/src/gdisp/gdisp.c
+++ b/src/gdisp/gdisp.c
@@ -1347,6 +1347,83 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
}
#endif
+#if GDISP_NEED_DUALCIRCLE
+
+ #define DRAW_DUALLINE(yval, r1, r2) \
+ g->p.y = yval; \
+ g->p.x = x-r1; g->p.x1 = x-r2+1; hline_clip(g); \
+ g->p.x = x-r2; g->p.x1 = x+r2; g->p.color = color2; hline_clip(g); \
+ g->p.x = x+r2+1; g->p.x1 = x+r1; g->p.color = color1; hline_clip(g)
+ #define DRAW_SINGLELINE(yval, r) g->p.y = yval; g->p.x = x-r; g->p.x1 = x+r; hline_clip(g)
+
+ void gdispGFillDualCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius1, color_t color1, coord_t radius2, color_t color2) {
+ coord_t a, b1, b2, p1, p2;
+
+ MUTEX_ENTER(g);
+
+ // Do the combined circle where the inner circle < 45 deg (and outer circle)
+ g->p.color = color1;
+ a = 0; b1 = radius1; b2 = radius2; p1 = p2 = 1;
+ do {
+ DRAW_DUALLINE(y+a, b1, b2);
+ DRAW_DUALLINE(y-a, b1, b2);
+ if (p1 >= 0) p1 -= b1--;
+ p1 += a;
+ if (p2 >= 0) p2 -= b2--;
+ p2 += a;
+ } while(++a < b2);
+
+ // Do the combined circle where inner circle > 45 deg, outer circle < 45
+ do {
+ DRAW_DUALLINE(y+a, b1, b2);
+ DRAW_DUALLINE(y-a, b1, b2);
+ if (p1 >= 0) p1 -= b1--;
+ p1 += a;
+ do { p2 -= --b2; } while (p2+a >= b2);
+ p2 += a;
+ } while(++a <= radius2 && a < b1);
+
+ if (a < radius2) {
+ // Do the combined circle where inner circle > 45 deg, outer circle > 45
+ do {
+ DRAW_DUALLINE(y+a, b1, b2);
+ DRAW_DUALLINE(y-a, b1, b2);
+ do { p1 -= --b1; } while (p1+a >= b1);
+ p1 += a;
+ do { p2 -= --b2; } while (p2+a >= b2);
+ p2 += a++;
+ } while(b2 > 0);
+
+ } else {
+ // Do the outer circle above the inner circle but < 45 deg
+ do {
+ DRAW_SINGLELINE(y+a, b1);
+ DRAW_SINGLELINE(y-a, b1);
+ if (p1 >= 0) p1 -= b1--;
+ p1 += a++;
+ } while(a < b1);
+ DRAW_SINGLELINE(y+a, b1);
+ DRAW_SINGLELINE(y-a, b1);
+ }
+
+ // Do the top and bottom part of the outer circle (outer circle > 45deg and above inner circle)
+ a = 0; b1 = radius1; p1 = 1;
+ do {
+ if (p1 >= 0) {
+ DRAW_SINGLELINE(y+b1, a);
+ DRAW_SINGLELINE(y-b1, a);
+ p1 -= b1--;
+ }
+ p1 += a++;
+ } while(b1 > radius2 && a < b1);
+
+ autoflush(g);
+ MUTEX_EXIT(g);
+ }
+ #undef DRAW_DUALLINE
+ #undef DRAW_SINGLELINE
+#endif
+
#if GDISP_NEED_ELLIPSE
void gdispGDrawEllipse(GDisplay *g, coord_t x, coord_t y, coord_t a, coord_t b, color_t color) {
coord_t dx, dy;
diff --git a/src/gdisp/gdisp.h b/src/gdisp/gdisp.h
index 5cb91896..22ee8877 100644
--- a/src/gdisp/gdisp.h
+++ b/src/gdisp/gdisp.h
@@ -574,6 +574,24 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#define gdispFillCircle(x,y,r,c) gdispGFillCircle(GDISP,x,y,r,c)
#endif
+#if GDISP_NEED_DUALCIRCLE || defined(__DOXYGEN__)
+ /**
+ * @brief Draw two filled circles with the same centre.
+ * @pre GDISP_NEED_DUALCIRCLE must be TRUE in your gfxconf.h
+ *
+ * @param[in] g The display to use
+ * @param[in] x,y The center of the circle
+ * @param[in] radius1 The radius of the larger circle
+ * @param[in] color1 The color to use for the larger circle
+ * @param[in] radius2 The radius of the smaller circle
+ * @param[in] color2 The color to use for the smaller circle
+ *
+ * @api
+ */
+ void gdispGFillDualCircle(GDisplay *g, coord_t x, coord_t y, coord_t radius1, color_t color1, coord_t radius2, color_t color2);
+ #define gdispFillDualCircle(x,y,r,c) gdispGFillDualCircle(GDISP,x,y,r1,c1,r2,c2)
+#endif
+
/* Ellipse Functions */
#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
diff --git a/src/gdisp/gdisp_options.h b/src/gdisp/gdisp_options.h
index 4c004808..09502618 100644
--- a/src/gdisp/gdisp_options.h
+++ b/src/gdisp/gdisp_options.h
@@ -94,6 +94,14 @@
#define GDISP_NEED_CIRCLE FALSE
#endif
/**
+ * @brief Are dual circle functions needed (one circle inside another).
+ * @details Defaults to FALSE
+ * @note Uses integer algorithms only. It does not use any trig or floating point.
+ */
+ #ifndef GDISP_NEED_DUALCIRCLE
+ #define GDISP_NEED_DUALCIRCLE FALSE
+ #endif
+ /**
* @brief Are ellipse functions needed.
* @details Defaults to FALSE
* @note Uses integer algorithms only. It does not use any trig or floating point.