Files
argyllcms/render/render.h
2026-08-20 20:28:40 +01:00

368 lines
12 KiB
C

#ifndef RENDER2D_H
#define RENDER2D_H
/*
* render2d
*
* Simple 2D raster rendering support.
*
* Author: Graeme W. Gill
* Date: 28/12/2005
*
* Copyright 2005, 2008, 2012, 2014 Graeme W. Gill
* All rights reserved.
*
* This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
* see the License.txt file for licencing details.
*/
/* This is basically a simple 2D ray tracing renderer, so it's not especially */
/* efficient, but it's simple and direct, easy to add new primitives or */
/* capabilities, is high quality, and has an accelleration algorithm that */
/* makes it fast enough for printed output. */
/* Mathematical coordinate in mm are used for primitives, ie. the origin is */
/* the bottom left corner. */
/* Device color values range from 0.0 to 1.0 */
#define MXCH2D 16 /* Maximum color channels */
#define TOTC2D (MXCH2D+1) /* Maximum total components */
#define PRIX2D (MXCH2D) /* Index of primitive kept with color value */
#define MXPATSIZE 4 /* Maximum color pattern size */
/* Color type */
/* Shouldn't this be an xcolorants mask ? */
typedef enum {
w_2d, /* Video style grey */
k_2d, /* Printing style grey */
lab_2d, /* Lab */
rgb_2d, /* RGB */
cmyk_2d, /* CMYK */
ncol_2d, /* N color */
ncol_a_2d /* N color with extra as alpha */
} colort2d;
/* Pixel depth */
typedef enum {
bpc8_2d, /* 8 bits per component */
bpc16_2d /* 16 bits per component */
} depth2d;
typedef double color2d[TOTC2D];
/* Font type */
typedef enum {
rowman_s = 0, /* Rownman, single stroke */
rowman_d = 1, /* Rownman, double stroke */
rowman_t = 2, /* Rownman, triple stroke */
timesr = 3, /* Times Roman */
timesr_b = 4, /* Times Roman, Bold */
futura_l = 5, /* Futura, Light */
futura_m = 6 /* Futura, Medium */
} font2d;
/* ------------------------------------ */
struct _render2d;
#define PRIM_STRUCT \
/* primt2d tag; */ /* Type of primitive */ \
int ix; /* Index (order added) */ \
int ncc; /* Number of color components */ \
struct _prim2d *next; /* Linked list to next primitive */ \
struct _prim2d *yl0; /* Previous lines Y list linked list */ \
struct _prim2d *yl; /* Active Y list linked list */ \
struct _prim2d *xl; /* Active X list linked list */ \
double x0, y0, x1, y1; /* Extent, top & left inclusive, bot & right non-inclusive */ \
void (*del)(struct _prim2d *s); /* Delete the object */ \
/* Render the object at location. Return nz if in primitive */ \
int (*rend)(struct _prim2d *s, color2d rv, double x, double y);
struct _prim2d {
PRIM_STRUCT
}; typedef struct _prim2d prim2d;
/* ------------------------------------ */
/* Solid rectange primitive */
struct _rect2d {
PRIM_STRUCT
double rx0, ry0, rx1, ry1; /* Rectangle vertices */
color2d c; /* Color of rectangle (if dpat == NULL) */
double (*dpat)[MXPATSIZE][MXPATSIZE][TOTC2D]; /* Special for ChromeCast experiments */
int dp_w, dp_h; /* dpat dimensions */
}; typedef struct _rect2d rect2d;
prim2d *new_rect2d(struct _render2d *s, double x, double y, double w, double h, color2d c);
void set_rect2d_dpat(struct _rect2d *s, double (*pat)[MXPATSIZE][MXPATSIZE][TOTC2D], int w, int h);
/* ------------------------------------ */
/* Vertex shaded rectange */
struct _rectvs2d {
PRIM_STRUCT
double rx0, ry0, rx1, ry1; /* Rectangle vertices */
color2d c[4]; /* Bot left, bot right, top left, top right */
int x_blend; /* Blending rule flags, 0 = linear, 1 = spline, 2 = sine */
int y_blend;
int y_sine;
}; typedef struct _rectvs2d rectvs2d;
prim2d *new_rectvs2d(struct _render2d *s, double x, double y, double w, double h, color2d c[4]);
/* ------------------------------------ */
/* Vertex shaded triangle */
struct _trivs2d {
PRIM_STRUCT
double be[3][3]; /* baricentric equations */
color2d c[3]; /* Color of each vertex */
}; typedef struct _trivs2d trivs2d;
prim2d *new_trivs2d(struct _render2d *s, double v[3][2], color2d c[3]);
/* ------------------------------------ */
/* Polygon */
/* Solid polygon primitive */
struct _poly2d {
PRIM_STRUCT
color2d c; /* Color of polyangle (if dpat == NULL) */
int n; /* Number of vertices */
double co[1][2]; /* Array of [n][2] vertices */
}; typedef struct _poly2d poly2d;
prim2d *new_poly2d(struct _render2d *s, int n, double v[][2], color2d c);
#ifdef NEVER
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy) {
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
#endif // NEVER
/* ------------------------------------ */
/* Circular disk/line primitive */
struct _disk2d {
PRIM_STRUCT
double cx, cy; /* Center */
color2d c; /* Color of disk/line */
double orr, irr; /* Outer radius squared, inner radius squared (0.0 if disk) */
}; typedef struct _disk2d disk2d;
/* Center and radius */
prim2d *new_disk2d(struct _render2d *s, double x, double y, double r, color2d c);
/* Center, radius and line width */
void add_circle2d(struct _render2d *s, double x, double y, double r, double w, color2d c);
/* ------------------------------------ */
/* A single line. */
struct _line2d {
PRIM_STRUCT
double lx0, ly0, lx1, ly1; /* Line vertices */
double ww; /* half width of line squared */
int cap; /* 0 = butt, 1 = round, 2 = square */
color2d c; /* Color of the line */
int t; /* nz if line is degenerate */
double vx, vy; /* Vector relative to x0 y0 */
}; typedef struct _line2d line2d;
prim2d *new_line2d(struct _render2d *s, double x0, double y0, double x1, double y1, double w, int cap, color2d c);
/* ------------------------------------ */
/* Comound primitives */
/* add a dashed line */
void add_dashed_line2d(
struct _render2d *s,
double x0, double y0,
double x1, double y1,
double w,
double on, double off,
int cap,
color2d c);
/* Add a text character at the given location using lines */
void add_char2d(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char ch, /* Character code to be printed */
double x, double y, /* Location of bottom left of normal orientation text */
double h, /* Height of text in normal orientation */
int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
color2d c /* Color of text */
);
/* Add a string from the given location using lines. */
void add_string2d(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char *string, /* Character code to be printed */
double x, double y, /* Location of bottom left of normal orientation text */
double h, /* Height of text in normal orientation */
int or, /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
color2d c /* Color of text */
);
/* Return the total width of the string without adding it */
void meas_string2d(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char *string, /* Character code to be printed */
double h, /* Height of text in normal orientation */
int or /* Orintation, 0 = right, 1 = down, 2 = left, 3 = up */
);
/* Convert an angle in degrees (0 = right) */
/* into transform matrix */
void deg2mat(double mat[2][2], double a);
/* Convert a vector into a rotation matrix */
void vec2mat(double mat[2][2], double dx, double dy);
/* Add a text character at the given location using lines */
/* (matrix orientation version) */
void add_char2dmat(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char ch, /* Character code to be printed */
double x, double y, /* Location of bottom left of normal orientation text */
double h, /* Height of text in normal orientation */
double mat[2][2], /* Unity orientation matrix */
color2d c /* Color of text */
);
/* Add a string from the given location using lines. */
/* (matrix orientation version) */
void add_string2dmat(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char *string, /* Character code to be printed */
double x, double y, /* Location of bottom left of normal orientation text */
double h, /* Height of text in normal orientation */
double mat[2][2], /* Unity orientation matrix */
color2d c /* Color of text */
);
/* Return the total width of the string without adding it */
/* (matrix orientation version) */
void meas_string2dmat(
struct _render2d *s,
double *xinc, /* Return increment in position for next character */
double *yinc,
font2d fo, /* Font to use */
char *string, /* Character code to be printed */
double h, /* Height of text in normal orientation */
double mat[2][2] /* Unity orientation matrix */
);
/* ------------------------------------ */
/* Type of output to save to. */
typedef enum {
tiff_file, /* Write a TIFF format file */
png_file, /* Write a PNG format file */
png_mem, /* Write a PNG image to a memory buffer */
mem_rast /* Write a memory raster */
} rend_format;
/* ------------------------------------ */
/* Render object */
struct _render2d {
/* Private: */
int ix; /* Next primitive index */
double fw, fh; /* Page size in mm including margines */
double lm, rm, tm, bm; /* Page margines in mm */
double w, h; /* Page size in mm excluding margines */
double hres, vres; /* Page pixel resolution in pixels/mm */
int pw, ph; /* Page size in pixels */
colort2d csp; /* Color space */
int ncc; /* Number of color components */
depth2d dpth; /* Depth of the components */
int dither; /* Dither flag, 1 = ordered, 2 = error diffusion */
int noavg; /* Don't anti-alias or average 4 pixels together */
int dithfgo; /* Dither F.G. only flag */
void (*quant)(void *qcntx, double *out, double *in); /* optional quantization func. for edith */
void *qcntx;
double mxerr; /* Maximum error diffusion error */
color2d defc; /* Default color value */
void (*bgfunc)(void *cntx, color2d c, double x, double y); /* BG color function */
void *cntx;
prim2d *head; /* Start of list of primitives in rendering order */
prim2d *yl; /* Active Y list linked list head */
prim2d *xl; /* Active X list linked list head */
int ppitch; /* if mem_rast, pixel pitch in bytes */
int lpitch; /* if mem_rast, line pitch in bytes */
/* Public: */
/* Methods */
void (*del)(struct _render2d *s); /* Free ourselves and all primitives */
void (*set_defc)(struct _render2d *s, color2d c); /* Set the default/background color */
void (*set_bg_func)(struct _render2d *s, /* Set background color function */
void (*func)(void *cntx, color2d c, double x, double y), /* Func can choose not to set */
void *cntx
);
void (*add)(struct _render2d *s, prim2d *p); /* Add a primitive */
int (*write)(struct _render2d *s, char *filename, int comprn,
unsigned char **obuf, size_t *olen,
rend_format fmt); /* Render and write to a TIFF or PNG file */
void (*rast_details)(struct _render2d *s,
int *width, /* Return raster width in pixels */
int *height, /* Return raster width in pixels */
int *ppitch, /* Return pixel pitch in bytes */
int *lpitch /* Return line pitch in bytes */
);
}; typedef struct _render2d render2d;
/* Constructor */
render2d *new_render2d(
double w, /* width in mm */
double h, /* height in mm */
double ma[4], /* Margines, left, right, top, bottom, NULL for zero in mm */
double hres, /* horizontal resolution in pixels/mm */
double vres, /* horizontal resolution in pixels/mm */
colort2d csp, /* Color type */
int nd, /* Number of channels if c = ncol */
depth2d dpth, /* Pixel depth */
int dither, /* Dither flag, 1 = ordered, 2 = error diffusion, | 0x8000 to dither FG only */
/* | 0x4000 don't anti-alias by averaging pixels together. */
void (*quant)(void *qcntx, double *out, double *in), /* optional quantization func. for edith */
void *qcntx, /* Optional context for quant */
double mxerr /* Maximum error diffusion error (0.0 for default) */
);
#endif /* RENDER2D_H */