Added new arc sector drawing routines (Thanks to steved for the inspiration).

Added demo to match.
ugfx_release_2.6
inmarket 2014-10-27 16:44:53 +10:00
parent cb668266b5
commit 3825cec8f8
6 changed files with 494 additions and 16 deletions

View File

@ -0,0 +1,3 @@
DEMODIR = $(GFXLIB)/demos/modules/gdisp/arcsectors
GFXINC += $(DEMODIR)
GFXSRC += $(DEMODIR)/main.c

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* The operating system to use. One of these must be defined - preferably in your Makefile */
//#define GFX_USE_OS_CHIBIOS FALSE
//#define GFX_USE_OS_WIN32 FALSE
//#define GFX_USE_OS_LINUX FALSE
//#define GFX_USE_OS_OSX FALSE
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GINPUT TRUE
#define GFX_USE_GEVENT TRUE
#define GFX_USE_GTIMER TRUE
/* Features for the GDISP subsystem. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_ARCSECTORS TRUE
#define GINPUT_NEED_MOUSE TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gfx.h"
GListener gl;
int main(void) {
coord_t width, height, r1, r2, cx, cy;
uint8_t sectors;
GEventMouse *pme;
// Initialize and clear the display
gfxInit();
// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();
r1 = width > height ? height/3 : width/3;
r2 = r1*3/4;
cx = width/2;
cy = height/2;
sectors = 1;
// We want to listen for mouse button events
geventListenerInit(&gl);
geventAttachSource(&gl, ginputGetMouse(0), GLISTEN_MOUSEMETA);
while(1) {
// Draw the arc sectors
gdispClear(White);
gdispDrawArcSectors(cx, cy, r1, sectors, Blue);
gdispFillArcSectors(cx, cy, r2, sectors, Red);
// Get an Event
pme = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
// Change our sectors based on the event.
switch(pme->type) {
case GEVENT_MOUSE:
case GEVENT_TOUCH:
if (pme->buttons & GMETA_MOUSE_CLICK)
sectors++;
else if (pme->buttons & GMETA_MOUSE_CXTCLICK)
sectors--;
break;
}
}
}

View File

@ -31,11 +31,12 @@ FIX: Improve memory usage for the GWIN Frame widget.
FEATURE: Added transparent custom draws for GWIN containers and frame widgets
FEATURE: Added image custom draws for GWIN containers and frame widgets
FEATURE: Added GDRIVER infrastructure. Ported GDISP to use it.
FEATURE: Added gdispDrawArcSectors() and gdispFillArcSectors().
*** Release 2.1 ***
FIX: Significant improvements to the way the MCU touch driver works.
FEATURE: Add support for edge to edge touch calibration.
FEATURE: Add support for edge to edge touch calibration.
FEATURE: Added progressbar widget
FEATURE: Added gdispGDrawThickLine() by user jpa-
DEPRECATE: TDISP module removed
@ -78,7 +79,7 @@ FEATURE: GDISP Streaming API and demos.
DEPRECATE: GDISP_NEED_ASYNC is now deprecated.
DEPRECATE: 3rd party boing demo is now deprecated (replaced by GDISP Streaming demo)
FIX: Remove GOS definitions from demo conf files so that it can be supplied by a makefile.
FEATURE: Repair GDISP low level driver interfaces so they can now be included in the doxygen documentation.
FEATURE: Repair GDISP low level driver interfaces so they can now be included in the doxygen documentation.
FEATURE: New driver interface for GDISP
FEATURE: Multiple display support
FEATURE: Multiple controller support

View File

@ -1420,8 +1420,233 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
}
#endif
#if GDISP_NEED_ARCSECTORS
void gdispGDrawArcSectors(GDisplay *g, coord_t x, coord_t y, coord_t radius, uint8_t sectors, color_t color) {
coord_t a, b, P;
MUTEX_ENTER(g);
// Calculate intermediates
a = 1; // x in many explanations
b = radius; // y in many explanations
P = 4 - radius;
g->p.color = color;
// Away we go using Bresenham's circle algorithm
// Optimized to prevent double drawing
if (sectors & 0x06) { g->p.x = x; g->p.y = y - b; drawpixel_clip(g); } // Upper upper
if (sectors & 0x60) { g->p.x = x; g->p.y = y + b; drawpixel_clip(g); } // Lower lower
if (sectors & 0x81) { g->p.x = x + b; g->p.y = y; drawpixel_clip(g); } // Right right
if (sectors & 0x18) { g->p.x = x - b; g->p.y = y; drawpixel_clip(g); } // Left left
do {
if (sectors & 0x01) { g->p.x = x + b; g->p.y = y - a; drawpixel_clip(g); } // Upper right right
if (sectors & 0x02) { g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g); } // Upper upper right
if (sectors & 0x04) { g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g); } // Upper upper left
if (sectors & 0x08) { g->p.x = x - b; g->p.y = y - a; drawpixel_clip(g); } // Upper left left
if (sectors & 0x10) { g->p.x = x - b; g->p.y = y + a; drawpixel_clip(g); } // Lower left left
if (sectors & 0x20) { g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g); } // Lower lower left
if (sectors & 0x40) { g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g); } // Lower lower right
if (sectors & 0x80) { g->p.x = x + b; g->p.y = y + a; drawpixel_clip(g); } // Lower right right
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
if (sectors & 0xC0) { g->p.x = x + a; g->p.y = y + b; drawpixel_clip(g); } // Lower right
if (sectors & 0x03) { g->p.x = x + a; g->p.y = y - b; drawpixel_clip(g); } // Upper right
if (sectors & 0x30) { g->p.x = x - a; g->p.y = y + b; drawpixel_clip(g); } // Lower left
if (sectors & 0x0C) { g->p.x = x - a; g->p.y = y - b; drawpixel_clip(g); } // Upper left
autoflush(g);
MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARCSECTORS
void gdispGFillArcSectors(GDisplay *g, coord_t x, coord_t y, coord_t radius, uint8_t sectors, color_t color) {
coord_t a, b, P;
MUTEX_ENTER(g);
// Calculate intermediates
a = 1; // x in many explanations
b = radius; // y in many explanations
P = 4 - radius;
g->p.color = color;
// Away we go using Bresenham's circle algorithm
// Optimized to prevent double drawing
if (sectors & 0x06) { g->p.x = x; g->p.y = y - b; drawpixel_clip(g); } // Upper upper
if (sectors & 0x60) { g->p.x = x; g->p.y = y + b; drawpixel_clip(g); } // Lower lower
if (sectors & 0x81) { // Center right
g->p.y = y; g->p.x = x; g->p.x1 = x + b;
if (sectors & 0x18) g->p.x -= b; // Left right
hline_clip(g);
} else if (sectors & 0x18) { // Left center
g->p.x = x - b; g->p.x1 = x; g->p.y = y;
hline_clip(g);
}
do {
// Top half
switch(sectors & 0x0F) {
case 0x01:
g->p.y = y - a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x02:
g->p.y = y - b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
break;
case 0x03:
g->p.y = y - b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x; g->p.x1 = x + b; hline_clip(g);
break;
case 0x04:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
break;
case 0x05:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x06:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
break;
case 0x07:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x08:
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
break;
case 0x09:
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y - a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0A:
g->p.y = y - b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y - a; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
break;
case 0x0B:
g->p.y = y - b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y - a; g->p.x = x; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0C:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x; hline_clip(g);
break;
case 0x0D:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x; hline_clip(g);
g->p.y = y - a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0E:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x + a; hline_clip(g);
break;
case 0x0F:
g->p.y = y - b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y - a; g->p.x = x - b; g->p.x1 = x + b; hline_clip(g);
break;
}
// Bottom half
switch((sectors & 0xF0)>>4) {
case 0x01:
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
break;
case 0x02:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
break;
case 0x03:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x; hline_clip(g);
break;
case 0x04:
g->p.y = y + b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
break;
case 0x05:
g->p.y = y + b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y + a; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
break;
case 0x06:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
break;
case 0x07:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x + a; hline_clip(g);
break;
case 0x08:
g->p.y = y + a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x09:
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y + a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0A:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0B:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x; hline_clip(g);
g->p.y = y + a; g->p.x = x + a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0C:
g->p.y = y + b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0D:
g->p.y = y + b; g->p.x = x; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x - a; hline_clip(g);
g->p.y = y + a; g->p.x = x; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0E:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - a; g->p.x1 = x + b; hline_clip(g);
break;
case 0x0F:
g->p.y = y + b; g->p.x = x - a; g->p.x1 = x + a; hline_clip(g);
g->p.y = y + a; g->p.x = x - b; g->p.x1 = x + b; hline_clip(g);
break;
}
if (P < 0)
P += 3 + 2*a++;
else
P += 5 + 2*(a++ - b--);
} while(a < b);
// Top half
if (sectors & 0x02) { g->p.y = y - a; g->p.x = x; g->p.x1 = x + a; hline_clip(g); }
else if (sectors & 0x01) { g->p.y = y - a; g->p.x = x + a; drawpixel_clip(g); }
if (sectors & 0x04) { g->p.y = y - a; g->p.x = x - a; g->p.x1 = x; hline_clip(g); }
else if (sectors & 0x08) { g->p.y = y - a; g->p.x = x - a; drawpixel_clip(g); }
// Bottom half
if (sectors & 0x40) { g->p.y = y + a; g->p.x = x; g->p.x1 = x + a; hline_clip(g); }
else if (sectors & 0x80) { g->p.y = y + a; g->p.x = x + a; drawpixel_clip(g); }
if (sectors & 0x20) { g->p.y = y + a; g->p.x = x - a; g->p.x1 = x; hline_clip(g); }
else if (sectors & 0x10) { g->p.y = y + a; g->p.x = x - a; drawpixel_clip(g); }
autoflush(g);
MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARC
#if !GMISC_NEED_FIXEDTRIG && !GMISC_NEED_FASTTRIG
#if (!GMISC_NEED_FIXEDTRIG && !GMISC_NEED_FASTTRIG) || !GFX_USE_GMISC
#include <math.h>
#endif
@ -2102,27 +2327,34 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
autoflush(g);
MUTEX_EXIT(g);
}
#endif
#if GDISP_NEED_ARC
#if GDISP_NEED_ARC || GDISP_NEED_ARCSECTORS
void gdispGDrawRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
if (2*radius > cx || 2*radius > cy) {
gdispGDrawBox(g, x, y, cx, cy, color);
return;
}
gdispGDrawArc(g, x+radius, y+radius, radius, 90, 180, color);
#if GDISP_NEED_ARCSECTORS
gdispGFillArcSectors(g, x+radius, y+radius, radius, 0x0C, color);
gdispGFillArcSectors(g, x+cx-1-radius, y+radius, radius, 0x03, color);
gdispGFillArcSectors(g, x+cx-1-radius, y+cy-1-radius, radius, 0xC0, color);
gdispGFillArcSectors(g, x+radius, y+cy-1-radius, radius, 0x30, color);
#else
gdispGDrawArc(g, x+radius, y+radius, radius, 90, 180, color);
gdispGDrawArc(g, x+cx-1-radius, y+radius, radius, 0, 90, color);
gdispGDrawArc(g, x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
gdispGDrawArc(g, x+radius, y+cy-1-radius, radius, 180, 270, color);
#endif
gdispGDrawLine(g, x+radius+1, y, x+cx-2-radius, y, color);
gdispGDrawArc(g, x+cx-1-radius, y+radius, radius, 0, 90, color);
gdispGDrawLine(g, x+cx-1, y+radius+1, x+cx-1, y+cy-2-radius, color);
gdispGDrawArc(g, x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
gdispGDrawLine(g, x+radius+1, y+cy-1, x+cx-2-radius, y+cy-1, color);
gdispGDrawArc(g, x+radius, y+cy-1-radius, radius, 180, 270, color);
gdispGDrawLine(g, x, y+radius+1, x, y+cy-2-radius, color);
}
#endif
#if GDISP_NEED_ARC
#if GDISP_NEED_ARC || GDISP_NEED_ARCSECTORS
void gdispGFillRoundedBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t radius, color_t color) {
coord_t radius2;
@ -2131,12 +2363,19 @@ void gdispGBlitArea(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, c
gdispGFillArea(g, x, y, cx, cy, color);
return;
}
gdispGFillArc(g, x+radius, y+radius, radius, 90, 180, color);
#if GDISP_NEED_ARCSECTORS
gdispGFillArcSectors(g, x+radius, y+radius, radius, 0x0C, color);
gdispGFillArcSectors(g, x+cx-1-radius, y+radius, radius, 0x03, color);
gdispGFillArcSectors(g, x+cx-1-radius, y+cy-1-radius, radius, 0xC0, color);
gdispGFillArcSectors(g, x+radius, y+cy-1-radius, radius, 0x30, color);
#else
gdispGFillArc(g, x+radius, y+radius, radius, 90, 180, color);
gdispGFillArc(g, x+cx-1-radius, y+radius, radius, 0, 90, color);
gdispGFillArc(g, x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
gdispGFillArc(g, x+radius, y+cy-1-radius, radius, 180, 270, color);
#endif
gdispGFillArea(g, x+radius+1, y, cx-radius2, radius, color);
gdispGFillArc(g, x+cx-1-radius, y+radius, radius, 0, 90, color);
gdispGFillArc(g, x+cx-1-radius, y+cy-1-radius, radius, 270, 360, color);
gdispGFillArea(g, x+radius+1, y+cy-radius, cx-radius2, radius, color);
gdispGFillArc(g, x+radius, y+cy-1-radius, radius, 180, 270, color);
gdispGFillArea(g, x, y+radius, cx, cy-radius2, color);
}
#endif

View File

@ -430,6 +430,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Start a streaming operation.
* @details Stream data to a window on the display sequentially and very fast.
* @pre GDISP_NEED_STREAMING must be TRUE in your gfxconf.h
* @note While streaming is in operation - no other calls to GDISP functions
* can be made (with the exception of @p gdispBlendColor() and streaming
* functions). If a call is made (eg in a multi-threaded application) the other
@ -456,6 +457,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Send pixel data to the stream.
* @details Write a pixel to the next position in the streamed area and increment the position
* @pre GDISP_NEED_STREAMING must be TRUE in your gfxconf.h
* @pre @p gdispStreamStart() has been called.
* @note If the gdispStreamStart() has not been called (or failed due to clipping), the
* data provided here is simply thrown away.
@ -471,6 +473,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Finish the current streaming operation.
* @details Completes the current streaming operation and allows other GDISP calls to operate again.
* @pre GDISP_NEED_STREAMING must be TRUE in your gfxconf.h
* @pre @p gdispStreamStart() has been called.
* @note If the gdispStreamStart() has not been called (or failed due to clipping), this
* call is simply ignored.
@ -488,6 +491,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_CLIP || defined(__DOXYGEN__)
/**
* @brief Clip all drawing to the defined area.
* @pre GDISP_NEED_CLIP must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The start position
@ -504,6 +508,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_CIRCLE || defined(__DOXYGEN__)
/**
* @brief Draw a circle.
* @pre GDISP_NEED_CIRCLE must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The center of the circle
@ -517,6 +522,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a filled circle.
* @pre GDISP_NEED_CIRCLE must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The center of the circle
@ -534,6 +540,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_ELLIPSE || defined(__DOXYGEN__)
/**
* @brief Draw an ellipse.
* @pre GDISP_NEED_ELLIPSE must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The center of the ellipse
@ -547,6 +554,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a filled ellipse.
* @pre GDISP_NEED_ELLIPSE must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The center of the ellipse
@ -560,10 +568,70 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#endif
/* Arc Functions */
#if GDISP_NEED_ARCSECTORS || defined(__DOXYGEN__)
/**
* @brief Draw a selection of 45 degree arcs of a circle
* @pre GDISP_NEED_ARCSECTORS 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] radius The radius of the circle
* @param[in] sectors Bits determine which sectors are drawn.
* Bits go anti-clockwise from the 0 degree mark (y = 0, x is positive), as follows:
* bit 0 - upper right right -----
* bit 1 - upper upper right /2 1\
* bit 2 - upper upper left /3 0\
* bit 3 - upper left left \4 7/
* bit 4 - lower left left \5 6/
* bit 5 - lower lower left -----
* bit 6 - lower lower right
* bit 7 - lower left left
* @param[in] color The color to use
*
* @note This is a more limited versions of the general arc drawing routine. It
* doesn't require trig libraries or tables or floating point and is smaller in code size.
* There is probably little point in including both this and the general
* arc routine as the general arc routine can do everything this can do.
*
* @api
*/
void gdispGDrawArcSectors(GDisplay *g, coord_t x, coord_t y, coord_t radius, uint8_t sectors, color_t color);
#define gdispDrawArcSectors(x,y,r,s,c) gdispGDrawArcSectors(GDISP,x,y,r,s,c)
/**
* @brief Fill a selection of 45 degree arcs of a circle
* @pre GDISP_NEED_ARCSECTORS 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] radius The radius of the circle
* @param[in] sectors Bits determine which sectors are drawn.
* Bits go anti-clockwise from the 0 degree mark (y = 0, x is positive), as follows:
* bit 0 - upper right right -----
* bit 1 - upper upper right /2 1\
* bit 2 - upper upper left /3 0\
* bit 3 - upper left left \4 7/
* bit 4 - lower left left \5 6/
* bit 5 - lower lower left -----
* bit 6 - lower lower right
* bit 7 - lower left left
* @param[in] color The color to use
*
* @note This is a more limited versions of the general arc filling routine. It
* doesn't require trig libraries or tables or floating point and is smaller in code size.
* There is probably little point in including both this and the general
* arc routine as the general arc routine can do everything this can do.
*
* @api
*/
void gdispGFillArcSectors(GDisplay *g, coord_t x, coord_t y, coord_t radius, uint8_t sectors, color_t color);
#define gdispFillArcSectors(x,y,r,s,c) gdispGFillArcSectors(GDISP,x,y,r,s,c)
#endif
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
/*
* @brief Draw an arc.
* @pre GDISP_NEED_ARC must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x0,y0 The center point
@ -572,6 +640,15 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* @param[in] end The end angle (0 to 360)
* @param[in] color The color of the arc
*
* @note If you are just doing 45 degree angles consider using @p gdispDrawArcSectors() instead.
* @note This routine requires trig support. It can either come from your C runtime library
* cos() and sin() which requires floating point support (and is slow), or you can define GFX_USE_GMISC
* and either GMISC_NEED_FIXEDTRIG or GMISC_NEED_FASTTRIG.
* GMISC_NEED_FASTTRIG uses table based floating point trig operations.
* GMISC_NEED_FIXEDTRIG uses fixed point integer trig operations.
* Note accuracy on both the table based options are more than adequate for the one degree
* resolution provided by these arc routines. Both are much faster than your C runtime library.
*
* @api
*/
void gdispGDrawArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
@ -579,7 +656,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/*
* @brief Draw a filled arc.
* @note Not very efficient currently - does lots of overdrawing
* @pre GDISP_NEED_ARC must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x0,y0 The center point
@ -588,6 +665,15 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* @param[in] end The end angle (0 to 360)
* @param[in] color The color of the arc
*
* @note If you are just doing 45 degree angles consider using @p gdispFillArcSectors() instead.
* @note This routine requires trig support. It can either come from your C runtime library
* cos() and sin() which requires floating point support (and is slow), or you can define GFX_USE_GMISC
* and either GMISC_NEED_FIXEDTRIG or GMISC_NEED_FASTTRIG.
* GMISC_NEED_FASTTRIG uses table based floating point trig operations.
* GMISC_NEED_FIXEDTRIG uses fixed point integer trig operations.
* Note accuracy on both the table based options are more than adequate for the one degree
* resolution provided by these arc routines. Both are much faster than your C runtime library.
*
* @api
*/
void gdispGFillArc(GDisplay *g, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
@ -600,6 +686,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Get the color of a pixel.
* @return The color of the pixel.
* @pre GDISP_NEED_PIXELREAD must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position of the pixel
@ -636,6 +723,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_CONTROL || defined(__DOXYGEN__)
/**
* @brief Control hardware specific parts of the display. eg powermodes, backlight etc
* @pre GDISP_NEED_CONTROL must be TRUE in your gfxconf.h
* @note Depending on the hardware implementation this function may not
* support some codes. They will be ignored.
*
@ -654,6 +742,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_QUERY || defined(__DOXYGEN__)
/**
* @brief Query a property of the display.
* @pre GDISP_NEED_QUERY must be TRUE in your gfxconf.h
* @note The result must be typecast to the correct type.
* @note An unsupported query will return (void *)-1.
*
@ -669,6 +758,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_CONVEX_POLYGON || defined(__DOXYGEN__)
/**
* @brief Draw an enclosed polygon (convex, non-convex or complex).
* @pre GDISP_NEED_CONVEX_POLYGON must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
@ -684,6 +774,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Fill a convex polygon
* @details Doesn't handle non-convex or complex polygons.
* @pre GDISP_NEED_CONVEX_POLYGON must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] tx, ty Transform all points in pntarray by tx, ty
@ -708,6 +799,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* @brief Draw a line with a specified thickness
* @details The line thickness is specified in pixels. The line ends can
* be selected to be either flat or round.
* @pre GDISP_NEED_CONVEX_POLYGON must be TRUE in your gfxconf.h
* @note Uses gdispGFillConvexPoly() internally to perform the drawing.
*
* @param[in] g The display to use
@ -728,6 +820,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
/**
* @brief Draw a text character.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position for the text
@ -742,6 +835,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a text character with a filled background.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position for the text
@ -757,6 +851,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a text string.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position for the text
@ -771,6 +866,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a text string.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position for the text
@ -786,6 +882,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a text string vertically centered within the specified box.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The position for the text (need to define top-right or base-line - check code)
@ -802,6 +899,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a text string vertically centered within the specified box. The box background is filled with the specified background color.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
* @note The entire box is filled
*
* @param[in] g The display to use
@ -821,6 +919,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Get a metric of a font.
* @return The metric requested in pixels.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] font The font to test
* @param[in] metric The metric to measure
@ -832,6 +931,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Get the pixel width of a character.
* @return The width of the character in pixels. Does not include any between character padding.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] c The character to draw
* @param[in] font The font to use
@ -843,6 +943,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Get the pixel width of a string.
* @return The width of the string in pixels.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] str The string to measure
* @param[in] font The font to use
@ -855,6 +956,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* @brief Find a font and return it.
* @details The supplied name is matched against the font name. A '*' will replace 0 or more characters.
* @return Returns a font or NULL if no matching font could be found.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] name The font name to find.
*
@ -866,6 +968,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Release a font after use.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] font The font to release.
*
@ -877,6 +980,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
* @brief Make a scaled copy of an existing font.
* @details Allocates memory for new font metadata using gfxAlloc, remember to close font after use!
* @return A new font or NULL if out of memory.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] font The base font to use.
* @param[in] scale_x The scale factor in horizontal direction.
@ -887,6 +991,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Get the name of the specified font.
* @returns The name of the font.
* @pre GDISP_NEED_TEXT must be TRUE in your gfxconf.h
*
* @param[in] font The font to get the name for.
*
@ -897,9 +1002,10 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/* Extra Arc Functions */
#if GDISP_NEED_ARC || defined(__DOXYGEN__)
#if GDISP_NEED_ARC || GDISP_NEED_ARCSECTORS || defined(__DOXYGEN__)
/**
* @brief Draw a rectangular box with rounded corners
* @pre GDISP_NEED_ARC or GDISP_NEED_ARCSECTORS must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The start position
@ -914,6 +1020,7 @@ void gdispGDrawBox(GDisplay *g, coord_t x, coord_t y, coord_t cx, coord_t cy, co
/**
* @brief Draw a filled rectangular box with rounded corners
* @pre GDISP_NEED_ARC or GDISP_NEED_ARCSECTORS must be TRUE in your gfxconf.h
*
* @param[in] g The display to use
* @param[in] x,y The start position