8 - hatched (pattern, fg, bg)
16 static i_color fcolor_to_color(i_fcolor *c) {
20 for (ch = 0; ch < MAXCHANNELS; ++ch)
21 out.channel[ch] = SampleFTo8(c->channel[ch]);
24 static i_fcolor color_to_fcolor(i_color *c) {
28 for (ch = 0; ch < MAXCHANNELS; ++ch)
29 out.channel[ch] = Sample8ToF(c->channel[ch]);
39 #define COMBINE(out, in, channels) \
42 for (ch = 0; ch < (channels); ++ch) { \
43 (out).channel[ch] = ((out).channel[ch] * (255 - (in).channel[3]) \
44 + (in).channel[ch] * (in).channel[3]) / 255; \
48 #define COMBINEF(out, in, channels) \
51 for (ch = 0; ch < (channels); ++ch) { \
52 (out).channel[ch] = (out).channel[ch] * (1.0 - (in).channel[3]) \
53 + (in).channel[ch] * (in).channel[3]; \
57 static void fill_solid(i_fill_t *, int x, int y, int width, int channels,
59 static void fill_solidf(i_fill_t *, int x, int y, int width, int channels,
61 static void fill_solid_comb(i_fill_t *, int x, int y, int width, int channels,
63 static void fill_solidf_comb(i_fill_t *, int x, int y, int width,
64 int channels, i_fcolor *);
66 static i_fill_solid_t base_solid_fill =
75 static i_fill_solid_t base_solid_fill_comb =
86 i_fill_destroy(i_fill_t *fill) {
88 (fill->destroy)(fill);
93 i_new_fill_solidf(i_fcolor *c, int combine) {
95 i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
97 if (combine && c->channel[3] < 1.0)
98 *fill = base_solid_fill_comb;
100 *fill = base_solid_fill;
102 for (ch = 0; ch < MAXCHANNELS; ++ch) {
103 fill->c.channel[ch] = SampleFTo8(c->channel[ch]);
110 i_new_fill_solid(i_color *c, int combine) {
112 i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
114 if (combine && c->channel[3] < 255)
115 *fill = base_solid_fill_comb;
117 *fill = base_solid_fill;
119 for (ch = 0; ch < MAXCHANNELS; ++ch) {
120 fill->fc.channel[ch] = Sample8ToF(c->channel[ch]);
126 #define T_SOLID_FILL(fill) ((i_fill_solid_t *)(fill))
129 fill_solid(i_fill_t *fill, int x, int y, int width, int channels,
131 while (width-- > 0) {
132 *data++ = T_SOLID_FILL(fill)->c;
137 fill_solidf(i_fill_t *fill, int x, int y, int width, int channels,
139 while (width-- > 0) {
140 *data++ = T_SOLID_FILL(fill)->fc;
145 fill_solid_comb(i_fill_t *fill, int x, int y, int width, int channels,
147 i_color c = T_SOLID_FILL(fill)->c;
149 while (width-- > 0) {
150 COMBINE(*data, c, channels);
156 fill_solidf_comb(i_fill_t *fill, int x, int y, int width, int channels,
158 i_fcolor c = T_SOLID_FILL(fill)->fc;
160 while (width-- > 0) {
161 COMBINEF(*data, c, channels);
167 builtin_hatches[][8] =
170 /* 1x1 checkerboard */
171 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
174 /* 2x2 checkerboard */
175 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33,
178 /* 4 x 4 checkerboard */
179 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F,
182 /* single vertical lines */
183 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
186 /* double vertical lines */
187 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
190 /* quad vertical lines */
191 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
195 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
203 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
207 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
211 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
215 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88,
219 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11,
223 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
227 0xFF, 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88,
231 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA,
235 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
243 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
247 0x48, 0x84, 0x00, 0x00, 0x84, 0x48, 0x00, 0x00,
251 0x55, 0xFD, 0x05, 0xFD, 0x55, 0xDF, 0x50, 0xDF,
254 /* single cross hatch */
255 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x01,
258 /* double cross hatch */
259 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11,
262 /* vertical lozenge */
263 0x11, 0x11, 0x11, 0xAA, 0x44, 0x44, 0x44, 0xAA,
266 /* horizontal lozenge */
267 0x88, 0x70, 0x88, 0x07, 0x88, 0x70, 0x88, 0x07,
270 /* scales overlapping downwards */
271 0x80, 0x80, 0x41, 0x3E, 0x08, 0x08, 0x14, 0xE3,
274 /* scales overlapping upwards */
275 0xC7, 0x28, 0x10, 0x10, 0x7C, 0x82, 0x01, 0x01,
278 /* scales overlapping leftwards */
279 0x83, 0x84, 0x88, 0x48, 0x38, 0x48, 0x88, 0x84,
282 /* scales overlapping rightwards */
283 0x21, 0x11, 0x12, 0x1C, 0x12, 0x11, 0x21, 0xC1,
287 0x44, 0x88, 0x22, 0x11, 0x44, 0x88, 0x22, 0x11,
291 0xFF, 0x84, 0x84, 0x9C, 0x94, 0x9C, 0x90, 0x90,
295 0x80, 0x40, 0x20, 0x00, 0x02, 0x04, 0x08, 0x00,
304 unsigned char hatch[8];
308 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
310 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
315 i_new_hatch_low(i_color *fg, i_color *bg, i_fcolor *ffg, i_fcolor *fbg,
316 int combine, int hatch, unsigned char *cust_hatch,
318 i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t));
320 fill->base.fill_with_color = fill_hatch;
321 fill->base.fill_with_fcolor = fill_hatchf;
322 fill->base.destroy = NULL;
323 fill->fg = fg ? *fg : fcolor_to_color(ffg);
324 fill->bg = bg ? *bg : fcolor_to_color(fbg);
325 fill->ffg = ffg ? *ffg : color_to_fcolor(fg);
326 fill->fbg = fbg ? *fbg : color_to_fcolor(bg);
327 fill->base.combines =
328 combine && (fill->ffg.channel[0] < 1 || fill->fbg.channel[0] < 1);
330 memcpy(fill->hatch, cust_hatch, 8);
333 if (hatch > sizeof(builtin_hatches)/sizeof(*builtin_hatches))
335 memcpy(fill->hatch, builtin_hatches[hatch], 8);
344 i_new_fill_hatch(i_color *fg, i_color *bg, int combine, int hatch,
345 unsigned char *cust_hatch, int dx, int dy) {
346 return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch,
351 i_new_fill_hatchf(i_fcolor *fg, i_fcolor *bg, int combine, int hatch,
352 unsigned char *cust_hatch, int dx, int dy) {
353 return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch,
357 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
359 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
360 int byte = f->hatch[(y + f->dy) & 7];
361 int xpos = (x + f->dx) & 7;
362 int mask = 128 >> xpos;
364 while (width-- > 0) {
365 i_color c = (byte & mask) ? f->fg : f->bg;
367 if (f->base.combines) {
368 COMBINE(*data, c, channels);
374 if ((mask >>= 1) == 0)
379 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
381 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
382 int byte = f->hatch[(y + f->dy) & 7];
383 int xpos = (x + f->dx) & 7;
384 int mask = 128 >> xpos;
386 while (width-- > 0) {
387 i_fcolor c = (byte & mask) ? f->ffg : f->fbg;
389 if (f->base.combines) {
390 COMBINE(*data, c, channels);
396 if ((mask >>= 1) == 0)