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,
300 unsigned char hatch[8];
304 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
306 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
311 i_new_hatch_low(i_color *fg, i_color *bg, i_fcolor *ffg, i_fcolor *fbg,
312 int combine, int hatch, unsigned char *cust_hatch,
314 i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t));
316 fill->base.fill_with_color = fill_hatch;
317 fill->base.fill_with_fcolor = fill_hatchf;
318 fill->base.destroy = NULL;
319 fill->fg = fg ? *fg : fcolor_to_color(ffg);
320 fill->bg = bg ? *bg : fcolor_to_color(fbg);
321 fill->ffg = ffg ? *ffg : color_to_fcolor(fg);
322 fill->fbg = fbg ? *fbg : color_to_fcolor(bg);
323 fill->base.combines =
324 combine && (fill->ffg.channel[0] < 1 || fill->fbg.channel[0] < 1);
326 memcpy(fill->hatch, cust_hatch, 8);
329 if (hatch > sizeof(builtin_hatches)/sizeof(*builtin_hatches))
331 memcpy(fill->hatch, builtin_hatches[hatch], 8);
340 i_new_fill_hatch(i_color *fg, i_color *bg, int combine, int hatch,
341 unsigned char *cust_hatch, int dx, int dy) {
342 return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch,
347 i_new_fill_hatchf(i_fcolor *fg, i_fcolor *bg, int combine, int hatch,
348 unsigned char *cust_hatch, int dx, int dy) {
349 return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch,
353 static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
355 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
356 int byte = f->hatch[(y + f->dy) & 7];
357 int xpos = (x + f->dx) & 7;
358 int mask = 128 >> xpos;
360 while (width-- > 0) {
361 i_color c = (byte & mask) ? f->fg : f->bg;
363 if (f->base.combines) {
364 COMBINE(*data, c, channels);
370 if ((mask >>= 1) == 0)
375 static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels,
377 i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
378 int byte = f->hatch[(y + f->dy) & 7];
379 int xpos = (x + f->dx) & 7;
380 int mask = 128 >> xpos;
382 while (width-- > 0) {
383 i_fcolor c = (byte & mask) ? f->ffg : f->fbg;
385 if (f->base.combines) {
386 COMBINE(*data, c, channels);
392 if ((mask >>= 1) == 0)