Added doply() rendering function for convexe filled polygons with border

This commit is contained in:
Sylvain PILLOT 2024-01-19 21:20:00 +01:00
parent dcf34833c5
commit e517b1b42d
3 changed files with 189 additions and 73 deletions

View File

@ -104,6 +104,7 @@ set(SOURCES_COMMON
# Rendering
src/render/dcircle.c
src/render/dellipse.c
src/render/dpoly.c
src/render/dhline.c
src/render/dimage.c
src/render/dline.c

View File

@ -13,8 +13,8 @@
extern "C" {
#endif
#include <gint/defs/types.h>
#include <gint/defs/call.h>
#include <gint/defs/types.h>
/* Platform-specific functions include VRAM management and the definition of
the color_t type. */
@ -23,7 +23,7 @@ extern "C" {
#include <gint/display-fx.h>
#endif
#if defined(FXCG50) && ! defined(FX9860G_AS_CG)
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
#include <gint/display-cg.h>
#endif
@ -90,8 +90,8 @@ gint_call_t dupdate_get_hook(void);
to the rectangle spanning from (left,top) included, to (right,bottom)
excluded. The default is from (0,0) to (DWIDTH,DHEIGHT). */
struct dwindow {
int left, top;
int right, bottom;
int left, top;
int right, bottom;
};
extern struct dwindow dwindow;
@ -149,8 +149,8 @@ void drect(int x1, int y1, int x2, int y2, int color);
@fill_color Center color (same values as drect() are allowed)
@border_width Amount of pixels reserved for the border on each side
@border_color Border color (same values as drect() are allowed) */
void drect_border(int x1, int y1, int x2, int y2,
int fill_color, int border_width, int border_color);
void drect_border(int x1, int y1, int x2, int y2, int fill_color,
int border_width, int border_color);
//---
// Point drawing functions
@ -241,69 +241,78 @@ void dcircle(int xm, int ym, int r, int fill_color, int border_color);
@x1 @y1 @x2 @y2 Ellipse's bounding box (both bounds included, like drect())
@fill_color Color of the surface inside the ellipse, C_NONE to disable
@border_color Color of the ellipse itself, C_NONE to disable */
void dellipse(int x1, int y1, int x2, int y2, int fill_color,
int border_color);
void dellipse(int x1, int y1, int x2, int y2, int fill_color, int border_color);
/* dpoly(): Polygone with border
This function renders a closed-polygone defined by its vertices coordinates.
@x @y Pointer to arrays containing the x / y coordinates of each
individual vertex
@nbvertices Number of vertices
@fill_color Color of the surface inside the polygone, C_NONE to disable
@border_color Color of the polygon itself, C_NONE to disable */
void dpoly(int *x, int *y, int nbvertices, int fill_color, int border_color);
//---
// Text rendering (topti)
//---
/* font_t: Font data encoded for topti */
typedef struct
{
/* Font name (NUL-terminated), NULL if no title */
char const *name;
typedef struct {
/* Font name (NUL-terminated), NULL if no title */
char const *name;
/* Font shape flags */
uint bold :1;
uint italic :1;
uint serif :1;
uint mono :1;
uint :3;
/* Whether data is variable-length (proportional font) */
uint prop :1;
/* Font shape flags */
uint bold : 1;
uint italic : 1;
uint serif : 1;
uint mono : 1;
uint : 3;
/* Whether data is variable-length (proportional font) */
uint prop : 1;
/* Line height */
uint8_t line_height;
/* Storage height */
uint8_t data_height;
/* Line height */
uint8_t line_height;
/* Storage height */
uint8_t data_height;
/* Number of Unicode blocks */
uint8_t block_count;
/* Number of total glyphs */
uint32_t glyph_count;
/* Number of Unicode blocks */
uint8_t block_count;
/* Number of total glyphs */
uint32_t glyph_count;
/* Character spacing (usually 1) */
uint8_t char_spacing;
/* Character spacing (usually 1) */
uint8_t char_spacing;
uint :24;
uint : 24;
struct {
/* Unicode point of first character in block */
uint start :20;
/* Length of block */
uint length :12;
} *blocks;
struct {
/* Unicode point of first character in block */
uint start : 20;
/* Length of block */
uint length : 12;
} * blocks;
/* Raw glyph data */
uint32_t *data;
/* Raw glyph data */
uint32_t *data;
union {
/* For monospaced fonts */
struct {
/* Width of glyphs */
uint16_t width;
/* Storage size, in longwords, of each glyph */
uint16_t storage_size;
};
/* For proportional fonts */
struct {
/* Storage index to find glyphs quickly */
uint16_t *glyph_index;
/* Width of each individual glyph */
uint8_t *glyph_width;
};
};
union {
/* For monospaced fonts */
struct {
/* Width of glyphs */
uint16_t width;
/* Storage size, in longwords, of each glyph */
uint16_t storage_size;
};
/* For proportional fonts */
struct {
/* Storage index to find glyphs quickly */
uint16_t *glyph_index;
/* Width of each individual glyph */
uint8_t *glyph_width;
};
};
} GPACKED(4) font_t;
@ -381,14 +390,14 @@ char const *drsize(char const *str, font_t const *font, int width, int *w);
and a horizontal alignment option specifies where a given point (x,y) should
be relative to the rendered string. */
enum {
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
DTEXT_LEFT = 0,
DTEXT_CENTER = 1,
DTEXT_RIGHT = 2,
/* Vertical settings: default in dtext() is DTEXT_TOP */
DTEXT_TOP = 0,
DTEXT_MIDDLE = 1,
DTEXT_BOTTOM = 2,
/* Horizontal settings: default in dtext() is DTEXT_LEFT */
DTEXT_LEFT = 0,
DTEXT_CENTER = 1,
DTEXT_RIGHT = 2,
/* Vertical settings: default in dtext() is DTEXT_TOP */
DTEXT_TOP = 0,
DTEXT_MIDDLE = 1,
DTEXT_BOTTOM = 2,
};
/* dtext_opt(): Display a string of text
@ -419,12 +428,13 @@ enum {
@str String to display
@size Maximum number of bytes to display (negative for no limit) */
void dtext_opt(int x, int y, int fg, int bg, int halign, int valign,
char const *str, int size);
char const *str, int size);
/* The last parameter @size was added in gint 2.4; this macro will add it
automatically with a value of -1 if the call is made with only 7 parameters.
This is for backwards compatibility. */
#define dtext_opt8(x,y,fg,bg,h,v,str,sz,...) dtext_opt(x,y,fg,bg,h,v,str,sz)
#define dtext_opt8(x, y, fg, bg, h, v, str, sz, ...) \
dtext_opt(x, y, fg, bg, h, v, str, sz)
#define dtext_opt(...) dtext_opt8(__VA_ARGS__, -1)
/* dtext(): Simple version of dtext_opt() with defaults
@ -439,7 +449,7 @@ void dtext(int x, int y, int fg, char const *str);
dprint_opt(x, y, fg, bg, halign, valign, "A=%d B=%d", A, B); */
void dprint_opt(int x, int y, int fg, int bg, int halign, int valign,
char const *format, ...);
char const *format, ...);
/* dprint(): Simple version of dprint_op() with defaults
Calls dprint_opt() with bg=C_NONE, halign=DTEXT_LEFT and valign=DTEXT_TOP */
@ -484,12 +494,12 @@ void dimage(int x, int y, bopti_image_t const *image);
/* Option values for dsubimage() */
enum {
/* No option */
DIMAGE_NONE = 0x00,
/* Disable clipping, ie. adjustments to the specified subrectangle and
screen location such that any part that overflows from the image or
the screen is ignored. Slightly faster. */
DIMAGE_NOCLIP = 0x01,
/* No option */
DIMAGE_NONE = 0x00,
/* Disable clipping, ie. adjustments to the specified subrectangle and
screen location such that any part that overflows from the image or
the screen is ignored. Slightly faster. */
DIMAGE_NOCLIP = 0x01,
};
/* dsubimage(): Render a section of an image
@ -502,7 +512,7 @@ enum {
@width @height Subrectangle dimensions
@flags OR-combination of DIMAGE_* flags */
void dsubimage(int x, int y, bopti_image_t const *image, int left, int top,
int width, int height, int flags);
int width, int height, int flags);
#ifdef __cplusplus
}

