7 fills.c - implements the basic general fills
15 fill = i_new_fill_solidf(&fc1, combine);
16 fill = i_new_fill_solid(&c1, combine);
17 fill = i_new_fill_hatchf(&fc1, &fc2, combine, hatch, cust_hash, dx, dy);
18 fill = i_new_fill_hatch(&c1, &c2, combine, hatch, cust_hash, dx, dy);
23 Implements the basic general fills, which can be used for filling some
24 shapes and for flood fills.
26 Each fill can implement up to 3 functions:
32 called for fills on 8-bit images. This can be NULL in which case the
33 fill_with_colorf function is called.
35 =item fill_with_fcolor
37 called for fills on non-8-bit images or when fill_with_color is NULL.
41 called by i_fill_destroy() if non-NULL, to release any extra resources
42 that the fill may need.
46 fill_with_color and fill_with_fcolor are basically the same function
47 except that the first works with lines of i_color and the second with
50 If the combines member if non-zero the line data is populated from the
51 target image before calling fill_with_*color.
53 fill_with_color needs to fill the I<data> parameter with the fill
54 pixels. If combines is non-zero it the fill pixels should be combined
55 with the existing data.
57 The current fills are:
75 Fountain fill is implemented by L<filters.c>.
82 static i_color fcolor_to_color(i_fcolor *c) {
86 for (ch = 0; ch < MAXCHANNELS; ++ch)
87 out.channel[ch] = SampleFTo8(c->channel[ch]);
90 static i_fcolor color_to_fcolor(i_color *c) {
94 for (ch = 0; ch < MAXCHANNELS; ++ch)
95 out.channel[ch] = Sample8ToF(c->channel[ch]);
105 #define COMBINE(out, in, channels) \
108 for (ch = 0; ch < (channels); ++ch) { \
109 (out).channel[ch] = ((out).channel[ch] * (255 - (in).channel[3]) \
110 + (in).channel[ch] * (in).channel[3]) / 255; \
114 #define COMBINEF(out, in, channels) \
117 for (ch = 0; ch < (channels); ++ch) { \
118 (out).channel[ch] = (out).channel[ch] * (1.0 - (in).channel[3]) \
119 + (in).channel[ch] * (in).channel[3]; \
123 static void fill_solid(i_fill_t *, int x, int y, int width, int channels,
125 static void fill_solidf(i_fill_t *, int x, int y, int width, int channels,
127 static void fill_solid_comb(i_fill_t *, int x, int y, int width, int channels,
129 static void fill_solidf_comb(i_fill_t *, int x, int y, int width,
130 int channels, i_fcolor *);
132 static i_fill_solid_t base_solid_fill =
141 static i_fill_solid_t base_solid_fill_comb =
152 =item i_fill_destroy(fill)
154 Call to destroy any fill object.
160 i_fill_destroy(i_fill_t *fill) {
162 (fill->destroy)(fill);
167 =item i_new_fill_solidf(color, combine)
169 Create a solid fill based on a float color.
171 If combine is non-zero then alpha values will be combined.
177 i_new_fill_solidf(i_fcolor *c, int combine) {
179 i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
181 if (combine && c->channel[3] < 1.0)
182 *fill = base_solid_fill_comb;
184 *fill = base_solid_fill;
186 for (ch = 0; ch < MAXCHANNELS; ++ch) {
187 fill->c.channel[ch] = SampleFTo8(c->channel[ch]);
194 =item i_new_fill_solid(color, combine)
196 Create a solid fill based.
198 If combine is non-zero then alpha values will be combined.
204 i_new_fill_solid(i_color *c, int combine) {
206 i_fill_solid_t *fill = mymalloc(sizeof(i_fill_solid_t));
208 if (combine && c->channel[3] < 255)
209 *fill = base_solid_fill_comb;
211 *fill = base_solid_fill;
213 for (ch = 0; ch < MAXCHANNELS; ++ch) {
214 fill->fc.channel[ch] = Sample8ToF(c->channel[ch]);
221 builtin_hatches[][8] =
224 /* 1x1 checkerboard */
225 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
228 /* 2x2 checkerboard */
229 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33,
232 /* 4 x 4 checkerboard */
233 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F,
236 /* single vertical lines */
237 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
240 /* double vertical lines */
241 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
244 /* quad vertical lines */
245 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
249 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
253 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
257 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
261 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
265 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
269 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88,
273 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11,
277 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
281 0xFF, 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88,
285 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA,
289 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
297 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
301 0x48, 0x84, 0x00, 0x00, 0x84, 0x48, 0x00, 0x00,
305 0x55, 0xFD, 0x05, 0xFD, 0x55, 0xDF, 0x50, 0xDF,
308 /* single cross hatch */
309 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x01,
312 /* double cross hatch */
313 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11,
316 /* vertical lozenge */
317 0x11, 0x11, 0x11, 0xAA, 0x44, 0x44, 0x44, 0xAA,
320 /* horizontal lozenge */
321 0x88, 0x70, 0x88, 0x07, 0x88, 0x70, 0x88, 0x07,
324 /* scales overlapping downwards */
325 0x80, 0x80, 0x41, 0x3E, 0x08, 0x08, 0x14, 0xE3,
328 /* scales overlapping upwards */
329 0xC7, 0x28, 0x10, 0x10, 0x7C, 0x82, 0x01, 0x01,
332 /* scales overlapping leftwards */
333 0x83, 0x84, 0x88, 0x48, 0x38, 0x48, 0x88, 0x84,
336 /* scales overlapping rightwards */
337 0x21, 0x11, 0x12, 0x1C, 0x12, 0x11, 0x21, 0xC1,
341 0x44, 0x88, 0x22, 0x11, 0x44, 0x88, 0x22, 0x11,
345 0xFF, 0x84, 0x84, 0x9C, 0x94, 0x9C, 0x90, 0x90,
349 0x80, 0x40, 0x20, 0x00, 0x02, 0x04, 0x08, 0x00,
358 unsigned char hatch[8];
362 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
364 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
368 i_new_hatch_low(i_color *fg, i_color *bg, i_fcolor *ffg, i_fcolor *fbg,
369 int combine, int hatch, unsigned char *cust_hatch,
373 =item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
375 Creates a new hatched fill with the fg color used for the 1 bits in
376 the hatch and bg for the 0 bits. If combine is non-zero alpha values
379 If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
380 hash definition, with the high-bits to the left.
382 If cust_hatch is NULL then one of the standard hatches is used.
384 (dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
389 i_new_fill_hatch(i_color *fg, i_color *bg, int combine, int hatch,
390 unsigned char *cust_hatch, int dx, int dy) {
391 return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch,
396 =item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
398 Creates a new hatched fill with the fg color used for the 1 bits in
399 the hatch and bg for the 0 bits. If combine is non-zero alpha values
402 If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
403 hash definition, with the high-bits to the left.
405 If cust_hatch is NULL then one of the standard hatches is used.
407 (dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
412 i_new_fill_hatchf(i_fcolor *fg, i_fcolor *bg, int combine, int hatch,
413 unsigned char *cust_hatch, int dx, int dy) {
414 return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch,
418 #define T_SOLID_FILL(fill) ((i_fill_solid_t *)(fill))
423 =head1 INTERNAL FUNCTIONS
427 =item fill_solid(fill, x, y, width, channels, data)
429 The 8-bit sample fill function for non-combining solid fills.
434 fill_solid(i_fill_t *fill, int x, int y, int width, int channels,
436 while (width-- > 0) {
437 *data++ = T_SOLID_FILL(fill)->c;
442 =item fill_solid(fill, x, y, width, channels, data)
444 The floating sample fill function for non-combining solid fills.
449 fill_solidf(i_fill_t *fill, int x, int y, int width, int channels,
451 while (width-- > 0) {
452 *data++ = T_SOLID_FILL(fill)->fc;
457 =item fill_solid_comb(fill, x, y, width, channels, data)
459 The 8-bit sample fill function for combining solid fills.
464 fill_solid_comb(i_fill_t *fill, int x, int y, int width, int channels,
466 i_color c = T_SOLID_FILL(fill)->c;
468 while (width-- > 0) {
469 COMBINE(*data, c, channels);
475 =item fill_solidf_comb(fill, x, y, width, channels, data)
477 The floating sample fill function for combining solid fills.
482 fill_solidf_comb(i_fill_t *fill, int x, int y, int width, int channels,
484 i_fcolor c = T_SOLID_FILL(fill)->fc;
486 while (width-- > 0) {
487 COMBINEF(*data, c, channels);
493 =item i_new_hatch_low(fg, bg, ffg, fbg, combine, hatch, cust_hatch, dx, dy)
495 Implements creation of hatch fill objects.
501 i_new_hatch_low(i_color *fg, i_color *bg, i_fcolor *ffg, i_fcolor *fbg,
502 int combine, int hatch, unsigned char *cust_hatch,
504 i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t));
506 fill->base.fill_with_color = fill_hatch;
507 fill->base.fill_with_fcolor = fill_hatchf;
508 fill->base.destroy = NULL;
509 fill->fg = fg ? *fg : fcolor_to_color(ffg);
510 fill->bg = bg ? *bg : fcolor_to_color(fbg);
511 fill->ffg = ffg ? *ffg : color_to_fcolor(fg);
512 fill->fbg = fbg ? *fbg : color_to_fcolor(bg);
513 fill->base.combines =
514 combine && (fill->ffg.channel[0] < 1 || fill->fbg.channel[0] < 1);
516 memcpy(fill->hatch, cust_hatch, 8);
519 if (hatch > sizeof(builtin_hatches)/sizeof(*builtin_hatches))
521 memcpy(fill->hatch, builtin_hatches[hatch], 8);
530 =item fill_hatch(fill, x, y, width, channels, data)
532 The 8-bit sample fill function for hatched fills.
536 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
538 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
539 int byte = f->hatch[(y + f->dy) & 7];
540 int xpos = (x + f->dx) & 7;
541 int mask = 128 >> xpos;
543 while (width-- > 0) {
544 i_color c = (byte & mask) ? f->fg : f->bg;
546 if (f->base.combines) {
547 COMBINE(*data, c, channels);
553 if ((mask >>= 1) == 0)
559 =item fill_hatchf(fill, x, y, width, channels, data)
561 The floating sample fill function for hatched fills.
565 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
567 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
568 int byte = f->hatch[(y + f->dy) & 7];
569 int xpos = (x + f->dx) & 7;
570 int mask = 128 >> xpos;
572 while (width-- > 0) {
573 i_fcolor c = (byte & mask) ? f->ffg : f->fbg;
575 if (f->base.combines) {
576 COMBINE(*data, c, channels);
582 if ((mask >>= 1) == 0)
592 Tony Cook <tony@develop-help.com>