]> git.imager.perl.org - imager.git/blame - compose.im
correct changes - we search for font handlers not fonts
[imager.git] / compose.im
CommitLineData
9b1ec2b8
TC
1#include "imager.h"
2#include "imrender.h"
3#include "imageri.h"
4
5int
6i_compose_mask(i_img *out, i_img *src, i_img *mask,
7 int out_left, int out_top,
8 int src_left, int src_top,
9 int mask_left, int mask_top,
10 int width, int height,
11 int combine,
12 double opacity) {
13 i_render r;
14 int dy;
15 i_fill_combine_f combinef_8;
16 i_fill_combinef_f combinef_double;
17 int channel_zero = 0;
18
19 i_clear_error();
20 if (out_left >= out->xsize
21 || out_top >= out->ysize
22 || src_left >= src->xsize
23 || src_top >= src->ysize
24 || width <= 0
25 || height <= 0
26 || out_left + width <= 0
27 || out_top + height <= 0
28 || src_left + width <= 0
29 || src_top + height <= 0
30 || mask_left >= mask->xsize
31 || mask_top >= mask->ysize
32 || mask_left + width <= 0
33 || mask_top + height <= 0)
34 return 0;
35
36 if (out_left < 0) {
37 width = out_left + width;
38 out_left = 0;
39 }
40 if (out_left + width > out->xsize)
41 width = out->xsize - out_left;
42
43 if (out_top < 0) {
44 height = out_top + height;
45 out_top = 0;
46 }
47 if (out_top + height > out->ysize)
48 height = out->ysize - out_top;
49
50 if (src_left < 0) {
51 width = src_left + width;
52 src_left = 0;
53 }
54 if (src_left + width > src->xsize)
55 width = src->xsize - src_left;
56
57 if (src_top < 0) {
58 height = src_top + height;
59 src_top = 0;
60 }
61 if (src_top + height > src->ysize)
62 height = src->ysize - src_left;
63
64 if (mask_left < 0) {
65 width = mask_left + width;
66 mask_left = 0;
67 }
68 if (mask_left + width > mask->xsize)
69 width = mask->xsize - mask_left;
70
71 if (mask_top < 0) {
72 height = mask->ysize + height;
73 mask_top = 0;
74 }
75 if (mask_top + height > mask->ysize)
76 height = mask->xsize - mask_top;
77
78 if (opacity > 1.0)
79 opacity = 1.0;
80 else if (opacity <= 0)
81 return 0;
82
83 i_get_combine(combine, &combinef_8, &combinef_double);
84
85 i_render_init(&r, out, width);
86#code out->bits <= 8 && src->bits<= 8 && mask->bits <= 8
87 IM_COLOR *src_line = mymalloc(sizeof(IM_COLOR) * width);
88 IM_SAMPLE_T *mask_line = mymalloc(sizeof(IM_SAMPLE_T) * width);
89 int adapt_channels = out->channels;
90
91 if (adapt_channels == 1 || adapt_channels == 3)
92 ++adapt_channels;
93
94 for (dy = 0; dy < height; ++dy) {
95 IM_GLIN(src, src_left, src_left + width, src_top + dy, src_line);
96 IM_ADAPT_COLORS(adapt_channels, src->channels, src_line, width);
97 IM_GSAMP(mask, mask_left, mask_left + width, mask_top + dy,
98 mask_line, &channel_zero, 1);
99 if (opacity < 1.0) {
100 int i;
101 IM_SAMPLE_T *maskp = mask_line;
102 for (i = 0; i < width; ++i) {
103 *maskp = IM_ROUND(*maskp * opacity);
104 ++maskp;
105 }
106 }
107 IM_RENDER_LINE(&r, out_left, out_top+dy, width, mask_line, src_line,
108 IM_SUFFIX(combinef));
109 }
110 myfree(src_line);
111 myfree(mask_line);
112
113#/code
114 i_render_done(&r);
115
116 return 1;
117}
118
119int
120i_compose(i_img *out, i_img *src,
121 int out_left, int out_top,
122 int src_left, int src_top,
123 int width, int height,
124 int combine,
125 double opacity) {
126 i_render r;
127 int dy;
128 i_fill_combine_f combinef_8;
129 i_fill_combinef_f combinef_double;
130
131 i_clear_error();
132 if (out_left >= out->xsize
133 || out_top >= out->ysize
134 || src_left >= src->xsize
135 || src_top >= src->ysize
136 || width <= 0
137 || height <= 0
138 || out_left + width <= 0
139 || out_top + height <= 0
140 || src_left + width <= 0
141 || src_top + height <= 0)
142 return 0;
143
144 if (out_left < 0) {
145 width = out_left + width;
146 out_left = 0;
147 }
148 if (out_left + width > out->xsize)
149 width = out->xsize - out_left;
150
151 if (out_top < 0) {
152 height = out_top + height;
153 out_top = 0;
154 }
155 if (out_top + height > out->ysize)
156 height = out->ysize - out_top;
157
158 if (src_left < 0) {
159 width = src_left + width;
160 src_left = 0;
161 }
162 if (src_left + width > src->xsize)
163 width = src->xsize - src_left;
164
165 if (src_top < 0) {
166 height = src_top + height;
167 src_top = 0;
168 }
169 if (src_top + height > src->ysize)
170 height = src->ysize - src_left;
171
172 if (opacity > 1.0)
173 opacity = 1.0;
174 else if (opacity <= 0)
175 return 0;
176
177 i_get_combine(combine, &combinef_8, &combinef_double);
178
179 i_render_init(&r, out, width);
180#code out->bits <= 8 && src->bits <= 8
181 IM_COLOR *src_line = mymalloc(sizeof(IM_COLOR) * width);
182 IM_SAMPLE_T *mask_line = NULL;
183 int adapt_channels = out->channels;
184
185 if (opacity != 1.0) {
186 int i;
187 IM_SAMPLE_T mask_value = IM_ROUND(opacity * IM_SAMPLE_MAX);
188 mask_line = mymalloc(sizeof(IM_SAMPLE_T) * width);
189
190 for (i = 0; i < width; ++i)
191 mask_line[i] = mask_value;
192 }
193
194 if (adapt_channels == 1 || adapt_channels == 3)
195 ++adapt_channels;
196
197 for (dy = 0; dy < height; ++dy) {
198 IM_GLIN(src, src_left, src_left + width, src_top + dy, src_line);
199 IM_ADAPT_COLORS(adapt_channels, src->channels, src_line, width);
200 IM_RENDER_LINE(&r, out_left, out_top+dy, width, mask_line, src_line,
201 IM_SUFFIX(combinef));
202 }
203 myfree(src_line);
204 if (mask_line)
205 myfree(mask_line);
206
207#/code
208 i_render_done(&r);
209
210 return 1;
211}