/* See LICENSE file for copyright and license details. */
#include "librifunktionsteckensnittsglyfrasteriseringsprogrambiblioteket.h"
#include <errno.h>
#include <math.h>
#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
# pragma GCC diagnostic ignored "-Wempty-body"
# pragma GCC diagnostic ignored "-Wfloat-equal"
# define PURE_FUNCTION __attribute__((__pure__))
# define CONST_FUNCTION __attribute__((__const__))
#elif defined(__clang__)
# pragma clang diagnostic ignored "-Wcomma"
# pragma clang diagnostic ignored "-Wfloat-equal"
# pragma clang diagnostic ignored "-Wfloat-conversion"
# define PURE_FUNCTION
# define CONST_FUNCTION
#else
# define PURE_FUNCTION
# define CONST_FUNCTION
#endif
#define SIGNUM(X) (((X) > 0) - ((X) < 0))
#define DEFAULT_DRAFTNESS 0.5
#define draw_vertical_line_opposite_only(...)
typedef struct rtgrpblib_cell {
/**
* The sum all contribution lines make to
* the cell's ink level
*
* For each line, this is calculated by
* the signed area of the right triangle,
* whose catheti are parallel to the edges
* and whose hypotenuse is the line's segment
* in the cell, plus the area of the rectangle
* whose left edge is the opposite cathetus
* of the right triangle, and whose right edge
* intersects with the right cell edge
*/
double cell_coverage; /* ink here */
/**
* The sum all contribution lines make to
* the shadow on the cell's right edge:
* the ink level on the next cell
*
* For each line, this is calculated by the
* signed size of the opposite (right-side)
* cathetus of the right triangle, whose
* catheti are parallel to the edges and
* whose hypotenuse is the line's segment
* in the cell
*/
double opposite_coverage; /* ink there */
} CELL;
typedef struct rtgrpblib_raster {
size_t height;
size_t width;
size_t size;
double draftness; /* TODO support 0 */
CELL cells[];
} RASTER;
#define TOLERANCE 0.000001
CONST_FUNCTION
static inline int
iszeroish(double x)
{
return x <= TOLERANCE && x >= -TOLERANCE;
}
/* draw_linear_bezier_reference.c */
#define draw_linear_bezier_reference rtgrpblib_draw_linear_bezier_reference__
void draw_linear_bezier_reference(RASTER *restrict raster, double x1, double y1, double x2, double y2);
/* equations.c */
#define solve_cubic rtgrpblib_solve_cubic__
#define solve_quadratic rtgrpblib_solve_quadratic__
#define solve_linear rtgrpblib_solve_linear__
size_t solve_cubic(double *ts, double a, double b, double c, double d);
size_t solve_quadratic(double *ts, double a, double b, double c);
size_t solve_linear(double *ts, double a, double b);
/* lines.c */
#ifndef draw_vertical_line_opposite_only
# define draw_vertical_line_opposite_only rtgrpblib_draw_vertical_line_opposite_only__
void draw_vertical_line_opposite_only(RASTER *restrict raster, size_t x, double y1, double y2, int ydir);
#else
# define ROWWISE_RESET_INKLEVEL
#endif
#define draw_vertical_line rtgrpblib_draw_vertical_line__
#define draw_diagonal_line rtgrpblib_draw_diagonal_line__
#define draw_bounded_line rtgrpblib_draw_bounded_line__
void draw_vertical_line(RASTER *restrict raster, double x1, double y1, double y2, int ydir);
void draw_diagonal_line(RASTER *restrict raster, double x1, double y1, double x2, double y2,
double dx, double dy, int xdir, int ydir);
void draw_bounded_line(RASTER *restrict raster, double x1, double y1, double x2, double y2);
/* sorting.c */
#define doublepcmp rtgrpblib_doublepcmp__
PURE_FUNCTION int doublepcmp(const void *avp, const void *bvp);
#ifdef TEST
#include <unistd.h>
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
# pragma GCC diagnostic ignored "-Wfloat-equal"
# pragma GCC diagnostic ignored "-Wsuggest-attribute=const"
#elif defined(__clang__)
# pragma clang diagnostic ignored "-Wfloat-equal"
#endif
static inline int
eq(double a, double b)
{
return iszeroish(a - b);
}
static inline int
tolerant_eq(double a, double b)
{
return iszeroish((a - b) / 100.0);
}
static inline int
intolerant_eq(double a, double b)
{
return fabs(a - b) < 1e-11;
}
# define ASSERT(ASSERTION)\
do {\
if (!(ASSERTION)) {\
fprintf(stderr, "Failed assertion at line %i: %s\n", __LINE__, #ASSERTION);\
exit(1);\
}\
} while (0)
# if 0
static void
print_raster(const RASTER *r) {
size_t y, x;
fprintf(stderr, "\nOutline (area)\n");
for (y = 0; y < r->height; y++) {
for (x = 0; x < r->width; x++)
fprintf(stderr, r->cells[y * r->width + x].cell_coverage ? "%+.4lf " : " 0 ",
r->cells[y * r->width + x].cell_coverage);
printf("\n");
}
fprintf(stderr, "\nOutline (shadow)\n");
for (y = 0; y < r->height; y++) {
for (x = 0; x < r->width; x++)
fprintf(stderr, r->cells[y * r->width + x].opposite_coverage ? "%+.4lf " : " 0 ",
r->cells[y * r->width + x].opposite_coverage);
printf("\n");
}
}
# endif
#endif