libtthimage/Lib/drawing.c
2023-09-28 23:50:23 +02:00

242 lines
5.7 KiB
C

/*
primitives graphiques premier module (back in 1999)
---------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#endif
/*::------------------------------------------------------------------::*/
static int iSign(int a)
{
if (a<0) return -1;
if (a>0) return 1;
return 0;
}
/*::------------------------------------------------------------------::*/
static void symmetry(int x, int y, int xc, int yc, RGBA *g, Image_Desc *i)
{
int x_start, x_end;
int y_start, y_end;
x_start = x; y_start = y;
x_end = x + 1; y_end = y + 1;
Image_plotRGB(i, x+xc, y+yc, 100, 100, 100);
fprintf(stderr, "sym %d %d\n", x, y);
}
/* le parametre 'wrap' ne sert a rien */
int Image_draw_circle(Image_Desc *i, int xc, int yc, int rayon, RGBA *q, int wrap)
{
int x, y, d;
#if DEBUG_LEVEL
fprintf(stderr, "%s : centre %d %d, rayon %d\n", __func__, xc, yc, rayon);
#endif
y = rayon;
d = 3 - 2 * rayon;
for ( x=0; x<y; ) {
symmetry(x, y, xc, yc, q, i);
if (d<0) {
d += 4 * x + 6;
}
else {
d += 4 * (y - x) * 10;
--y;
}
++x;
}
return FUNC_NOT_FINISH;
}
/*::------------------------------------------------------------------::*/
/* New Mon 19 Dec 2022 12:56:44 PM CET */
int Image_H_line(Image_Desc *i, int xa, int xb, int ypos, RGBA *col)
{
int ix;
#if 1
fprintf(stderr, ">>> %s ( %d %d %d %p )\n", __func__, xa, xb, ypos, col);
#endif
if (xa > xb) { ix=xa, xa=xb, xb=ix; }
for (ix=xa; ix<xb; ix++) {
Image_plotRGB(i, ix, ypos, col->r, col->g, col->b);
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* l'appel a la fonction isign devrait disparaitre pour optimiser
* la vitesse du bouzin.
*/
int Image_draw_line(Image_Desc *i, int x1, int y1, int x2, int y2, RGBA *q)
{
int dx, dy, ix, iy, inc;
int foo, plotx, ploty, x, y;
int plot;
#if DEBUG_LEVEL
printf(">>> %s ( %p %4d %4d %4d %4d\n", __func__, i, x1, y1, x2, y2);
#endif
dx = x2 - x1; dy = y2 - y1;
ix = abs(dx); iy = abs(dy);
inc = ix<iy ? iy : ix;
#if DEBUG_LEVEL > 1
printf("d %4d %4d i %4d %4d ^ %4d\n", dx, dy, ix, iy, inc);
#endif
plotx = x1;
ploty = y1;
x = y = 0;
for (foo=0; foo<=inc; ++foo) {
x += ix;
y += iy;
plot = 0;
if (x > inc) {
plot = 42;
x -= inc;
plotx += iSign(dx);
}
if (y > inc) {
plot = 42;
y -= inc;
ploty += iSign(dy);
}
if (plot) {
/* printf("%5d %5d %5d\n", foo, plotx, ploty ); */
Image_plotRGB(i, plotx, ploty, q->r, q->g, q->b);
}
}
return 0;
}
/*::------------------------------------------------------------------::*/
/*
* XXX si je veux remplacer 'plotRGB' par un acces direct
* XXX dans les buffers, il faut soigner les controles
*/
int Image_paint_rect(Image_Desc *img, Image_Rect *rect, int r, int g, int b)
{
int xd, yd, xf, yf, x, y;
#if DEBUG_LEVEL > 2
fprintf(stderr, "Paint Rect : image %d x %d\n", img->width, img->height);
Image_dump_rect(rect, "in 'paint a rect'", 0);
#endif
xd = max(0, rect->x);
yd = max(0, rect->y);
xf = min((img->width), (rect->x+rect->w));
yf = min((img->height), (rect->y+rect->h));
/*
* 24 Juin 2002: est-ce que le code ci-dessus est vraiment valide ?
* 24 Avril 2008: NON !
* 26 janvier 2014 : toujours non...
* 19 septembre 2022 : je n'ai pas de certitude a ce sujet
*/
#if DEBUG_LEVEL > 2
fprintf(stderr, "Paint Rect: %4d < X < %4d %4d < Y < %4d\n",
xd, xf, yd, yf);
#endif
for (x=xd; x<xf; x++) {
for (y=yd; y<yf; y++) {
/* Image_plotRGB(img, x, y, r, g, b); */
(img->Rpix[y])[x] = r;
(img->Gpix[y])[x] = g;
(img->Bpix[y])[x] = b;
}
}
return 0;
}
/*::------------------------------------------------------------------::*/
/*
* 27 Juin 2001: there was an off-by-one error in this func...
* See also 'drawpatt.c' for others things.
###
### THERE IS A OFF-BY-ONE IN THIS FUNCTION !
###
*/
int Image_draw_rect(Image_Desc *img, Image_Rect *rect, int r, int g, int b)
{
int foo;
int xd, yd, xf, yf;
xd = max(0, rect->x);
yd = max(0, rect->y);
xf = min((img->width-1), ((rect->x+rect->w)));
yf = min((img->height-1), ((rect->y+rect->h)));
#if DEBUG_LEVEL > 1
Image_dump_rect(rect, "draw a rect", 0);
fprintf(stderr, "Draw a Rect: xd:%4d yd:%4d xf:%4d yf:%4d\n",
xd, yd, xf, yf);
#endif
for (foo=xd; foo<xf; foo++) {
/* if ( (rect->y >= 0) && (rect->y < img->height) ) */
Image_plotRGB(img, foo, rect->y, r, g, b);
/* if ( (rect->y+rect->h >= 0) && (rect->y+rect->h < img->height) ) */
Image_plotRGB(img, foo, rect->y+rect->h-1, r, g, b);
}
for (foo=yd; foo<yf; foo++) {
/* if ( (rect->x >= 0) && (rect->x < img->width) ) */
Image_plotRGB(img, rect->x, foo, r, g, b);
/* if ( (rect->x+rect->w >= 0) && (rect->x+rect->w < img->width) ) */
Image_plotRGB(img, rect->x+rect->w-1, foo, r, g, b);
}
return 0;
}
/*::------------------------------------------------------------------::*/
/* new 10 octobre 2008 - zone de Monredon (Betatech) */
int Image_noise_rect(Image_Desc *img, Image_Rect *rect, int r, int g, int b)
{
int xd, yd, xf, yf, x, y;
fprintf(stderr, "%s: i=%p r=%p %d %d %d\n", __func__, img, rect, r, g, b);
xd = max(0, rect->x);
yd = max(0, rect->y);
xf = min((img->width-1), (rect->x+rect->w));
yf = min((img->height-1), (rect->y+rect->h));
#if DEBUG_LEVEL
fprintf(stderr, "%s: %d %d %d %d\n", __func__, xd, yd, xf, yf);
#endif
for (x=xd; x<xf; x++) {
for (y=yd; y<yf; y++) {
(img->Rpix[y])[x] = rand() % r;
(img->Gpix[y])[x] = rand() % g;
(img->Bpix[y])[x] = rand() % b;
}
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
/*
* kikoo lol a tous les goret-codeurs, et en particulier Mr Spleyt.
*/