Skip to content

Commit

Permalink
export more C functions via LinkingTo
Browse files Browse the repository at this point in the history
  • Loading branch information
coolbutuseless committed Aug 18, 2024
1 parent 772ad89 commit df88291
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 4 deletions.
62 changes: 59 additions & 3 deletions inst/include/nara.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,72 @@
// nr_point(uint32_t *nr, int height, int width, uint32_t color, int x, int y)
// @param nr pointer to the integer data of a native raster
// @param height,width dimensions of nativeRaster
// @param color package integer representing RGBA colour
// @param color packed integer representing RGBA colour
// @param x,y location of point
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static inline void nr_point(uint32_t *nr, int height, int width, uint32_t color, int x, int y) {
static SEXP (*fun)(uint32_t *nr, int height, int width, uint32_t color, int x, int y) = NULL;

if (fun == NULL) {
// void draw_point_c(uint32_t *nr, int height, int width, uint32_t color, int x, int y)
fun = (SEXP (*)(uint32_t *nr, int height, int width, uint32_t color, int x, int y)) R_GetCCallable("nara", "draw_point_c");
fun = (SEXP (*)(uint32_t *nr, int height, int width, uint32_t color, int x, int y)) R_GetCCallable("nara", "nr_point");
}

fun(nr, height, width, color, x, y);
}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void line(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1)
// @param nr pointer to the integer data of a native raster
// @param height,width dimensions of nativeRaster
// @param color packed integer representing RGBA colour
// @param x0,y0,x1,y1 locations of endpoints
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static inline void nr_line(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1) {
static SEXP (*fun)(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1) = NULL;

if (fun == NULL) {
fun = (SEXP (*)(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1)) R_GetCCallable("nara", "nr_line");
}

fun(nr, height, width, color, x0, y0, x1, y1);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void nr_hline(uint32_t *nr, int height, int width, uint32_t color, int x1, int x2, int y)
// @param nr pointer to the integer data of a native raster
// @param height,width dimensions of nativeRaster
// @param color packed integer representing RGBA colour
// @param x1,x2 inclusive endpoints
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static inline void nr_hline(uint32_t *nr, int height, int width, uint32_t color, int x1, int x2, int y) {
static SEXP (*fun)(uint32_t *nr, int height, int width, uint32_t color, int x1, int x2, int y) = NULL;

if (fun == NULL) {
fun = (SEXP (*)(uint32_t *nr, int height, int width, uint32_t color, int x1, int x2, int y)) R_GetCCallable("nara", "nr_hline");
}

fun(nr, height, width, color, x1, x2, y);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// void draw_circle_c(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color)
// @param nr pointer to the integer data of a native raster
// @param height,width dimensions of nativeRaster
// @param color packed integer representing RGBA colour
// @param fill packed integer representing RGBA fill
// @param xm,ym centre
// @param r radius
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static inline void nr_circle(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color) {
static SEXP (*fun)(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color) = NULL;

if (fun == NULL) {
fun = (SEXP (*)(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color)) R_GetCCallable("nara", "nr_circle");
}

fun(nr, height, width, xm, ym, r, fill, color);
}

8 changes: 7 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ static const R_CallMethodDef CEntries[] = {

// C funss for export via "LinkingTo"
extern void draw_point_c(uint32_t *nr, int height, int width, uint32_t color, int x, int y);
extern void draw_line_c(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1) ;
extern void draw_point_sequence_c(uint32_t *nr, int height, int width, uint32_t color, int x1, int x2, int y);
extern void draw_circle_c(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color);

void R_init_nara(DllInfo *info) {
R_registerRoutines(
Expand All @@ -119,7 +122,10 @@ void R_init_nara(DllInfo *info) {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Make the C code available to other packages
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
R_RegisterCCallable("nara", "draw_point_c", (DL_FUNC) &draw_point_c);
R_RegisterCCallable("nara", "nr_point" , (DL_FUNC) &draw_point_c);
R_RegisterCCallable("nara", "nr_line" , (DL_FUNC) &draw_line_c);
R_RegisterCCallable("nara", "nr_hline" , (DL_FUNC) &draw_point_sequence_c);
R_RegisterCCallable("nara", "nr_circle", (DL_FUNC) &draw_circle_c);
}


Expand Down
41 changes: 41 additions & 0 deletions src/nr-draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,47 @@ SEXP draw_rect_(SEXP nr_, SEXP x_, SEXP y_, SEXP w_, SEXP h_,
}


// void draw_line_c(uint32_t *nr, int height, int width, uint32_t color, int x0, int y0, int x1, int y1) {
void draw_circle_c(uint32_t *nr, int height, int width, int xm, int ym, int r, uint32_t fill, uint32_t color) {
// Skip NAs
if (xm == NA_INTEGER || ym == NA_INTEGER || r == NA_INTEGER) {
return;
}

int *ydone = (int *)calloc((size_t)r * 2, sizeof(int));
if (ydone == NULL) {
error("draw_circle_c(): error allocating 'ydone'");
}

int x = -r, y = 0, err = 2-2*r; /* II. Quadrant */
do {

if (!is_transparent(fill) && !ydone[y]) {
draw_point_sequence_c(nr, height, width, fill, xm + x, xm - x, ym + y);
if (y != 0) {
draw_point_sequence_c(nr, height, width, fill, xm + x, xm - x, ym - y);
}
ydone[y] = 1;
}

if (!is_transparent(color)) {
draw_point_c(nr, height, width, color, xm-x, ym+y); /* I. Quadrant */
draw_point_c(nr, height, width, color, xm+x, ym+y); /* II. Quadrant */
if (y != 0) {
draw_point_c(nr, height, width, color, xm-x, ym-y); /* III. Quadrant */
draw_point_c(nr, height, width, color, xm+x, ym-y); /* IV. Quadrant */
}
}

r = err;
if (r <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
if (r > x || err > y) err += ++x*2+1; /* e_xy+e_x > 0 or no 2nd y-step */
} while (x < 0);

free(ydone);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Draw Circle. Vectorised [R interface]
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down

0 comments on commit df88291

Please sign in to comment.