Skip to content

Commit

Permalink
Add drawEllipse() function
Browse files Browse the repository at this point in the history
  • Loading branch information
RossAdrian committed Aug 25, 2024
1 parent 5410174 commit c84af33
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 0 deletions.
34 changes: 34 additions & 0 deletions native/module_pyfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,39 @@ static PyObject* pyfunc_pyfb_sdrawCircle(PyObject* self, PyObject* args) {
return PyLong_FromLong(exitcode);
}

/**
* Python wrapper for the pyfb_drawEllipse function.
*
* @param self The function
* @param args The arguments, expecting long of the fbnum, long of the xm, long of the ym, long of the a, long of the b, long of the color
*
* @return Just 0
*/
static PyObject* pyfunc_pyfb_sdrawEllipse(PyObject* self, PyObject* args) {
unsigned char fbnum_c;
unsigned long int xm;
unsigned long int ym;
unsigned long int a;
unsigned long int b;
uint32_t color_val;

if(!PyArg_ParseTuple(args, "bkkkkI", &fbnum_c, &xm, &ym, &a, &b, &color_val)) {
PyErr_SetString(PyExc_TypeError, "Expecting arguments of type (byte, long, long, long, long, long)");
return NULL;
}

// now parse the color
struct pyfb_color color;
pyfb_initcolor_u32(&color, color_val);

// and invoke the target function
pyfb_sdrawEllipse((uint8_t)fbnum_c, xm, ym, a, b, &color);

// and return just 0
int exitcode = 0;
return PyLong_FromLong(exitcode);
}

// The module def

/**
Expand All @@ -268,6 +301,7 @@ static PyMethodDef pyfb_methods[] = {
{"pyfb_drawHorizontalLine", pyfunc_pyfb_sdrawHorizontalLine, METH_VARARGS, "Draw a horizontal line on the framebuffer"},
{"pyfb_drawVerticalLine", pyfunc_pyfb_sdrawVerticalLine, METH_VARARGS, "Draw a vertical line on the framebuffer"},
{"pyfb_drawCircle", pyfunc_pyfb_sdrawCircle, METH_VARARGS, "Draw a circle on the framebuffer"},
{"pyfb_drawEllipse", pyfunc_pyfb_sdrawEllipse, METH_VARARGS, "Draw a ellipse on the framebuffer"},
{"pyfb_flushBuffer", pyfunc_pyfb_flushBuffer, METH_VARARGS, "Flush the offscreen buffer to the framebuffer"},
{"pyfb_getResolution", pyfunc_pyfb_getResolution, METH_VARARGS, "Returns a tupel of the framebuffer resolution"},
{NULL, NULL, 0, NULL}};
Expand Down
74 changes: 74 additions & 0 deletions native/paint.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,80 @@ void pyfb_sdrawCircle(uint8_t fbnum,

pyfb_drawCircle(fbnum, xm, ym, radius, color);

// ready, so return
pyfb_fbunlock(fbnum);
}

void __APISTATUS_internal pyfb_drawEllipse(uint8_t fbnum,
unsigned long int xm,
unsigned long int ym,
unsigned long int a,
unsigned long int b,
struct pyfb_color* color) {
long int al = ULI_TO_LI(a);
long int bl = ULI_TO_LI(b);
long int dx = 0;
long int dy = bl;
long a2 = al * al;
long b2 = bl * bl;
long err = b2 - (2 * bl - 1) * a2;
long e2 = 0;

struct pyfb_videomode_info vinfo;
pyfb_vinfo(fbnum, &vinfo);

const long int xres = ULI_TO_LI(vinfo.vinfo.xres);
const long int yres = ULI_TO_LI(vinfo.vinfo.yres);

do {
SET_PIXEL_OR_IGNORE(fbnum, xm + dx, ym + dy, xres, yres, color);
SET_PIXEL_OR_IGNORE(fbnum, xm - dx, ym + dy, xres, yres, color);
SET_PIXEL_OR_IGNORE(fbnum, xm - dx, ym - dy, xres, yres, color);
SET_PIXEL_OR_IGNORE(fbnum, xm + dx, ym - dy, xres, yres, color);
e2 = 2 * err;

if(e2 < (2 * dx + 1) * b2) {
++dx;
err += (2 * dx + 1) * b2;
}

if(e2 > -(2 * dy - 1) * a2) {
--dy;
err -= (2 * dy - 1) * a2;
}
} while(dy >= 0);

while(dx++ < a) {
SET_PIXEL_OR_IGNORE(fbnum, xm + dx, ym, xres, yres, color);
SET_PIXEL_OR_IGNORE(fbnum, xm - dx, ym, xres, yres, color);
}
}

void pyfb_sdrawEllipse(uint8_t fbnum,
unsigned long int xm,
unsigned long int ym,
unsigned long int a,
unsigned long int b,
struct pyfb_color* color) {
// fist check if fbnum is valid
if(fbnum >= MAX_FRAMEBUFFERS) {
PyErr_SetString(PyExc_ValueError, "The framebuffer number is not valid");
return;
}

// Ok, then lock
pyfb_fblock(fbnum);

// next test, if the device is in use
if(!pyfb_fbused(fbnum)) {
// this framebuffer is not in use, so reject
PyErr_SetString(PyExc_IOError, "The framebuffer is not opened");
pyfb_fbunlock(fbnum);
return;
}

pyfb_drawEllipse(fbnum, xm, ym, a, b, color);

// ready, so return
pyfb_fbunlock(fbnum);
}
34 changes: 34 additions & 0 deletions native/pyframebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,40 @@ extern void __APISTATUS_internal pyfb_drawCircle(uint8_t fbnum,
unsigned long int radius,
struct pyfb_color* color);

/**
* Safe version to draw a ellipse on the screen.
*
* @param fbnum The framebuffer number
* @param xm The x coordinate of the middle point
* @param ym The y coordinate of the middle point
* @param a The long half axis
* @param b The short half axis
* @param color The color value
*/
extern void pyfb_sdrawEllipse(uint8_t fbnum,
unsigned long int xm,
unsigned long int ym,
unsigned long int a,
unsigned long int b,
struct pyfb_color* color);

/**
* Unsafe version to draw a ellipse on the screen.
*
* @param fbnum The framebuffer number
* @param xm The x coordinate of the middle point
* @param ym The y coordinate of the middle point
* @param a The long half axis
* @param b The short half axis
* @param color The color value
*/
extern void __APISTATUS_internal pyfb_drawEllipse(uint8_t fbnum,
unsigned long int xm,
unsigned long int ym,
unsigned long int a,
unsigned long int b,
struct pyfb_color* color);

/**
* Paints the content of the offscreen buffer to the framebuffer. This function must be callen
* because this is the only operation that is required to paint the content of the offscreen
Expand Down
13 changes: 13 additions & 0 deletions pyframebuffer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,19 @@ def drawCircle(self, xm, ym, radius, color):
color = getColorValue(color)
fb.pyfb_drawCircle(self.fbnum, xm, ym, radius, color)

def drawEllipse(self, xm, ym, a, b, color):
"""
Draws a ellipse on the offscreen buffer.
@param xm The x coordinate of the middle
@param ym The y coordinate of the middle
@param a The long half axis
@param b The short half axis
@param color The color value
"""
color = getColorValue(color)
fb.pyfb_drawEllipse(self.fbnum, xm, ym, a, b, color)


def openfb(num):
"""
Expand Down

0 comments on commit c84af33

Please sign in to comment.