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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
|
#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 verticies */
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 verticies */
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 verticies */
double co[1][2]; /* Array of [n][2] verticies */
}; 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 verticies */
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 */
} 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 */
/* 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 */
}; 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,
double mxerr /* Maximum error diffusion error */
);
#endif /* RENDER2D_H */
|