aboutsummaryrefslogblamecommitdiffstats
path: root/common.h
blob: 1c589be430973bd7a66663ea2e4887c933d7c252 (plain) (tree)






























                                                                           

                             




































                                                      
                    
















                                                 




                                                                                                       































                                                                                                         
                   




























                                                                                                    




















                                                                                                              
      
/* 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);
}

# 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