105
src/render/dpoly.c Normal file
View File

@ -0,0 +1,105 @@
#include <gint/defs/util.h>
#include <gint/display.h>
void dpoly(int *x, int *y, int nb_vertices, int fill_color, int border_color) {
int i, ymin, ymax, xmin, xmax, *xmint, *xmaxt;
char *emptyt;
if (fill_color == C_NONE && border_color == C_NONE)
return;
if (fill_color != C_NONE) {
int i, ymin, ymax, xmin2, xmax2, *xmin, *xmax;
char *empty;
if (nb_vertices < 3)
return;
ymin = ymax = y[0];
xmin2 = xmax2 = x[0];
for (i = 0; i < nb_vertices; i++) {
if (y[i] < ymin)
ymin = y[i];
if (y[i] > ymax)
ymax = y[i];
if (x[i] < xmin2)
xmin2 = x[i];
if (x[i] > xmax2)
xmax2 = x[i];
}
if (xmax2 < 0 || xmin2 > DWIDTH - 1 || ymax < 0 || ymin > DHEIGHT - 1)
return;
xmin = malloc((ymax - ymin + 1) * sizeof(int));
xmax = malloc((ymax - ymin + 1) * sizeof(int));
empty = malloc(ymax - ymin + 1);
if (xmin && xmax && empty) {
for (i = 0; i < ymax - ymin + 1; i++)
empty[i] = 1;
for (i = 0; i < nb_vertices; i++) {
int j, px, py, dx, dy, sx, sy, cumul;
px = x[i];
py = y[i];
dx = x[(i + 1) % nb_vertices] - px;
dy = y[(i + 1) % nb_vertices] - py;
sx = (dx > 0) ? 1 : -1;
sy = (dy > 0) ? 1 : -1;
dx = (dx > 0) ? dx : -dx;
dy = (dy > 0) ? dy : -dy;
if (empty[py - ymin])
xmax[py - ymin] = xmin[py - ymin] = px, empty[py - ymin] = 0;
else
xmax[py - ymin] = px;
if (dx > dy) {
cumul = dx >> 1;
for (j = 1; j < dx; j++) {
px += sx;
cumul += dy;
if (cumul > dx)
cumul -= dx, py += sy;
if (empty[py - ymin])
xmax[py - ymin] = xmin[py - ymin] = px, empty[py - ymin] = 0;
else
xmax[py - ymin] = px;
}
} else {
cumul = dy >> 1;
for (j = 1; j < dy; j++) {
py += sy;
cumul += dx;
if (cumul > dy)
cumul -= dy, px += sx;
if (empty[py - ymin])
xmax[py - ymin] = xmin[py - ymin] = px, empty[py - ymin] = 0;
else
xmax[py - ymin] = px;
}
}
}
for (i = 0; i < ymax - ymin + 1; i++)
dline(xmin[i], ymin + i, xmax[i], ymin + i, fill_color);
}
free(xmin);
free(xmax);
free(empty);
}
if (border_color != C_NONE) {
for (int i = 0; i < nb_vertices; i++) {
int px = x[i];
int py = y[i];
int px2 = x[(i + 1) % nb_vertices];
int py2 = y[(i + 1) % nb_vertices];
dline(px, py, px2, py2, border_color);
}
}
return;
}