aboutsummaryrefslogtreecommitdiffstats
path: root/common.h
blob: ae9a1d73db39481422057dd41f4e4b3764a9b7cf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* 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 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;
	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;
}



/* 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

#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);
}

# define ASSERT(ASSERTION)\
	do {\
		if (!(ASSERTION)) {\
			fprintf(stderr, "Failed assertion at line %i: %s\n", __LINE__, #ASSERTION);\
			exit(1);\
		}\
	} while (0)

#endif