/* See LICENSE file for copyright and license details. */
#ifndef LIBRIFUNKTIONSTECKENSNITTSGLYFRASTERISERINGSPROGRAMBIBLIOTEKET_H
#define LIBRIFUNKTIONSTECKENSNITTSGLYFRASTERISERINGSPROGRAMBIBLIOTEKET_H
/* ^ < ^ < ^ ^ > ^ */
/* r t g r p b lib */
#include <stddef.h>
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdocumentation"
#endif
/**
* Object that the library draws on, is converted to
* an ink-level image using the `rtgrpblib_fill_shapes`
* function. This object also contain drawing
* configurations.
*/
typedef struct rtgrpblib_raster RTGRPBLIB_RASTER;
/**
* Create a buffer that the library can use for drawing
*
* @param width The width of the buffer
* @param height The height of the buffer
* @return Drawing buffer, which can be deallocated with
* free(3), or `NULL` on failure
*
* @throws EINVAL `width` or `height` is zero
* @throws ENOMEM Cannot allocate enough memory
*
* @seealso rtgrpblib_reset_raster
*/
RTGRPBLIB_RASTER *rtgrpblib_create_raster(size_t width, size_t height);
/**
* Reshape and clear a drawing buffer
*
* @param raster The buffer to reshape and clear
* @param width The new width of the buffer
* @param height The new height of the buffer
* @return 0 on success, -1 on failure
*
* @throws EINVAL `width` or `height` is zero
* @throws EINVAL The buffers new area size exceeds its original area size
*/
int rtgrpblib_reset_raster(RTGRPBLIB_RASTER *raster, size_t width, size_t height);
/**
* Reconfigure a drawing buffer with a new draftness value
*
* When drawing a curve, the size of each step the library
* takes will be proportional to the draftness value, but
* will also depend on other factors. Doubling the draftness
* value with halve (disregarind overheads) the time it takes
* to draw any given curve.
*
* @param raster The drawing buffer to reconfigure
* @param draftness The new draftness value, must be positive
*/
void rtgrpblib_set_draftness(RTGRPBLIB_RASTER *raster, double draftness);
/**
* Create an image of the drawings applied to a drawing buffer
*
* All drawn shapes must be closed
*
* Shapes that are drawn in the same angular direction add to
* each other, shapes that are drawn in opposite angular
* directions subtract from each other
*
* @param image Output buffer, need not be initialised, but
* shall have an allocation size of `rowsize`
* multiplied by the height of `raster` and
* by `sizeof(double)`
* @param rowsize The number of elements in `image` per row,
* must be at least the width of `raster`
* @param raster The drawing buffer
*
* @seealso rtgrpblib_reset_raster
*/
void rtgrpblib_fill_shapes(double *restrict image, size_t rowsize, const RTGRPBLIB_RASTER *raster);
/**
* Draw a line between two points
*
* @param raster The drawing buffer
* @param x1, y1 The starting point
* @param x2, y2 The end point
*/
void rtgrpblib_draw_linear_bezier(RTGRPBLIB_RASTER *restrict raster,
double x1, double y1,
double x2, double y2);
/**
* Draw a quadratic Bézier curve
*
* @param raster The drawing buffer
* @param x1, y1 The starting point
* @param x2, y2 The control point
* @param x3, y3 The end point
*/
void rtgrpblib_draw_quadratic_bezier(RTGRPBLIB_RASTER *restrict raster,
double x1, double y1,
double x2, double y2,
double x3, double y3);
/**
* Draw a cubic Bézier curve
*
* @param raster The drawing buffer
* @param x1, y1 The starting point
* @param x2, y2 The first control point
* @param x3, y3 The second control point
* @param x4, y4 The end point
*/
void rtgrpblib_draw_cubic_bezier(RTGRPBLIB_RASTER *restrict raster,
double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
/**
* Draw a circular arc
*
* @param raster The drawing buffer
* @param x0, y0 The midpoint of the circle
* @param semiwidth Half the width of the circle
* @param semiheight Half the height of the circle
* @param start The angular starting point of the arc, in radians
* @param end The angular end point of the arc, in radians
*
* Rather than specify a radius, a semimajor and semiminor is
* specified, despite this, the shape is called a circular rather
* than elliptical, this is because the function is indented to
* draw a circular arc on a image with different horizontal
* and vertical cell densities; note an elliptical arc on an image
* with the same horizontal as vertical cell density. This is
* why the function doesn't provide a way to rotate the ellipse:
* it's a circle, not an ellipse, and circles are perfectly
* symmetrical
*/
void rtgrpblib_draw_circular_arc(RTGRPBLIB_RASTER *restrict raster,
double x0, double y0,
double semiwidth, double semiheight,
double start, double end);
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
#endif