Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | |||
3 | /* PDF 1.4 blend modes. These are slow. */ |
||
4 | |||
5 | typedef unsigned char byte; |
||
6 | |||
7 | static const char *fz_blendmode_names[] = |
||
8 | { |
||
9 | "Normal", |
||
10 | "Multiply", |
||
11 | "Screen", |
||
12 | "Overlay", |
||
13 | "Darken", |
||
14 | "Lighten", |
||
15 | "ColorDodge", |
||
16 | "ColorBurn", |
||
17 | "HardLight", |
||
18 | "SoftLight", |
||
19 | "Difference", |
||
20 | "Exclusion", |
||
21 | "Hue", |
||
22 | "Saturation", |
||
23 | "Color", |
||
24 | "Luminosity", |
||
25 | }; |
||
26 | |||
27 | int fz_find_blendmode(char *name) |
||
28 | { |
||
29 | int i; |
||
30 | for (i = 0; i < nelem(fz_blendmode_names); i++) |
||
31 | if (!strcmp(name, fz_blendmode_names[i])) |
||
32 | return i; |
||
33 | return FZ_BLEND_NORMAL; |
||
34 | } |
||
35 | |||
36 | char *fz_blendmode_name(int blendmode) |
||
37 | { |
||
38 | if (blendmode >= 0 && blendmode < nelem(fz_blendmode_names)) |
||
39 | return (char*)fz_blendmode_names[blendmode]; |
||
40 | return "Normal"; |
||
41 | } |
||
42 | |||
43 | /* Separable blend modes */ |
||
44 | |||
45 | static inline int fz_screen_byte(int b, int s) |
||
46 | { |
||
47 | return b + s - fz_mul255(b, s); |
||
48 | } |
||
49 | |||
50 | static inline int fz_hard_light_byte(int b, int s) |
||
51 | { |
||
52 | int s2 = s << 1; |
||
53 | if (s <= 127) |
||
54 | return fz_mul255(b, s2); |
||
55 | else |
||
56 | return fz_screen_byte(b, s2 - 255); |
||
57 | } |
||
58 | |||
59 | static inline int fz_overlay_byte(int b, int s) |
||
60 | { |
||
61 | return fz_hard_light_byte(s, b); /* note swapped order */ |
||
62 | } |
||
63 | |||
64 | static inline int fz_darken_byte(int b, int s) |
||
65 | { |
||
66 | return MIN(b, s); |
||
67 | } |
||
68 | |||
69 | static inline int fz_lighten_byte(int b, int s) |
||
70 | { |
||
71 | return MAX(b, s); |
||
72 | } |
||
73 | |||
74 | static inline int fz_color_dodge_byte(int b, int s) |
||
75 | { |
||
76 | s = 255 - s; |
||
77 | if (b == 0) |
||
78 | return 0; |
||
79 | else if (b >= s) |
||
80 | return 255; |
||
81 | else |
||
82 | return (0x1fe * b + s) / (s << 1); |
||
83 | } |
||
84 | |||
85 | static inline int fz_color_burn_byte(int b, int s) |
||
86 | { |
||
87 | b = 255 - b; |
||
88 | if (b == 0) |
||
89 | return 255; |
||
90 | else if (b >= s) |
||
91 | return 0; |
||
92 | else |
||
93 | return 0xff - (0x1fe * b + s) / (s << 1); |
||
94 | } |
||
95 | |||
96 | static inline int fz_soft_light_byte(int b, int s) |
||
97 | { |
||
98 | /* review this */ |
||
99 | if (s < 128) { |
||
100 | return b - fz_mul255(fz_mul255((255 - (s<<1)), b), 255 - b); |
||
101 | } |
||
102 | else { |
||
103 | int dbd; |
||
104 | if (b < 64) |
||
105 | dbd = fz_mul255(fz_mul255((b << 4) - 12, b) + 4, b); |
||
106 | else |
||
107 | dbd = (int)sqrtf(255.0f * b); |
||
108 | return b + fz_mul255(((s<<1) - 255), (dbd - b)); |
||
109 | } |
||
110 | } |
||
111 | |||
112 | static inline int fz_difference_byte(int b, int s) |
||
113 | { |
||
114 | return ABS(b - s); |
||
115 | } |
||
116 | |||
117 | static inline int fz_exclusion_byte(int b, int s) |
||
118 | { |
||
119 | return b + s - (fz_mul255(b, s)<<1); |
||
120 | } |
||
121 | |||
122 | /* Non-separable blend modes */ |
||
123 | |||
124 | static void |
||
125 | fz_luminosity_rgb(int *rd, int *gd, int *bd, int rb, int gb, int bb, int rs, int gs, int bs) |
||
126 | { |
||
127 | int delta, scale; |
||
128 | int r, g, b, y; |
||
129 | |||
130 | /* 0.3, 0.59, 0.11 in fixed point */ |
||
131 | delta = ((rs - rb) * 77 + (gs - gb) * 151 + (bs - bb) * 28 + 0x80) >> 8; |
||
132 | r = rb + delta; |
||
133 | g = gb + delta; |
||
134 | b = bb + delta; |
||
135 | |||
136 | if ((r | g | b) & 0x100) |
||
137 | { |
||
138 | y = (rs * 77 + gs * 151 + bs * 28 + 0x80) >> 8; |
||
139 | if (delta > 0) |
||
140 | { |
||
141 | int max; |
||
142 | max = MAX(r, MAX(g, b)); |
||
143 | scale = ((255 - y) << 16) / (max - y); |
||
144 | } |
||
145 | else |
||
146 | { |
||
147 | int min; |
||
148 | min = MIN(r, MIN(g, b)); |
||
149 | scale = (y << 16) / (y - min); |
||
150 | } |
||
151 | r = y + (((r - y) * scale + 0x8000) >> 16); |
||
152 | g = y + (((g - y) * scale + 0x8000) >> 16); |
||
153 | b = y + (((b - y) * scale + 0x8000) >> 16); |
||
154 | } |
||
155 | |||
156 | *rd = r; |
||
157 | *gd = g; |
||
158 | *bd = b; |
||
159 | } |
||
160 | |||
161 | static void |
||
162 | fz_saturation_rgb(int *rd, int *gd, int *bd, int rb, int gb, int bb, int rs, int gs, int bs) |
||
163 | { |
||
164 | int minb, maxb; |
||
165 | int mins, maxs; |
||
166 | int y; |
||
167 | int scale; |
||
168 | int r, g, b; |
||
169 | |||
170 | minb = MIN(rb, MIN(gb, bb)); |
||
171 | maxb = MAX(rb, MAX(gb, bb)); |
||
172 | if (minb == maxb) |
||
173 | { |
||
174 | /* backdrop has zero saturation, avoid divide by 0 */ |
||
175 | *rd = gb; |
||
176 | *gd = gb; |
||
177 | *bd = gb; |
||
178 | return; |
||
179 | } |
||
180 | |||
181 | mins = MIN(rs, MIN(gs, bs)); |
||
182 | maxs = MAX(rs, MAX(gs, bs)); |
||
183 | |||
184 | scale = ((maxs - mins) << 16) / (maxb - minb); |
||
185 | y = (rb * 77 + gb * 151 + bb * 28 + 0x80) >> 8; |
||
186 | r = y + ((((rb - y) * scale) + 0x8000) >> 16); |
||
187 | g = y + ((((gb - y) * scale) + 0x8000) >> 16); |
||
188 | b = y + ((((bb - y) * scale) + 0x8000) >> 16); |
||
189 | |||
190 | if ((r | g | b) & 0x100) |
||
191 | { |
||
192 | int scalemin, scalemax; |
||
193 | int min, max; |
||
194 | |||
195 | min = MIN(r, MIN(g, b)); |
||
196 | max = MAX(r, MAX(g, b)); |
||
197 | |||
198 | if (min < 0) |
||
199 | scalemin = (y << 16) / (y - min); |
||
200 | else |
||
201 | scalemin = 0x10000; |
||
202 | |||
203 | if (max > 255) |
||
204 | scalemax = ((255 - y) << 16) / (max - y); |
||
205 | else |
||
206 | scalemax = 0x10000; |
||
207 | |||
208 | scale = MIN(scalemin, scalemax); |
||
209 | r = y + (((r - y) * scale + 0x8000) >> 16); |
||
210 | g = y + (((g - y) * scale + 0x8000) >> 16); |
||
211 | b = y + (((b - y) * scale + 0x8000) >> 16); |
||
212 | } |
||
213 | |||
214 | *rd = r; |
||
215 | *gd = g; |
||
216 | *bd = b; |
||
217 | } |
||
218 | |||
219 | static void |
||
220 | fz_color_rgb(int *rr, int *rg, int *rb, int br, int bg, int bb, int sr, int sg, int sb) |
||
221 | { |
||
222 | fz_luminosity_rgb(rr, rg, rb, sr, sg, sb, br, bg, bb); |
||
223 | } |
||
224 | |||
225 | static void |
||
226 | fz_hue_rgb(int *rr, int *rg, int *rb, int br, int bg, int bb, int sr, int sg, int sb) |
||
227 | { |
||
228 | int tr, tg, tb; |
||
229 | fz_luminosity_rgb(&tr, &tg, &tb, sr, sg, sb, br, bg, bb); |
||
230 | fz_saturation_rgb(rr, rg, rb, tr, tg, tb, br, bg, bb); |
||
231 | } |
||
232 | |||
233 | /* Blending loops */ |
||
234 | |||
235 | void |
||
236 | fz_blend_separable(byte * restrict bp, byte * restrict sp, int n, int w, int blendmode) |
||
237 | { |
||
238 | int k; |
||
239 | int n1 = n - 1; |
||
240 | while (w--) |
||
241 | { |
||
242 | int sa = sp[n1]; |
||
243 | int ba = bp[n1]; |
||
244 | int saba = fz_mul255(sa, ba); |
||
245 | |||
246 | /* ugh, division to get non-premul components */ |
||
247 | int invsa = sa ? 255 * 256 / sa : 0; |
||
248 | int invba = ba ? 255 * 256 / ba : 0; |
||
249 | |||
250 | for (k = 0; k < n1; k++) |
||
251 | { |
||
252 | int sc = (sp[k] * invsa) >> 8; |
||
253 | int bc = (bp[k] * invba) >> 8; |
||
254 | int rc; |
||
255 | |||
256 | switch (blendmode) |
||
257 | { |
||
258 | default: |
||
259 | case FZ_BLEND_NORMAL: rc = sc; break; |
||
260 | case FZ_BLEND_MULTIPLY: rc = fz_mul255(bc, sc); break; |
||
261 | case FZ_BLEND_SCREEN: rc = fz_screen_byte(bc, sc); break; |
||
262 | case FZ_BLEND_OVERLAY: rc = fz_overlay_byte(bc, sc); break; |
||
263 | case FZ_BLEND_DARKEN: rc = fz_darken_byte(bc, sc); break; |
||
264 | case FZ_BLEND_LIGHTEN: rc = fz_lighten_byte(bc, sc); break; |
||
265 | case FZ_BLEND_COLOR_DODGE: rc = fz_color_dodge_byte(bc, sc); break; |
||
266 | case FZ_BLEND_COLOR_BURN: rc = fz_color_burn_byte(bc, sc); break; |
||
267 | case FZ_BLEND_HARD_LIGHT: rc = fz_hard_light_byte(bc, sc); break; |
||
268 | case FZ_BLEND_SOFT_LIGHT: rc = fz_soft_light_byte(bc, sc); break; |
||
269 | case FZ_BLEND_DIFFERENCE: rc = fz_difference_byte(bc, sc); break; |
||
270 | case FZ_BLEND_EXCLUSION: rc = fz_exclusion_byte(bc, sc); break; |
||
271 | } |
||
272 | |||
273 | bp[k] = fz_mul255(255 - sa, bp[k]) + fz_mul255(255 - ba, sp[k]) + fz_mul255(saba, rc); |
||
274 | } |
||
275 | |||
276 | bp[k] = ba + sa - saba; |
||
277 | |||
278 | sp += n; |
||
279 | bp += n; |
||
280 | } |
||
281 | } |
||
282 | |||
283 | void |
||
284 | fz_blend_nonseparable(byte * restrict bp, byte * restrict sp, int w, int blendmode) |
||
285 | { |
||
286 | while (w--) |
||
287 | { |
||
288 | int rr, rg, rb; |
||
289 | |||
290 | int sa = sp[3]; |
||
291 | int ba = bp[3]; |
||
292 | int saba = fz_mul255(sa, ba); |
||
293 | |||
294 | /* ugh, division to get non-premul components */ |
||
295 | int invsa = sa ? 255 * 256 / sa : 0; |
||
296 | int invba = ba ? 255 * 256 / ba : 0; |
||
297 | |||
298 | int sr = (sp[0] * invsa) >> 8; |
||
299 | int sg = (sp[1] * invsa) >> 8; |
||
300 | int sb = (sp[2] * invsa) >> 8; |
||
301 | |||
302 | int br = (bp[0] * invba) >> 8; |
||
303 | int bg = (bp[1] * invba) >> 8; |
||
304 | int bb = (bp[2] * invba) >> 8; |
||
305 | |||
306 | switch (blendmode) |
||
307 | { |
||
308 | default: |
||
309 | case FZ_BLEND_HUE: |
||
310 | fz_hue_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
311 | break; |
||
312 | case FZ_BLEND_SATURATION: |
||
313 | fz_saturation_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
314 | break; |
||
315 | case FZ_BLEND_COLOR: |
||
316 | fz_color_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
317 | break; |
||
318 | case FZ_BLEND_LUMINOSITY: |
||
319 | fz_luminosity_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
320 | break; |
||
321 | } |
||
322 | |||
323 | bp[0] = fz_mul255(255 - sa, bp[0]) + fz_mul255(255 - ba, sp[0]) + fz_mul255(saba, rr); |
||
324 | bp[1] = fz_mul255(255 - sa, bp[1]) + fz_mul255(255 - ba, sp[1]) + fz_mul255(saba, rg); |
||
325 | bp[2] = fz_mul255(255 - sa, bp[2]) + fz_mul255(255 - ba, sp[2]) + fz_mul255(saba, rb); |
||
326 | bp[3] = ba + sa - saba; |
||
327 | |||
328 | sp += 4; |
||
329 | bp += 4; |
||
330 | } |
||
331 | } |
||
332 | |||
333 | static void |
||
334 | fz_blend_separable_nonisolated(byte * restrict bp, byte * restrict sp, int n, int w, int blendmode, byte * restrict hp, int alpha) |
||
335 | { |
||
336 | int k; |
||
337 | int n1 = n - 1; |
||
338 | |||
339 | if (alpha == 255 && blendmode == 0) |
||
340 | { |
||
341 | /* In this case, the uncompositing and the recompositing |
||
342 | * cancel one another out, and it's just a simple copy. */ |
||
343 | /* FIXME: Maybe we can avoid using the shape plane entirely |
||
344 | * and just copy? */ |
||
345 | while (w--) |
||
346 | { |
||
347 | int ha = fz_mul255(*hp++, alpha); /* ha = shape_alpha */ |
||
348 | /* If ha == 0 then leave everything unchanged */ |
||
349 | if (ha != 0) |
||
350 | { |
||
351 | for (k = 0; k < n; k++) |
||
352 | { |
||
353 | bp[k] = sp[k]; |
||
354 | } |
||
355 | } |
||
356 | |||
357 | sp += n; |
||
358 | bp += n; |
||
359 | } |
||
360 | return; |
||
361 | } |
||
362 | while (w--) |
||
363 | { |
||
364 | int ha = *hp++; |
||
365 | int haa = fz_mul255(ha, alpha); /* ha = shape_alpha */ |
||
366 | /* If haa == 0 then leave everything unchanged */ |
||
367 | if (haa != 0) |
||
368 | { |
||
369 | int sa = sp[n1]; |
||
370 | int ba = bp[n1]; |
||
371 | int baha = fz_mul255(ba, haa); |
||
372 | |||
373 | /* ugh, division to get non-premul components */ |
||
374 | int invsa = sa ? 255 * 256 / sa : 0; |
||
375 | int invba = ba ? 255 * 256 / ba : 0; |
||
376 | |||
377 | /* Calculate result_alpha */ |
||
378 | int ra = bp[n1] = ba - baha + haa; |
||
379 | |||
380 | /* Because we are a non-isolated group, we need to |
||
381 | * 'uncomposite' before we blend (recomposite). |
||
382 | * We assume that normal blending has been done inside |
||
383 | * the group, so: ra.rc = (1-ha).bc + ha.sc |
||
384 | * A bit of rearrangement, and that gives us that: |
||
385 | * sc = (ra.rc - bc)/ha + bc |
||
386 | * Now, the result of the blend was stored in src, so: |
||
387 | */ |
||
388 | int invha = ha ? 255 * 256 / ha : 0; |
||
389 | |||
390 | if (ra != 0) for (k = 0; k < n1; k++) |
||
391 | { |
||
392 | int sc = (sp[k] * invsa) >> 8; |
||
393 | int bc = (bp[k] * invba) >> 8; |
||
394 | int rc; |
||
395 | |||
396 | /* Uncomposite */ |
||
397 | sc = (((sc-bc)*invha)>>8) + bc; |
||
398 | if (sc < 0) sc = 0; |
||
399 | if (sc > 255) sc = 255; |
||
400 | |||
401 | switch (blendmode) |
||
402 | { |
||
403 | default: |
||
404 | case FZ_BLEND_NORMAL: rc = sc; break; |
||
405 | case FZ_BLEND_MULTIPLY: rc = fz_mul255(bc, sc); break; |
||
406 | case FZ_BLEND_SCREEN: rc = fz_screen_byte(bc, sc); break; |
||
407 | case FZ_BLEND_OVERLAY: rc = fz_overlay_byte(bc, sc); break; |
||
408 | case FZ_BLEND_DARKEN: rc = fz_darken_byte(bc, sc); break; |
||
409 | case FZ_BLEND_LIGHTEN: rc = fz_lighten_byte(bc, sc); break; |
||
410 | case FZ_BLEND_COLOR_DODGE: rc = fz_color_dodge_byte(bc, sc); break; |
||
411 | case FZ_BLEND_COLOR_BURN: rc = fz_color_burn_byte(bc, sc); break; |
||
412 | case FZ_BLEND_HARD_LIGHT: rc = fz_hard_light_byte(bc, sc); break; |
||
413 | case FZ_BLEND_SOFT_LIGHT: rc = fz_soft_light_byte(bc, sc); break; |
||
414 | case FZ_BLEND_DIFFERENCE: rc = fz_difference_byte(bc, sc); break; |
||
415 | case FZ_BLEND_EXCLUSION: rc = fz_exclusion_byte(bc, sc); break; |
||
416 | } |
||
417 | rc = fz_mul255(255 - haa, bc) + fz_mul255(fz_mul255(255 - ba, sc), haa) + fz_mul255(baha, rc); |
||
418 | if (rc < 0) rc = 0; |
||
419 | if (rc > 255) rc = 255; |
||
420 | bp[k] = fz_mul255(rc, ra); |
||
421 | } |
||
422 | } |
||
423 | |||
424 | sp += n; |
||
425 | bp += n; |
||
426 | } |
||
427 | } |
||
428 | |||
429 | static void |
||
430 | fz_blend_nonseparable_nonisolated(byte * restrict bp, byte * restrict sp, int w, int blendmode, byte * restrict hp, int alpha) |
||
431 | { |
||
432 | while (w--) |
||
433 | { |
||
434 | int ha = *hp++; |
||
435 | int haa = fz_mul255(ha, alpha); |
||
436 | if (haa != 0) |
||
437 | { |
||
438 | int sa = sp[3]; |
||
439 | int ba = bp[3]; |
||
440 | int baha = fz_mul255(ba, haa); |
||
441 | |||
442 | /* Calculate result_alpha */ |
||
443 | int ra = bp[3] = ba - baha + haa; |
||
444 | if (ra != 0) |
||
445 | { |
||
446 | /* Because we are a non-isolated group, we |
||
447 | * need to 'uncomposite' before we blend |
||
448 | * (recomposite). We assume that normal |
||
449 | * blending has been done inside the group, |
||
450 | * so: ra.rc = (1-ha).bc + ha.sc |
||
451 | * A bit of rearrangement, and that gives us |
||
452 | * that: sc = (ra.rc - bc)/ha + bc |
||
453 | * Now, the result of the blend was stored in |
||
454 | * src, so: */ |
||
455 | int invha = ha ? 255 * 256 / ha : 0; |
||
456 | |||
457 | int rr, rg, rb; |
||
458 | |||
459 | /* ugh, division to get non-premul components */ |
||
460 | int invsa = sa ? 255 * 256 / sa : 0; |
||
461 | int invba = ba ? 255 * 256 / ba : 0; |
||
462 | |||
463 | int sr = (sp[0] * invsa) >> 8; |
||
464 | int sg = (sp[1] * invsa) >> 8; |
||
465 | int sb = (sp[2] * invsa) >> 8; |
||
466 | |||
467 | int br = (bp[0] * invba) >> 8; |
||
468 | int bg = (bp[1] * invba) >> 8; |
||
469 | int bb = (bp[2] * invba) >> 8; |
||
470 | |||
471 | /* Uncomposite */ |
||
472 | sr = (((sr-br)*invha)>>8) + br; |
||
473 | sg = (((sg-bg)*invha)>>8) + bg; |
||
474 | sb = (((sb-bb)*invha)>>8) + bb; |
||
475 | |||
476 | switch (blendmode) |
||
477 | { |
||
478 | default: |
||
479 | case FZ_BLEND_HUE: |
||
480 | fz_hue_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
481 | break; |
||
482 | case FZ_BLEND_SATURATION: |
||
483 | fz_saturation_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
484 | break; |
||
485 | case FZ_BLEND_COLOR: |
||
486 | fz_color_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
487 | break; |
||
488 | case FZ_BLEND_LUMINOSITY: |
||
489 | fz_luminosity_rgb(&rr, &rg, &rb, br, bg, bb, sr, sg, sb); |
||
490 | break; |
||
491 | } |
||
492 | |||
493 | rr = fz_mul255(255 - haa, bp[0]) + fz_mul255(fz_mul255(255 - ba, sr), haa) + fz_mul255(baha, rr); |
||
494 | rg = fz_mul255(255 - haa, bp[1]) + fz_mul255(fz_mul255(255 - ba, sg), haa) + fz_mul255(baha, rg); |
||
495 | rb = fz_mul255(255 - haa, bp[2]) + fz_mul255(fz_mul255(255 - ba, sb), haa) + fz_mul255(baha, rb); |
||
496 | bp[0] = fz_mul255(ra, rr); |
||
497 | bp[1] = fz_mul255(ra, rg); |
||
498 | bp[2] = fz_mul255(ra, rb); |
||
499 | } |
||
500 | } |
||
501 | |||
502 | sp += 4; |
||
503 | bp += 4; |
||
504 | } |
||
505 | } |
||
506 | |||
507 | void |
||
508 | fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape) |
||
509 | { |
||
510 | unsigned char *sp, *dp; |
||
511 | fz_bbox bbox; |
||
512 | int x, y, w, h, n; |
||
513 | |||
514 | /* TODO: fix this hack! */ |
||
515 | if (isolated && alpha < 255) |
||
516 | { |
||
517 | sp = src->samples; |
||
518 | n = src->w * src->h * src->n; |
||
519 | while (n--) |
||
520 | { |
||
521 | *sp = fz_mul255(*sp, alpha); |
||
522 | sp++; |
||
523 | } |
||
524 | } |
||
525 | |||
526 | bbox = fz_bound_pixmap(dst); |
||
527 | bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src)); |
||
528 | |||
529 | x = bbox.x0; |
||
530 | y = bbox.y0; |
||
531 | w = bbox.x1 - bbox.x0; |
||
532 | h = bbox.y1 - bbox.y0; |
||
533 | |||
534 | n = src->n; |
||
535 | sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * n; |
||
536 | dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * n; |
||
537 | |||
538 | assert(src->n == dst->n); |
||
539 | |||
540 | if (!isolated) |
||
541 | { |
||
542 | unsigned char *hp = shape->samples + (y - shape->y) * shape->w + (x - shape->x); |
||
543 | |||
544 | while (h--) |
||
545 | { |
||
546 | if (n == 4 && blendmode >= FZ_BLEND_HUE) |
||
547 | fz_blend_nonseparable_nonisolated(dp, sp, w, blendmode, hp, alpha); |
||
548 | else |
||
549 | fz_blend_separable_nonisolated(dp, sp, n, w, blendmode, hp, alpha); |
||
550 | sp += src->w * n; |
||
551 | dp += dst->w * n; |
||
552 | hp += shape->w; |
||
553 | } |
||
554 | } |
||
555 | else |
||
556 | { |
||
557 | while (h--) |
||
558 | { |
||
559 | if (n == 4 && blendmode >= FZ_BLEND_HUE) |
||
560 | fz_blend_nonseparable(dp, sp, w, blendmode); |
||
561 | else |
||
562 | fz_blend_separable(dp, sp, n, w, blendmode); |
||
563 | sp += src->w * n; |
||
564 | dp += dst->w * n; |
||
565 | } |
||
566 | } |
||
567 | }>>>>>>><>><>>><>><>><>1); |