Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 : #ifndef X_DISPLAY_MISSING
28 : #include "gxdrawP.h"
29 : #include "gxcdrawP.h"
30 : #include <math.h>
31 : #include <string.h>
32 :
33 : /* On the cygwin X server masking with mono images is broken */
34 : #ifdef _BrokenBitmapImages
35 : # undef FAST_BITS
36 : # define FAST_BITS 0
37 : #endif
38 :
39 : /* On some X displays (my linux box for instance) bitmap drawing is very */
40 : /* slow when compared to 24bit drawing. So if FAST_BITS is set then use */
41 : /* 1 bit masks otherwise use the depth of the screen */
42 : #ifndef FAST_BITS
43 : #define FAST_BITS 0
44 : #endif
45 :
46 0 : static void intersect_rectangles(GRect *rect, GRect *clip) {
47 0 : if ( rect->x < clip->x ) {
48 0 : rect->width -= (clip->x - rect->x);
49 0 : if ( rect->width < 0 ) rect->width = 0;
50 0 : rect->x = clip->x;
51 : }
52 0 : if ( rect->x + rect->width > clip->x + clip->width ) {
53 0 : rect->width = clip->x + clip->width - rect->x;
54 0 : if ( rect->width < 0 ) rect->width = 0;
55 : }
56 0 : if ( rect->y < clip->y ) {
57 0 : rect->height -= (clip->y - rect->y);
58 0 : if ( rect->height < 0 ) rect->height = 0;
59 0 : rect->y = clip->y;
60 : }
61 0 : if ( rect->y + rect->height > clip->y + clip->height ) {
62 0 : rect->height = clip->y + clip->height - rect->y;
63 0 : if ( rect->height < 0 ) rect->height = 0;
64 : }
65 0 : }
66 :
67 0 : static void gdraw_8_on_1_nomag_dithered_masked(GXDisplay *gdisp,GImage *image,
68 : GRect *src) {
69 : struct gcol clut[256];
70 : int i,j, index;
71 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
72 0 : int trans = base->trans;
73 : unsigned char *pt, *ipt, *mpt;
74 : short *g_d;
75 : register int gd;
76 : struct gcol *pos;
77 : int bit;
78 :
79 0 : _GDraw_getimageclut(base,clut);
80 :
81 0 : for ( i=src->width-1; i>=0; --i )
82 0 : gdisp->gg.green_dith[i] = 0;
83 :
84 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
85 0 : pt = (unsigned char *) (base->data) + i*base->bytes_per_line + src->x;
86 0 : ipt = (unsigned char *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
87 0 : mpt = (unsigned char *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
88 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst )
89 0 : bit = 0x80;
90 : else
91 0 : bit = 0x1;
92 0 : gd = 0;
93 0 : g_d = gdisp->gg.green_dith;
94 0 : for ( j=src->width-1; j>=0; --j ) {
95 0 : index = *pt++;
96 0 : if ( index==trans ) {
97 0 : *mpt |= bit;
98 0 : *ipt &= ~bit;
99 0 : ++g_d;
100 : } else {
101 0 : *mpt &= ~bit;
102 0 : pos = &clut[index];
103 0 : gd += *g_d + pos->red + pos->green + pos->blue;
104 0 : if ( gd<3*128 ) {
105 0 : *ipt &= ~bit;
106 0 : *g_d++ = gd /= 2;
107 : } else {
108 0 : *ipt |= bit;
109 0 : *g_d++ = gd = (gd - 3*255)/2;
110 : }
111 : }
112 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst ) {
113 0 : if (( bit>>=1 )==0 ) {bit=0x80; ++ipt; ++mpt;};
114 : } else {
115 0 : if (( bit<<=1 )==256 ) {bit=0x1; ++ipt; ++mpt;};
116 : }
117 : }
118 : }
119 0 : }
120 :
121 0 : static void gdraw_32_on_1_nomag_dithered_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
122 : int i,j, index;
123 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
124 0 : int trans = base->trans;
125 : uint32 *pt;
126 : uint8 *ipt, *mpt;
127 : short *g_d;
128 : register int gd;
129 : int bit;
130 :
131 0 : for ( i=src->width-1; i>=0; --i )
132 0 : gdisp->gg.green_dith[i] = 0;
133 :
134 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
135 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
136 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
137 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
138 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst )
139 0 : bit = 0x80;
140 : else
141 0 : bit = 0x1;
142 0 : gd = 0;
143 0 : g_d = gdisp->gg.green_dith;
144 0 : for ( j=src->width-1; j>=0; --j ) {
145 0 : index = *pt++;
146 0 : if ( index==trans ) {
147 0 : *mpt |= bit;
148 0 : *ipt &= ~bit;
149 0 : ++g_d;
150 : } else {
151 0 : *mpt &= ~bit;
152 0 : gd += *g_d + COLOR_RED(index) + COLOR_GREEN(index) + COLOR_BLUE(index);
153 0 : if ( gd<3*128 ) {
154 0 : *ipt &= ~bit;
155 0 : *g_d++ = gd /= 2;
156 : } else {
157 0 : *ipt |= bit;
158 0 : *g_d++ = gd = (gd - 3*255)/2;
159 : }
160 : }
161 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst ) {
162 0 : if (( bit>>=1 )==0 ) {bit=0x80; ++ipt; ++mpt;};
163 : } else {
164 0 : if (( bit<<=1 )==256 ) {bit=0x1; ++ipt; ++mpt;};
165 : }
166 : }
167 : }
168 0 : }
169 :
170 0 : static void gdraw_32a_on_1_nomag_dithered(GXDisplay *gdisp, GImage *image, GRect *src) {
171 : int i,j;
172 : unsigned int index;
173 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
174 0 : int trans = base->trans;
175 : uint32 *pt;
176 : uint8 *ipt, *mpt;
177 : short *g_d;
178 : register int gd;
179 : int bit;
180 :
181 0 : for ( i=src->width-1; i>=0; --i )
182 0 : gdisp->gg.green_dith[i] = 0;
183 :
184 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
185 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
186 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
187 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
188 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst )
189 0 : bit = 0x80;
190 : else
191 0 : bit = 0x1;
192 0 : gd = 0;
193 0 : g_d = gdisp->gg.green_dith;
194 0 : for ( j=src->width-1; j>=0; --j ) {
195 0 : index = *pt++;
196 0 : if ( index==trans || (index>>24)<0x80 ) {
197 0 : *mpt |= bit;
198 0 : *ipt &= ~bit;
199 0 : ++g_d;
200 : } else {
201 0 : *mpt &= ~bit;
202 0 : gd += *g_d + COLOR_RED(index) + COLOR_GREEN(index) + COLOR_BLUE(index);
203 0 : if ( gd<3*128 ) {
204 0 : *ipt &= ~bit;
205 0 : *g_d++ = gd /= 2;
206 : } else {
207 0 : *ipt |= bit;
208 0 : *g_d++ = gd = (gd - 3*255)/2;
209 : }
210 : }
211 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst ) {
212 0 : if (( bit>>=1 )==0 ) {bit=0x80; ++ipt; ++mpt;};
213 : } else {
214 0 : if (( bit<<=1 )==256 ) {bit=0x1; ++ipt; ++mpt;};
215 : }
216 : }
217 : }
218 0 : }
219 :
220 0 : static void gdraw_8_on_1_nomag_dithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
221 : struct gcol clut[256];
222 : int i,j, index;
223 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
224 : unsigned char *pt, *ipt;
225 : short *g_d;
226 : register int gd;
227 : struct gcol *pos;
228 : int bit;
229 :
230 0 : _GDraw_getimageclut(base,clut);
231 :
232 0 : for ( i=src->width-1; i>=0; --i )
233 0 : gdisp->gg.green_dith[i] = 0;
234 :
235 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
236 0 : pt = (unsigned char *) (base->data) + i*base->bytes_per_line + src->x;
237 0 : ipt = (unsigned char *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
238 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst )
239 0 : bit = 0x80;
240 : else
241 0 : bit = 0x1;
242 0 : gd = 0;
243 0 : g_d = gdisp->gg.green_dith;
244 0 : for ( j=src->width-1; j>=0; --j ) {
245 0 : index = *pt++;
246 0 : pos = &clut[index];
247 0 : gd += *g_d + pos->red + pos->green + pos->blue;
248 0 : if ( gd<3*128 ) {
249 0 : *ipt &= ~bit;
250 0 : *g_d++ = gd /= 2;
251 : } else {
252 0 : *ipt |= bit;
253 0 : *g_d++ = gd = (gd - 3*255)/2;
254 : }
255 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst ) {
256 0 : if (( bit>>=1 )==0 ) {bit=0x80; ++ipt;};
257 : } else {
258 0 : if (( bit<<=1 )==256 ) {bit=0x1; ++ipt;};
259 : }
260 : }
261 : }
262 0 : }
263 :
264 0 : static void gdraw_32_on_1_nomag_dithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
265 : struct gcol clut[256];
266 : int i,j, index;
267 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
268 : uint32 *pt;
269 : uint8 *ipt;
270 : short *g_d;
271 : register int gd;
272 : int bit;
273 :
274 0 : _GDraw_getimageclut(base,clut);
275 :
276 0 : for ( i=src->width-1; i>=0; --i )
277 0 : gdisp->gg.green_dith[i] = 0;
278 :
279 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
280 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
281 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
282 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst )
283 0 : bit = 0x80;
284 : else
285 0 : bit = 0x1;
286 0 : gd = 0;
287 0 : g_d = gdisp->gg.green_dith;
288 0 : for ( j=src->width-1; j>=0; --j ) {
289 0 : index = *pt++;
290 0 : gd += *g_d + COLOR_RED(index) + COLOR_GREEN(index) + COLOR_BLUE(index);
291 0 : if ( gd<3*128 ) {
292 0 : *ipt &= ~bit;
293 0 : *g_d++ = gd /= 2;
294 : } else {
295 0 : *ipt |= bit;
296 0 : *g_d++ = gd = (gd - 3*255)/2;
297 : }
298 0 : if ( gdisp->gg.img->bitmap_bit_order == MSBFirst ) {
299 0 : if (( bit>>=1 )==0 ) {bit=0x80; ++ipt;};
300 : } else {
301 0 : if (( bit<<=1 )==256 ) {bit=0x1; ++ipt;};
302 : }
303 : }
304 : }
305 0 : }
306 :
307 0 : static void gdraw_8_on_8_nomag_dithered_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
308 : struct gcol clut[256];
309 : int i,j, index;
310 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
311 0 : int trans = base->trans;
312 : uint8 *pt, *ipt, *mpt;
313 : short *r_d, *g_d, *b_d;
314 : register int rd, gd, bd;
315 : const struct gcol *pos;
316 : #if FAST_BITS
317 : int mbit;
318 : #endif
319 :
320 0 : _GDraw_getimageclut(base,clut);
321 :
322 0 : for ( i=src->width-1; i>=0; --i )
323 0 : gdisp->gg.red_dith[i]= gdisp->gg.green_dith[i] = gdisp->gg.blue_dith[i] = 0;
324 :
325 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
326 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
327 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
328 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
329 : #if FAST_BITS
330 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
331 : mbit = 0x80;
332 : else
333 : mbit = 0x1;
334 : #endif
335 0 : rd = gd = bd = 0;
336 0 : r_d = gdisp->gg.red_dith; g_d = gdisp->gg.green_dith; b_d = gdisp->gg.blue_dith;
337 0 : for ( j=src->width-1; j>=0; --j ) {
338 0 : index = *pt++;
339 0 : if ( index==trans ) {
340 : #if FAST_BITS==0
341 0 : *mpt++ = 0xff;
342 : #else
343 : *mpt |= mbit;
344 : #endif
345 0 : *ipt++ = 0x00;
346 0 : ++r_d; ++g_d; ++b_d;
347 : } else {
348 0 : pos = &clut[index];
349 0 : rd += *r_d + pos->red; if ( rd<0 ) rd=0; else if ( rd>255 ) rd = 255;
350 0 : gd += *g_d + pos->green; if ( gd<0 ) gd=0; else if ( gd>255 ) gd = 255;
351 0 : bd += *b_d + pos->blue; if ( bd<0 ) bd=0; else if ( bd>255 ) bd = 255;
352 0 : pos = _GImage_GetIndexedPixel(COLOR_CREATE(rd,gd,bd), gdisp->cs.rev);
353 0 : *ipt++ = pos->pixel;
354 0 : *r_d++ = rd = (rd - pos->red)/2;
355 0 : *g_d++ = gd = (gd - pos->green)/2;
356 0 : *b_d++ = bd = (bd - pos->blue)/2;
357 : #if FAST_BITS==0
358 0 : *mpt++ = 0;
359 : #else
360 : *mpt &= ~mbit;
361 : #endif
362 : }
363 : #if FAST_BITS
364 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
365 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
366 : } else {
367 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
368 : }
369 : #endif
370 : }
371 : }
372 0 : }
373 :
374 0 : static void gdraw_8_on_8_nomag_nodithered_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
375 : struct gcol clut[256];
376 : register int j;
377 : int i,index;
378 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
379 0 : int trans = base->trans;
380 : register uint8 *pt, *ipt, *mpt;
381 : struct gcol *pos; const struct gcol *temp;
382 : #if FAST_BITS
383 : int mbit;
384 : #endif
385 :
386 0 : _GDraw_getimageclut(base,clut);
387 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
388 0 : pos = &clut[i];
389 0 : temp = _GImage_GetIndexedPixel(COLOR_CREATE(pos->red,pos->green,pos->blue),gdisp->cs.rev);
390 0 : pos->pixel = temp->pixel;
391 : }
392 :
393 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
394 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
395 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
396 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
397 : #if FAST_BITS
398 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
399 : mbit = 0x80;
400 : else
401 : mbit = 0x1;
402 : #endif
403 0 : for ( j=src->width-1; j>=0; --j ) {
404 0 : index = *pt++;
405 0 : if ( index==trans ) {
406 : #if FAST_BITS==0
407 0 : *mpt++ = 0xff;
408 : #else
409 : *mpt |= mbit;
410 : #endif
411 0 : *ipt++ = 0x00;
412 : } else {
413 0 : *ipt++ = clut[index].pixel;
414 : #if FAST_BITS==0
415 0 : *mpt++ = 0;
416 : #else
417 : *mpt &= ~mbit;
418 : #endif
419 : }
420 : #if FAST_BITS
421 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
422 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
423 : } else {
424 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
425 : }
426 : #endif
427 : }
428 : }
429 0 : }
430 :
431 0 : static void gdraw_32_on_8_nomag_dithered_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
432 : int i,j;
433 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
434 0 : int trans = base->trans;
435 : uint32 *pt, index;
436 : uint8 *ipt, *mpt;
437 : short *r_d, *g_d, *b_d;
438 : register int rd, gd, bd;
439 : const struct gcol *pos;
440 : #if FAST_BITS
441 : int mbit;
442 : #endif
443 :
444 0 : for ( i=src->width-1; i>=0; --i )
445 0 : gdisp->gg.red_dith[i]= gdisp->gg.green_dith[i] = gdisp->gg.blue_dith[i] = 0;
446 :
447 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
448 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
449 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
450 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
451 : #if FAST_BITS
452 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
453 : mbit = 0x80;
454 : else
455 : mbit = 0x1;
456 : #endif
457 0 : rd = gd = bd = 0;
458 0 : r_d = gdisp->gg.red_dith; g_d = gdisp->gg.green_dith; b_d = gdisp->gg.blue_dith;
459 0 : for ( j=src->width-1; j>=0; --j ) {
460 0 : index = *pt++;
461 0 : if ( index==trans ) {
462 : #if FAST_BITS==0
463 0 : *mpt++ = 0xff;
464 : #else
465 : *mpt |= mbit;
466 : #endif
467 0 : *ipt++ = 0x00;
468 0 : ++r_d; ++g_d; ++b_d;
469 : } else {
470 0 : rd += *r_d + ((index>>16)&0xff); if ( rd<0 ) rd=0; else if ( rd>255 ) rd = 255;
471 0 : gd += *g_d + ((index>>8)&0xff); if ( gd<0 ) gd=0; else if ( gd>255 ) gd = 255;
472 0 : bd += *b_d + (index&0xff); if ( bd<0 ) bd=0; else if ( bd>255 ) bd = 255;
473 0 : pos = _GImage_GetIndexedPixel(COLOR_CREATE(rd,gd,bd),gdisp->cs.rev);
474 0 : *ipt++ = pos->pixel;
475 0 : *r_d++ = rd = (rd - pos->red)/2;
476 0 : *g_d++ = gd = (gd - pos->green)/2;
477 0 : *b_d++ = bd = (bd - pos->blue)/2;
478 : #if FAST_BITS==0
479 0 : *mpt++ = 0;
480 : #else
481 : *mpt &= ~mbit;
482 : #endif
483 : }
484 : #if FAST_BITS
485 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
486 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
487 : } else {
488 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
489 : }
490 : #endif
491 : }
492 : }
493 0 : }
494 :
495 0 : static void gdraw_32a_on_8_nomag_dithered(GXDisplay *gdisp, GImage *image, GRect *src) {
496 : int i,j;
497 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
498 0 : int trans = base->trans;
499 : uint32 *pt, index;
500 : uint8 *ipt, *mpt;
501 : short *r_d, *g_d, *b_d;
502 : register int rd, gd, bd;
503 : const struct gcol *pos;
504 : #if FAST_BITS
505 : int mbit;
506 : #endif
507 :
508 0 : for ( i=src->width-1; i>=0; --i )
509 0 : gdisp->gg.red_dith[i]= gdisp->gg.green_dith[i] = gdisp->gg.blue_dith[i] = 0;
510 :
511 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
512 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
513 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
514 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
515 : #if FAST_BITS
516 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
517 : mbit = 0x80;
518 : else
519 : mbit = 0x1;
520 : #endif
521 0 : rd = gd = bd = 0;
522 0 : r_d = gdisp->gg.red_dith; g_d = gdisp->gg.green_dith; b_d = gdisp->gg.blue_dith;
523 0 : for ( j=src->width-1; j>=0; --j ) {
524 0 : index = *pt++;
525 0 : if ( index==trans || (index>>24)<0x80 ) {
526 : #if FAST_BITS==0
527 0 : *mpt++ = 0xff;
528 : #else
529 : *mpt |= mbit;
530 : #endif
531 0 : *ipt++ = 0x00;
532 0 : ++r_d; ++g_d; ++b_d;
533 : } else {
534 0 : rd += *r_d + ((index>>16)&0xff); if ( rd<0 ) rd=0; else if ( rd>255 ) rd = 255;
535 0 : gd += *g_d + ((index>>8)&0xff); if ( gd<0 ) gd=0; else if ( gd>255 ) gd = 255;
536 0 : bd += *b_d + (index&0xff); if ( bd<0 ) bd=0; else if ( bd>255 ) bd = 255;
537 0 : pos = _GImage_GetIndexedPixel(COLOR_CREATE(rd,gd,bd),gdisp->cs.rev);
538 0 : *ipt++ = pos->pixel;
539 0 : *r_d++ = rd = (rd - pos->red)/2;
540 0 : *g_d++ = gd = (gd - pos->green)/2;
541 0 : *b_d++ = bd = (bd - pos->blue)/2;
542 : #if FAST_BITS==0
543 0 : *mpt++ = 0;
544 : #else
545 : *mpt &= ~mbit;
546 : #endif
547 : }
548 : #if FAST_BITS
549 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
550 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
551 : } else {
552 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
553 : }
554 : #endif
555 : }
556 : }
557 0 : }
558 :
559 0 : static void gdraw_32_on_8_nomag_nodithered_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
560 : int i,j;
561 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
562 0 : int trans = base->trans;
563 : uint32 *pt, index;
564 : register uint8 *ipt, *mpt;
565 : #if FAST_BITS
566 : int mbit;
567 : #endif
568 :
569 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
570 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
571 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
572 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
573 : #if FAST_BITS
574 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
575 : mbit = 0x80;
576 : else
577 : mbit = 0x1;
578 : #endif
579 0 : for ( j=src->width-1; j>=0; --j ) {
580 0 : index = *pt++;
581 0 : if ( index==trans ) {
582 : #if FAST_BITS==0
583 0 : *mpt++ = 0xff;
584 : #else
585 : *mpt |= mbit;
586 : #endif
587 0 : *ipt++ = 0x00;
588 : } else {
589 0 : *ipt++ = _GXDraw_GetScreenPixel(gdisp,index);
590 : #if FAST_BITS==0
591 0 : *mpt++ = 0;
592 : #else
593 : *mpt &= ~mbit;
594 : #endif
595 : }
596 : #if FAST_BITS
597 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
598 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
599 : } else {
600 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
601 : }
602 : #endif
603 : }
604 : }
605 0 : }
606 :
607 0 : static void gdraw_32a_on_8_nomag_nodithered(GXDisplay *gdisp, GImage *image, GRect *src) {
608 : int i,j;
609 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
610 0 : int trans = base->trans;
611 : uint32 *pt, index;
612 : register uint8 *ipt, *mpt;
613 : #if FAST_BITS
614 : int mbit;
615 : #endif
616 :
617 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
618 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
619 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
620 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
621 : #if FAST_BITS
622 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
623 : mbit = 0x80;
624 : else
625 : mbit = 0x1;
626 : #endif
627 0 : for ( j=src->width-1; j>=0; --j ) {
628 0 : index = *pt++;
629 0 : if ( (index==trans && trans!=-1 ) || (index>>24)<0x80 ) {
630 : #if FAST_BITS==0
631 0 : *mpt++ = 0xff;
632 : #else
633 : *mpt |= mbit;
634 : #endif
635 0 : *ipt++ = 0x00;
636 : } else {
637 0 : *ipt++ = _GXDraw_GetScreenPixel(gdisp,index);
638 : #if FAST_BITS==0
639 0 : *mpt++ = 0;
640 : #else
641 : *mpt &= ~mbit;
642 : #endif
643 : }
644 : #if FAST_BITS
645 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
646 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
647 : } else {
648 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
649 : }
650 : #endif
651 : }
652 : }
653 0 : }
654 :
655 0 : static void gdraw_8_on_8_nomag_dithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
656 : struct gcol clut[256];
657 : int i,j, index;
658 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
659 : uint8 *pt, *ipt;
660 : short *r_d, *g_d, *b_d;
661 : register int rd, gd, bd;
662 : const struct gcol *pos;
663 :
664 0 : _GDraw_getimageclut(base,clut);
665 :
666 0 : for ( i=src->width-1; i>=0; --i )
667 0 : gdisp->gg.red_dith[i]= gdisp->gg.green_dith[i] = gdisp->gg.blue_dith[i] = 0;
668 :
669 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
670 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
671 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
672 0 : rd = gd = bd = 0;
673 0 : r_d = gdisp->gg.red_dith; g_d = gdisp->gg.green_dith; b_d = gdisp->gg.blue_dith;
674 0 : for ( j=src->width-1; j>=0; --j ) {
675 0 : index = *pt++;
676 0 : pos = &clut[index];
677 0 : rd += *r_d + pos->red; if ( rd<0 ) rd=0; else if ( rd>255 ) rd = 255;
678 0 : gd += *g_d + pos->green; if ( gd<0 ) gd=0; else if ( gd>255 ) gd = 255;
679 0 : bd += *b_d + pos->blue; if ( bd<0 ) bd=0; else if ( bd>255 ) bd = 255;
680 0 : pos = _GImage_GetIndexedPixel(COLOR_CREATE(rd,gd,bd),gdisp->cs.rev);
681 0 : *ipt++ = pos->pixel;
682 0 : *r_d++ = rd = (rd - pos->red)/2;
683 0 : *g_d++ = gd = (gd - pos->green)/2;
684 0 : *b_d++ = bd = (bd - pos->blue)/2;
685 : }
686 : }
687 0 : }
688 :
689 0 : static void gdraw_8_on_8_nomag_nodithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
690 : struct gcol clut[256];
691 : register int j;
692 : int i,index;
693 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
694 : register uint8 *pt, *ipt;
695 : struct gcol *pos; const struct gcol *temp;
696 :
697 0 : _GDraw_getimageclut(base,clut);
698 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
699 0 : pos = &clut[i];
700 0 : temp = _GImage_GetIndexedPixel(COLOR_CREATE(pos->red,pos->green,pos->blue),gdisp->cs.rev);
701 0 : pos->pixel = temp->pixel;
702 : }
703 :
704 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
705 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
706 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
707 0 : for ( j=src->width-1; j>=0; --j ) {
708 0 : index = *pt++;
709 0 : *ipt++ = clut[index].pixel;
710 : }
711 : }
712 0 : }
713 :
714 0 : static void gdraw_32_on_8_nomag_dithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
715 : int i,j;
716 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
717 : uint32 *pt, index;
718 : uint8 *ipt;
719 : short *r_d, *g_d, *b_d;
720 : register int rd, gd, bd;
721 : const struct gcol *pos;
722 :
723 0 : for ( i=src->width-1; i>=0; --i )
724 0 : gdisp->gg.red_dith[i]= gdisp->gg.green_dith[i] = gdisp->gg.blue_dith[i] = 0;
725 :
726 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
727 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
728 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
729 0 : rd = gd = bd = 0;
730 0 : r_d = gdisp->gg.red_dith; g_d = gdisp->gg.green_dith; b_d = gdisp->gg.blue_dith;
731 0 : for ( j=src->width-1; j>=0; --j ) {
732 0 : index = *pt++;
733 0 : rd += *r_d + COLOR_RED(index); if ( rd<0 ) rd=0; else if ( rd>255 ) rd = 255;
734 0 : gd += *g_d + COLOR_GREEN(index); if ( gd<0 ) gd=0; else if ( gd>255 ) gd = 255;
735 0 : bd += *b_d + COLOR_BLUE(index); if ( bd<0 ) bd=0; else if ( bd>255 ) bd = 255;
736 0 : pos = _GImage_GetIndexedPixel(COLOR_CREATE(rd,gd,bd),gdisp->cs.rev);
737 0 : *ipt++ = pos->pixel;
738 0 : *r_d++ = rd = (rd - pos->red)/2;
739 0 : *g_d++ = gd = (gd - pos->green)/2;
740 0 : *b_d++ = bd = (bd - pos->blue)/2;
741 : }
742 : }
743 0 : }
744 :
745 0 : static void gdraw_32_on_8_nomag_nodithered_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
746 : int i,j;
747 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
748 : uint32 *pt, index;
749 : register uint8 *ipt;
750 :
751 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
752 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
753 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
754 0 : for ( j=src->width-1; j>=0; --j ) {
755 0 : index = *pt++;
756 0 : *ipt++ = _GXDraw_GetScreenPixel(gdisp,index);
757 : }
758 : }
759 0 : }
760 :
761 0 : static void gdraw_8_on_16_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
762 : struct gcol clut[256];
763 : register int j;
764 : int i,index;
765 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
766 0 : int trans = base->trans;
767 : #if FAST_BITS==0
768 : uint16 *mpt;
769 : #else
770 : int mbit;
771 : uint8 *mpt;
772 : #endif
773 : register uint8 *pt;
774 : uint16 *ipt;
775 : struct gcol *pos;
776 : Color col;
777 :
778 0 : _GDraw_getimageclut(base,clut);
779 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
780 0 : pos = &clut[i];
781 0 : col = (pos->red<<16)|(pos->green<<8)|pos->blue;
782 0 : pos->pixel = Pixel16(gdisp,col);
783 0 : if ( gdisp->endian_mismatch )
784 0 : pos->pixel = FixEndian16(pos->pixel);
785 : }
786 :
787 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
788 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
789 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
790 : #if FAST_BITS==0
791 0 : mpt = (uint16 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
792 : #else
793 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
794 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
795 : mbit = 0x80;
796 : else
797 : mbit = 0x1;
798 : #endif
799 0 : for ( j=src->width-1; j>=0; --j ) {
800 0 : index = *pt++;
801 0 : if ( index==trans ) {
802 : #if FAST_BITS==0
803 0 : *mpt++ = 0xffff;
804 : #else
805 : *mpt |= mbit;
806 : #endif
807 0 : *ipt++ = 0x00;
808 : } else {
809 0 : *ipt++ = clut[index].pixel;
810 : #if FAST_BITS==0
811 0 : *mpt++ = 0;
812 : #else
813 : *mpt &= ~mbit;
814 : #endif
815 : }
816 : #if FAST_BITS
817 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
818 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
819 : } else {
820 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
821 : }
822 : #endif
823 : }
824 : }
825 0 : }
826 :
827 0 : static void gdraw_32_on_16_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
828 : int i,j;
829 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
830 0 : int trans = base->trans;
831 : register uint32 *pt, index;
832 : register uint16 *ipt;
833 0 : int endian_mismatch = gdisp->endian_mismatch;
834 : #if FAST_BITS==0
835 : register uint16 *mpt;
836 : #else
837 : register uint8 *mpt;
838 : int mbit;
839 : #endif
840 :
841 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
842 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
843 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
844 : #if FAST_BITS==0
845 0 : mpt = (uint16 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
846 : #else
847 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
848 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
849 : mbit = 0x80;
850 : else
851 : mbit = 0x1;
852 : #endif
853 0 : for ( j=src->width-1; j>=0; --j ) {
854 0 : index = *pt++;
855 0 : if ( index==trans ) {
856 0 : *ipt++ = 0x00;
857 : #if FAST_BITS==0
858 0 : *mpt++ = 0xffff;
859 : #else
860 : *mpt |= mbit;
861 : #endif
862 : } else {
863 0 : *ipt++ = Pixel16(gdisp,index);
864 0 : if ( endian_mismatch )
865 0 : ipt[-1] = FixEndian16(ipt[-1]);
866 : #if FAST_BITS==0
867 0 : *mpt++ = 0;
868 : #else
869 : *mpt &= ~mbit;
870 : #endif
871 : }
872 : #if FAST_BITS
873 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
874 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
875 : } else {
876 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
877 : }
878 : #endif
879 : }
880 : }
881 0 : }
882 :
883 0 : static void gdraw_32a_on_16_nomag(GXDisplay *gdisp, GImage *image, GRect *src) {
884 : int i,j;
885 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
886 0 : int trans = base->trans;
887 : register uint32 *pt, index;
888 : register uint16 *ipt;
889 0 : int endian_mismatch = gdisp->endian_mismatch;
890 : #if FAST_BITS==0
891 : register uint16 *mpt;
892 : #else
893 : register uint8 *mpt;
894 : int mbit;
895 : #endif
896 :
897 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
898 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
899 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
900 : #if FAST_BITS==0
901 0 : mpt = (uint16 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
902 : #else
903 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
904 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
905 : mbit = 0x80;
906 : else
907 : mbit = 0x1;
908 : #endif
909 0 : for ( j=src->width-1; j>=0; --j ) {
910 0 : index = *pt++;
911 0 : if ( (index==trans && trans!=-1 ) || (index>>24)<0x80 ) {
912 0 : *ipt++ = 0x00;
913 : #if FAST_BITS==0
914 0 : *mpt++ = 0xffff;
915 : #else
916 : *mpt |= mbit;
917 : #endif
918 : } else {
919 0 : *ipt++ = Pixel16(gdisp,index);
920 0 : if ( endian_mismatch )
921 0 : ipt[-1] = FixEndian16(ipt[-1]);
922 : #if FAST_BITS==0
923 0 : *mpt++ = 0;
924 : #else
925 : *mpt &= ~mbit;
926 : #endif
927 : }
928 : #if FAST_BITS
929 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
930 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
931 : } else {
932 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
933 : }
934 : #endif
935 : }
936 : }
937 0 : }
938 :
939 0 : static void gdraw_8_on_16_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
940 : struct gcol clut[256];
941 : register int j;
942 : int i,index;
943 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
944 : register uint8 *pt;
945 : uint16 *ipt;
946 : struct gcol *pos;
947 : Color col;
948 :
949 0 : _GDraw_getimageclut(base,clut);
950 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
951 0 : pos = &clut[i];
952 0 : col = (pos->red<<16)|(pos->green<<8)|pos->blue;
953 0 : pos->pixel = Pixel16(gdisp,col);
954 0 : if ( gdisp->endian_mismatch )
955 0 : pos->pixel = FixEndian16(pos->pixel);
956 : }
957 :
958 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
959 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
960 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
961 0 : for ( j=src->width-1; j>=0; --j ) {
962 0 : index = *pt++;
963 0 : *ipt++ = clut[index].pixel;
964 : }
965 : }
966 0 : }
967 :
968 0 : static void gdraw_32_on_16_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
969 : int i,j;
970 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
971 : register uint32 *pt, index;
972 : register uint16 *ipt;
973 0 : int endian_mismatch = gdisp->endian_mismatch;
974 :
975 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
976 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
977 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
978 0 : for ( j=src->width-1; j>=0; --j ) {
979 0 : index = *pt++;
980 0 : *ipt++ = Pixel16(gdisp,index);
981 0 : if ( endian_mismatch )
982 0 : ipt[-1] = FixEndian16(ipt[-1]);
983 : }
984 : }
985 0 : }
986 :
987 0 : static void gdraw_8_on_any_nomag_glyph(GXDisplay *gdisp, GImage *image, GRect *src) {
988 : struct gcol clut[256];
989 : register int j;
990 : int i,index;
991 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
992 0 : int trans = base->trans;
993 : register uint8 *pt;
994 : struct gcol *pos;
995 : Color col;
996 0 : int msbf = gdisp->gg.img->byte_order == MSBFirst/*,
997 : msBf = gdisp->gg.mask->bitmap_bit_order == MSBFirst*/;
998 :
999 0 : _GDraw_getimageclut(base,clut);
1000 :
1001 0 : if ( gdisp->pixel_size==16 ) {
1002 : uint16 *ipt;
1003 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1004 0 : pos = &clut[i];
1005 0 : col = (pos->red<<16)|(pos->green<<8)|pos->blue;
1006 0 : pos->pixel = Pixel16(gdisp,col);
1007 0 : if ( i==trans )
1008 0 : pos->pixel = Pixel16(gdisp,0xffffff);
1009 0 : if ( gdisp->endian_mismatch )
1010 0 : pos->pixel = FixEndian16(pos->pixel);
1011 : }
1012 :
1013 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1014 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1015 0 : ipt = (uint16 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1016 0 : for ( j=src->width-1; j>=0; --j ) {
1017 0 : index = *pt++;
1018 0 : *ipt++ = clut[index].pixel;
1019 : }
1020 : }
1021 0 : } else if ( gdisp->pixel_size==24 ) {
1022 : uint8 *ipt;
1023 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1024 0 : pos = &clut[i];
1025 0 : pos->pixel = Pixel24(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1026 0 : if ( i==trans )
1027 0 : pos->pixel = Pixel24(gdisp,0xffffff);
1028 : }
1029 :
1030 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1031 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1032 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1033 0 : for ( j=src->width-1; j>=0; --j ) {
1034 : register uint32 col;
1035 0 : index = *pt++;
1036 0 : col = clut[index].pixel;
1037 0 : if ( msbf ) {
1038 0 : *ipt++ = col>>16;
1039 0 : *ipt++ = (col>>8)&0xff;
1040 0 : *ipt++ = col&0xff;
1041 : } else {
1042 0 : *ipt++ = col&0xff;
1043 0 : *ipt++ = (col>>8)&0xff;
1044 0 : *ipt++ = col>>16;
1045 : }
1046 : }
1047 : }
1048 : } else {
1049 : uint32 *ipt;
1050 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1051 0 : pos = &clut[i];
1052 0 : pos->pixel = Pixel32(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1053 0 : if ( i==trans )
1054 0 : pos->pixel = 0xffffffff;
1055 0 : if ( gdisp->endian_mismatch )
1056 0 : pos->pixel = FixEndian32(pos->pixel);
1057 : }
1058 :
1059 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1060 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1061 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1062 0 : for ( j=src->width-1; j>=0; --j ) {
1063 0 : index = *pt++;
1064 0 : *ipt++ = clut[index].pixel;
1065 : }
1066 : }
1067 : }
1068 0 : }
1069 :
1070 0 : static void gdraw_8_on_24_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
1071 : struct gcol clut[256];
1072 : register int j;
1073 : int i,index;
1074 : #if FAST_BITS
1075 : int mbit;
1076 : #endif
1077 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1078 0 : int trans = base->trans;
1079 : register uint8 *ipt;
1080 : register uint8 *pt, *mpt;
1081 : struct gcol *pos;
1082 0 : int msbf = gdisp->gg.img->byte_order == MSBFirst/*,
1083 : msBf = gdisp->gg.mask->bitmap_bit_order == MSBFirst*/;
1084 :
1085 0 : _GDraw_getimageclut(base,clut);
1086 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1087 0 : pos = &clut[i];
1088 0 : pos->pixel = Pixel24(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1089 : }
1090 :
1091 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1092 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1093 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1094 0 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
1095 : #if FAST_BITS
1096 : if ( msBf )
1097 : mbit = 0x80;
1098 : else
1099 : mbit = 0x1;
1100 : #endif
1101 0 : for ( j=src->width-1; j>=0; --j ) {
1102 0 : index = *pt++;
1103 0 : if ( index==trans ) {
1104 : #if FAST_BITS==0
1105 0 : *mpt++ = 0xff; *mpt++ = 0xff; *mpt++ = 0xff;
1106 : #else
1107 : *mpt |= mbit;
1108 : #endif
1109 0 : *ipt++ = 0x00; *ipt++ = 0x00; *ipt++ = 0x00;
1110 : } else {
1111 0 : register uint32 col = clut[index].pixel;
1112 0 : if ( msbf ) {
1113 0 : *ipt++ = col>>16;
1114 0 : *ipt++ = (col>>8)&0xff;
1115 0 : *ipt++ = col&0xff;
1116 : } else {
1117 0 : *ipt++ = col&0xff;
1118 0 : *ipt++ = (col>>8)&0xff;
1119 0 : *ipt++ = col>>16;
1120 : }
1121 : #if FAST_BITS==0
1122 0 : *mpt++ = 0; *mpt++ = 0; *mpt++ = 0;
1123 : #else
1124 : *mpt &= ~mbit;
1125 : #endif
1126 : }
1127 : #if FAST_BITS
1128 : if ( msBf ) {
1129 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt; };
1130 : } else {
1131 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1132 : }
1133 : #endif
1134 : }
1135 : }
1136 0 : }
1137 :
1138 0 : static void gdraw_32_on_24_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
1139 : int i,j;
1140 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1141 0 : int trans = base->trans;
1142 : register uint32 *pt, index;
1143 : register uint8 *mpt, *ipt;
1144 : #if FAST_BITS
1145 : int mbit;
1146 : #endif
1147 0 : int msbf = gdisp->gg.img->byte_order == MSBFirst;
1148 :
1149 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1150 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1151 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1152 0 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1153 : #if FAST_BITS
1154 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
1155 : mbit = 0x80;
1156 : else
1157 : mbit = 0x1;
1158 : #endif
1159 0 : for ( j=src->width-1; j>=0; --j ) {
1160 0 : index = *pt++;
1161 0 : if ( index==trans ) {
1162 0 : *ipt++ = 0x00; *ipt++ = 0x00; *ipt++ = 0x00;
1163 : #if FAST_BITS==0
1164 0 : *mpt++ = 0xff; *mpt++ = 0xff; *mpt++ = 0xff;
1165 : #else
1166 : *mpt |= mbit;
1167 : #endif
1168 : } else {
1169 0 : index = Pixel24(gdisp,index);
1170 0 : if ( msbf ) {
1171 0 : *ipt++ = index>>16;
1172 0 : *ipt++ = (index>>8)&0xff;
1173 0 : *ipt++ = index&0xff;
1174 : } else {
1175 0 : *ipt++ = index&0xff;
1176 0 : *ipt++ = (index>>8)&0xff;
1177 0 : *ipt++ = index>>16;
1178 : }
1179 : #if FAST_BITS==0
1180 0 : *mpt++ = 0; *mpt++ = 0; *mpt++ = 0;
1181 : #else
1182 : *mpt &= ~mbit;
1183 : #endif
1184 : }
1185 : #if FAST_BITS
1186 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
1187 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
1188 : } else {
1189 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1190 : }
1191 : #endif
1192 : }
1193 : }
1194 0 : }
1195 :
1196 0 : static void gdraw_32a_on_24_nomag(GXDisplay *gdisp, GImage *image, GRect *src) {
1197 : int i,j;
1198 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1199 0 : int trans = base->trans;
1200 : register uint32 *pt, index;
1201 : register uint8 *mpt, *ipt;
1202 : #if FAST_BITS
1203 : int mbit;
1204 : #endif
1205 0 : int msbf = gdisp->gg.img->byte_order == MSBFirst;
1206 :
1207 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1208 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1209 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1210 0 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1211 : #if FAST_BITS
1212 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
1213 : mbit = 0x80;
1214 : else
1215 : mbit = 0x1;
1216 : #endif
1217 0 : for ( j=src->width-1; j>=0; --j ) {
1218 0 : index = *pt++;
1219 0 : if ( (index==trans && trans!=-1) || (index>>24)<0x80 ) {
1220 0 : *ipt++ = 0x00; *ipt++ = 0x00; *ipt++ = 0x00;
1221 : #if FAST_BITS==0
1222 0 : *mpt++ = 0xff; *mpt++ = 0xff; *mpt++ = 0xff;
1223 : #else
1224 : *mpt |= mbit;
1225 : #endif
1226 : } else {
1227 0 : index = Pixel24(gdisp,index);
1228 0 : if ( msbf ) {
1229 0 : *ipt++ = index>>16;
1230 0 : *ipt++ = (index>>8)&0xff;
1231 0 : *ipt++ = index&0xff;
1232 : } else {
1233 0 : *ipt++ = index&0xff;
1234 0 : *ipt++ = (index>>8)&0xff;
1235 0 : *ipt++ = index>>16;
1236 : }
1237 : #if FAST_BITS==0
1238 0 : *mpt++ = 0; *mpt++ = 0; *mpt++ = 0;
1239 : #else
1240 : *mpt &= ~mbit;
1241 : #endif
1242 : }
1243 : #if FAST_BITS
1244 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
1245 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
1246 : } else {
1247 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1248 : }
1249 : #endif
1250 : }
1251 : }
1252 0 : }
1253 :
1254 0 : static void gdraw_8_on_24_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
1255 : struct gcol clut[256];
1256 : register uint8 *ipt;
1257 : register uint8 *pt;
1258 : register int index, j;
1259 : int i;
1260 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1261 : struct gcol *pos;
1262 :
1263 0 : _GDraw_getimageclut(base,clut);
1264 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1265 0 : pos = &clut[i];
1266 0 : pos->pixel = Pixel24(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1267 : }
1268 :
1269 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1270 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1271 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1272 0 : if ( gdisp->gg.img->byte_order == MSBFirst ) {
1273 0 : for ( j=src->width-1; j>=0; --j ) {
1274 0 : index = *pt++;
1275 0 : index = clut[index].pixel;
1276 0 : *ipt++ = index>>16;
1277 0 : *ipt++ = (index>>8)&0xff;
1278 0 : *ipt++ = index&0xff;
1279 : }
1280 : } else {
1281 0 : for ( j=src->width-1; j>=0; --j ) {
1282 0 : index = *pt++;
1283 0 : index = clut[index].pixel;
1284 0 : *ipt++ = index&0xff;
1285 0 : *ipt++ = (index>>8)&0xff;
1286 0 : *ipt++ = index>>16;
1287 : }
1288 : }
1289 : }
1290 0 : }
1291 :
1292 0 : static void gdraw_32_on_24_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
1293 : int i,j;
1294 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1295 : register uint32 *pt, index;
1296 : register uint8 *ipt;
1297 :
1298 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1299 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1300 0 : ipt = (uint8 *) (gdisp->gg.img->data) + (i-src->y)*gdisp->gg.img->bytes_per_line;
1301 0 : if ( gdisp->gg.img->byte_order == MSBFirst ) {
1302 0 : for ( j=src->width-1; j>=0; --j ) {
1303 0 : index = *pt++;
1304 0 : index = Pixel24(gdisp,index);
1305 0 : *ipt++ = index>>16;
1306 0 : *ipt++ = (index>>8)&0xff;
1307 0 : *ipt++ = index&0xff;
1308 : }
1309 : } else {
1310 0 : for ( j=src->width-1; j>=0; --j ) {
1311 0 : index = *pt++;
1312 0 : index = Pixel24(gdisp,index);
1313 0 : *ipt++ = index&0xff;
1314 0 : *ipt++ = (index>>8)&0xff;
1315 0 : *ipt++ = index>>16;
1316 : }
1317 : }
1318 : }
1319 0 : }
1320 :
1321 0 : static void gdraw_8_on_32a_nomag(GXDisplay *gdisp, GImage *image, GRect *src) {
1322 : struct gcol clut[256];
1323 : register int j;
1324 : int i,index;
1325 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1326 0 : int trans = base->trans;
1327 : register uint8 *pt;
1328 : uint32 *ipt;
1329 : struct gcol *pos;
1330 :
1331 0 : _GDraw_getimageclut(base,clut);
1332 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1333 0 : pos = &clut[i];
1334 0 : pos->pixel = Pixel32(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1335 0 : if ( i==trans )
1336 0 : pos->pixel = 0x00000000;
1337 0 : if ( gdisp->endian_mismatch )
1338 0 : pos->pixel = FixEndian32(pos->pixel);
1339 : }
1340 :
1341 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1342 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1343 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1344 0 : for ( j=src->width-1; j>=0; --j ) {
1345 0 : index = *pt++;
1346 0 : *ipt++ = clut[index].pixel;
1347 : }
1348 : }
1349 0 : }
1350 :
1351 0 : static void gdraw_8a_on_32a_nomag(GXDisplay *gdisp, GImage *image, GRect *src,
1352 : Color fg) {
1353 : register int j;
1354 : int i,index;
1355 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1356 : register uint8 *pt;
1357 : uint32 *ipt;
1358 0 : uint32 fg_pixel = Pixel32(gdisp,fg) & 0xffffff;
1359 :
1360 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1361 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1362 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1363 0 : for ( j=src->width-1; j>=0; --j ) {
1364 0 : index = *pt++;
1365 0 : *ipt++ = fg_pixel | (index<<24);
1366 : }
1367 : }
1368 0 : }
1369 :
1370 0 : static void gdraw_32_on_32a_nomag(GXDisplay *gdisp, GImage *image, GRect *src) {
1371 : int i,j;
1372 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1373 0 : int trans = base->trans;
1374 : register uint32 *pt, index, *ipt;
1375 0 : int endian_mismatch = gdisp->endian_mismatch;
1376 0 : int has_alpha = base->image_type == it_rgba;
1377 :
1378 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1379 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1380 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1381 0 : for ( j=src->width-1; j>=0; --j ) {
1382 0 : index = *pt++;
1383 0 : if ( index==trans ) {
1384 0 : *ipt++ = 0x00000000;
1385 : } else {
1386 0 : if ( has_alpha )
1387 0 : *ipt++ = Pixel16(gdisp,(index&0xffffff)) | (index&0xff000000);
1388 : else
1389 0 : *ipt++ = Pixel32(gdisp,index);
1390 0 : if ( endian_mismatch )
1391 0 : ipt[-1] = FixEndian32(ipt[-1]);
1392 : }
1393 : }
1394 : }
1395 0 : }
1396 :
1397 0 : static void gdraw_8_on_32_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
1398 : struct gcol clut[256];
1399 : register int j;
1400 : int i,index;
1401 : #if FAST_BITS==0
1402 : register uint32 *mpt;
1403 : #else
1404 : int mbit;
1405 : register uint8 *mpt;
1406 : #endif
1407 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1408 0 : int trans = base->trans;
1409 : register uint8 *pt;
1410 : uint32 *ipt;
1411 : struct gcol *pos;
1412 :
1413 0 : _GDraw_getimageclut(base,clut);
1414 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1415 0 : pos = &clut[i];
1416 0 : pos->pixel = Pixel32(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1417 0 : if ( gdisp->endian_mismatch )
1418 0 : pos->pixel = FixEndian32(pos->pixel);
1419 : }
1420 :
1421 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1422 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1423 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1424 : #if FAST_BITS==0
1425 0 : mpt = (uint32 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1426 : #else
1427 : mpt = (uint8 *) (gdisp->gg.mask->data) + (i-src->y)*gdisp->gg.mask->bytes_per_line;
1428 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
1429 : mbit = 0x80;
1430 : else
1431 : mbit = 0x1;
1432 : #endif
1433 0 : for ( j=src->width-1; j>=0; --j ) {
1434 0 : index = *pt++;
1435 0 : if ( index==trans ) {
1436 : #if FAST_BITS==0
1437 0 : *mpt++ = 0xffffffff;
1438 : #else
1439 : *mpt |= mbit;
1440 : #endif
1441 0 : *ipt++ = 0x00;
1442 : } else {
1443 0 : *ipt++ = clut[index].pixel;
1444 : #if FAST_BITS==0
1445 0 : *mpt++ = 0;
1446 : #else
1447 : *mpt &= ~mbit;
1448 : #endif
1449 : }
1450 : #if FAST_BITS
1451 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
1452 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
1453 : } else {
1454 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1455 : }
1456 : #endif
1457 : }
1458 : }
1459 0 : }
1460 :
1461 0 : static void gdraw_32_on_32_nomag_masked(GXDisplay *gdisp, GImage *image, GRect *src) {
1462 : int i,j;
1463 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1464 0 : int trans = base->trans;
1465 : register uint32 *pt, index, *ipt;
1466 0 : int endian_mismatch = gdisp->endian_mismatch;
1467 : #if FAST_BITS==0
1468 : register uint32 *mpt;
1469 : #else
1470 : register uint8 *mpt;
1471 : int mbit;
1472 : #endif
1473 :
1474 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1475 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1476 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1477 : #if FAST_BITS==0
1478 0 : mpt = (uint32 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1479 : #else
1480 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1481 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
1482 : mbit = 0x80;
1483 : else
1484 : mbit = 0x1;
1485 : #endif
1486 0 : for ( j=src->width-1; j>=0; --j ) {
1487 0 : index = *pt++;
1488 0 : if ( index==trans ) {
1489 0 : *ipt++ = Pixel32(gdisp,0);
1490 : #if FAST_BITS==0
1491 0 : *mpt++ = 0xffffffff;
1492 : #else
1493 : *mpt |= mbit;
1494 : #endif
1495 : } else {
1496 0 : *ipt++ = Pixel32(gdisp,index);
1497 0 : if ( endian_mismatch )
1498 0 : ipt[-1] = FixEndian32(ipt[-1]);
1499 : #if FAST_BITS==0
1500 0 : *mpt++ = 0;
1501 : #else
1502 : *mpt &= ~mbit;
1503 : #endif
1504 : }
1505 : #if FAST_BITS
1506 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
1507 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
1508 : } else {
1509 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1510 : }
1511 : #endif
1512 : }
1513 : }
1514 0 : }
1515 :
1516 0 : static void gdraw_32a_on_32_nomag(GXDisplay *gdisp, GImage *image, GRect *src) {
1517 : int i,j;
1518 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1519 0 : int trans = base->trans;
1520 : register uint32 *pt, index, *ipt;
1521 0 : int endian_mismatch = gdisp->endian_mismatch;
1522 : #if FAST_BITS==0
1523 : register uint32 *mpt;
1524 : #else
1525 : register uint8 *mpt;
1526 : int mbit;
1527 : #endif
1528 :
1529 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1530 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1531 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1532 : #if FAST_BITS==0
1533 0 : mpt = (uint32 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1534 : #else
1535 : mpt = (uint8 *) (gdisp->gg.mask->data + (i-src->y)*gdisp->gg.mask->bytes_per_line);
1536 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst )
1537 : mbit = 0x80;
1538 : else
1539 : mbit = 0x1;
1540 : #endif
1541 0 : for ( j=src->width-1; j>=0; --j ) {
1542 0 : index = *pt++;
1543 0 : if ( (index==trans && trans!=-1) || (index>>24)<0x80 ) {
1544 0 : *ipt++ = Pixel32(gdisp,0);
1545 : #if FAST_BITS==0
1546 0 : *mpt++ = 0xffffffff;
1547 : #else
1548 : *mpt |= mbit;
1549 : #endif
1550 : } else {
1551 0 : *ipt++ = Pixel32(gdisp,index);
1552 0 : if ( endian_mismatch )
1553 0 : ipt[-1] = FixEndian32(ipt[-1]);
1554 : #if FAST_BITS==0
1555 0 : *mpt++ = 0;
1556 : #else
1557 : *mpt &= ~mbit;
1558 : #endif
1559 : }
1560 : #if FAST_BITS
1561 : if ( gdisp->gg.mask->bitmap_bit_order == MSBFirst ) {
1562 : if (( mbit>>=1 )==0 ) {mbit=0x80; ++mpt;};
1563 : } else {
1564 : if (( mbit<<=1 )==256 ) {mbit=0x1; ++mpt;};
1565 : }
1566 : #endif
1567 : }
1568 : }
1569 0 : }
1570 :
1571 0 : static void gdraw_8_on_32_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
1572 : struct gcol clut[256];
1573 : register int j;
1574 : int i,index;
1575 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1576 : register uint8 *pt;
1577 : uint32 *ipt;
1578 : struct gcol *pos;
1579 :
1580 0 : _GDraw_getimageclut(base,clut);
1581 0 : for ( i=base->clut->clut_len-1; i>=0; --i ) {
1582 0 : pos = &clut[i];
1583 0 : pos->pixel = Pixel32(gdisp,COLOR_CREATE(pos->red,pos->green,pos->blue));
1584 0 : if ( gdisp->endian_mismatch )
1585 0 : pos->pixel = FixEndian32(pos->pixel);
1586 : }
1587 :
1588 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1589 0 : pt = (uint8 *) (base->data) + i*base->bytes_per_line + src->x;
1590 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1591 0 : for ( j=src->width-1; j>=0; --j ) {
1592 0 : index = *pt++;
1593 0 : *ipt++ = clut[index].pixel;
1594 : }
1595 : }
1596 0 : }
1597 :
1598 0 : static void gdraw_32_on_32_nomag_nomask(GXDisplay *gdisp, GImage *image, GRect *src) {
1599 : int i,j;
1600 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1601 : register uint32 *pt, index, *ipt;
1602 0 : int endian_mismatch = gdisp->endian_mismatch;
1603 :
1604 0 : for ( i=src->y; i<src->y+src->height; ++i ) {
1605 0 : pt = (uint32 *) (base->data + i*base->bytes_per_line) + src->x;
1606 0 : ipt = (uint32 *) (gdisp->gg.img->data + (i-src->y)*gdisp->gg.img->bytes_per_line);
1607 0 : for ( j=src->width-1; j>=0; --j ) {
1608 0 : index = *pt++;
1609 0 : *ipt++ = Pixel32(gdisp,index);
1610 0 : if ( endian_mismatch )
1611 0 : ipt[-1] = FixEndian32(ipt[-1]);
1612 : }
1613 : }
1614 0 : }
1615 :
1616 0 : static void gdraw_xbitmap(GXWindow w, XImage *xi, GClut *clut,
1617 : Color trans, GRect *src, int x, int y) {
1618 0 : GXDisplay *gdisp = w->display;
1619 0 : Display *display = gdisp->display;
1620 0 : GC gc = gdisp->gcstate[w->ggc->bitmap_col].gc;
1621 : Color fg, bg;
1622 :
1623 0 : if ( trans!=COLOR_UNKNOWN ) {
1624 0 : XSetFunction(display,gc,GXand);
1625 0 : if ( trans==1 ) {
1626 0 : XSetForeground(display,gc, ~gdisp->cs.alpha_bits );
1627 0 : XSetBackground(display,gc, 0 );
1628 : } else {
1629 0 : XSetForeground(display,gc, 0 );
1630 0 : XSetBackground(display,gc, ~gdisp->cs.alpha_bits );
1631 : }
1632 0 : XPutImage(display,w->w,gc,xi,src->x,src->y,
1633 0 : x,y, src->width, src->height );
1634 0 : fg = trans==1?0:_GXDraw_GetScreenPixel(gdisp,clut!=NULL?clut->clut[1]:COLOR_CREATE(0xff,0xff,0xff));
1635 0 : bg = trans==0?0:_GXDraw_GetScreenPixel(gdisp,clut!=NULL?clut->clut[0]:COLOR_CREATE(0,0,0));
1636 0 : fg |= (gdisp)->cs.alpha_bits;
1637 0 : bg |= (gdisp)->cs.alpha_bits;
1638 : if ( /*bg!=fg || fg!=0*/ true ) {
1639 : #ifdef _BrokenBitmapImages
1640 : /* See the comment at _GXDraw_Image about why this works */
1641 : XSetFunction(display,gc,GXxor);
1642 : #else
1643 0 : XSetFunction(display,gc,GXor);
1644 : #endif
1645 0 : XSetForeground(display,gc,fg);
1646 0 : XSetBackground(display,gc,bg);
1647 : }
1648 : } else {
1649 0 : XSetForeground(display,gc,
1650 0 : _GXDraw_GetScreenPixel(gdisp,
1651 0 : clut!=NULL?clut->clut[1]:COLOR_CREATE(0xff,0xff,0xff)) | (gdisp)->cs.alpha_bits);
1652 0 : XSetBackground(display,gc,
1653 0 : _GXDraw_GetScreenPixel(gdisp,
1654 0 : clut!=NULL?clut->clut[0]:COLOR_CREATE(0,0,0)) | (gdisp)->cs.alpha_bits);
1655 : }
1656 0 : XPutImage(display,w->w,gc,xi,src->x,src->y,
1657 0 : x,y, src->width, src->height );
1658 0 : XSetFunction(display,gc,GXcopy);
1659 0 : gdisp->gcstate[w->ggc->bitmap_col].fore_col = COLOR_UNKNOWN;
1660 0 : }
1661 :
1662 0 : static void gdraw_bitmap(GXWindow w, struct _GImage *image, GClut *clut,
1663 : Color trans, GRect *src, int x, int y) {
1664 : XImage *xi;
1665 0 : GXDisplay *gdisp = w->display;
1666 0 : uint8 *newdata = NULL;
1667 :
1668 0 : xi = XCreateImage(gdisp->display,gdisp->visual,1,XYBitmap,0,(char *) (image->data),
1669 0 : image->width, image->height,8,image->bytes_per_line);
1670 0 : if ( xi->bitmap_bit_order==LSBFirst ) {
1671 : /* sigh. The server doesn't use our convention. I might be able just */
1672 : /* to change this field but it doesn't say, so best not to */
1673 0 : int len = image->bytes_per_line*image->height;
1674 : uint8 *pt, *ipt, *end;
1675 : int m1,m2,val;
1676 :
1677 0 : for ( ipt = image->data, pt=newdata=malloc(len), end=pt+len; pt<end; ++pt, ++ipt ) {
1678 0 : val = 0;
1679 0 : for ( m1=1, m2=0x80; m2!=0; m1<<=1, m2>>=1 )
1680 0 : if ( *ipt&m1 ) val|=m2;
1681 0 : *pt = val;
1682 : }
1683 0 : xi->data = (char *) newdata;
1684 : }
1685 0 : gdraw_xbitmap(w,xi,clut,trans,src,x,y);
1686 0 : if ( (uint8 *) (xi->data)==image->data || (uint8 *) (xi->data)==newdata ) xi->data = NULL;
1687 0 : XDestroyImage(xi);
1688 0 : }
1689 :
1690 0 : static void check_image_buffers(GXDisplay *gdisp, int neww, int newh, int is_bitmap) {
1691 0 : int width = gdisp->gg.iwidth, height = gdisp->gg.iheight;
1692 : char *temp;
1693 0 : int depth = gdisp->depth, pixel_size;
1694 : union { int32 foo; uint8 bar[4]; } endian;
1695 :
1696 0 : if ( is_bitmap ) depth=1;
1697 0 : if ( neww > gdisp->gg.iwidth ) {
1698 0 : width = neww;
1699 0 : if ( width<400 ) width = 400;
1700 : }
1701 0 : if ( width > gdisp->gg.iwidth || (gdisp->gg.img!=NULL && depth!=gdisp->gg.img->depth) ) {
1702 0 : free(gdisp->gg.red_dith);
1703 0 : free(gdisp->gg.green_dith);
1704 0 : free(gdisp->gg.blue_dith);
1705 0 : if ( depth<=8 ) {
1706 0 : gdisp->gg.red_dith = malloc(width*sizeof(short));
1707 0 : gdisp->gg.green_dith = malloc(width*sizeof(short));
1708 0 : gdisp->gg.blue_dith = malloc(width*sizeof(short));
1709 0 : if ( gdisp->gg.red_dith==NULL || gdisp->gg.green_dith==NULL || gdisp->gg.blue_dith==NULL )
1710 0 : gdisp->do_dithering = 0;
1711 : } else {
1712 0 : gdisp->gg.red_dith = NULL;
1713 0 : gdisp->gg.green_dith = NULL;
1714 0 : gdisp->gg.blue_dith = NULL;
1715 : }
1716 : }
1717 0 : if ( newh > gdisp->gg.iheight ) {
1718 0 : height = newh;
1719 0 : if ( height<400 ) height = 400;
1720 : }
1721 :
1722 0 : if ( gdisp->gg.iwidth == width && gdisp->gg.iheight == height && depth==gdisp->gg.img->depth )
1723 0 : return;
1724 :
1725 0 : if ( gdisp->gg.img!=NULL ) {
1726 : /* If gdisp->gg.img->data was allocated by GC_malloc rather
1727 : than standard libc malloc then it must be set to NULL so
1728 : that XDestroyImage() does not try to free it and crash.
1729 :
1730 : If we no longer use libgc then the following conditional
1731 : block can be removed, but in case it isn't, the enclosed
1732 : free() will prevent a memory leak.
1733 : */
1734 0 : if (gdisp->gg.img->data) {
1735 0 : free(gdisp->gg.img->data);
1736 0 : gdisp->gg.img->data = NULL;
1737 : }
1738 0 : XDestroyImage(gdisp->gg.img);
1739 : }
1740 0 : if ( gdisp->gg.mask!=NULL ) {
1741 : /* If gdisp->gg.mask->data was allocated by GC_malloc rather
1742 : than standard libc malloc then it must be set to NULL so
1743 : that XDestroyImage() does not try to free it and crash.
1744 :
1745 : If we no longer use libgc then the following conditional
1746 : block can be removed, but in case it isn't, the enclosed
1747 : free() will prevent a memory leak.
1748 : */
1749 0 : if (gdisp->gg.mask->data) {
1750 0 : free(gdisp->gg.mask->data);
1751 0 : gdisp->gg.mask->data = NULL;
1752 : }
1753 0 : XDestroyImage(gdisp->gg.mask);
1754 : }
1755 0 : pixel_size = gdisp->pixel_size;
1756 0 : temp = malloc(((width*pixel_size+gdisp->bitmap_pad-1)/gdisp->bitmap_pad)*
1757 0 : (gdisp->bitmap_pad/8)*height);
1758 0 : if ( temp==NULL ) {
1759 0 : GDrawIError("Can't create image draw area");
1760 0 : exit(1);
1761 : }
1762 0 : gdisp->gg.img = XCreateImage(gdisp->display,gdisp->visual,depth,
1763 : depth==1?XYBitmap:ZPixmap,0,
1764 0 : temp,width,height,gdisp->bitmap_pad,0);
1765 0 : if ( gdisp->gg.img==NULL ) {
1766 0 : GDrawIError("Can't create image draw area");
1767 0 : exit(1);
1768 : }
1769 : if ( !FAST_BITS==0 ) pixel_size=1;
1770 0 : temp = malloc(((width*pixel_size+gdisp->bitmap_pad-1)/gdisp->bitmap_pad)*
1771 0 : (gdisp->bitmap_pad/8)*height);
1772 0 : gdisp->gg.mask = NULL;
1773 0 : if ( temp!=NULL ) {
1774 0 : gdisp->gg.mask = XCreateImage(gdisp->display,gdisp->visual,depth,
1775 : depth==1?XYBitmap:ZPixmap,
1776 0 : 0,temp,width,height,gdisp->bitmap_pad,0);
1777 0 : if ( gdisp->gg.mask==NULL )
1778 0 : free(temp);
1779 : }
1780 0 : gdisp->gg.iwidth = width; gdisp->gg.iheight = height;
1781 0 : endian.foo = 0xff;
1782 0 : if ( (gdisp->gg.img->byte_order==MSBFirst) != ( endian.bar[3]==0xff ))
1783 0 : gdisp->endian_mismatch = true;
1784 : }
1785 :
1786 0 : static void gximage_to_ximage(GXWindow gw, GImage *image, GRect *src) {
1787 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1788 0 : GXDisplay *gdisp = gw->display;
1789 : int depth;
1790 :
1791 0 : depth = gdisp->pixel_size;
1792 0 : if ( depth!=8 && depth!=16 && depth!=24 && depth!=32 )
1793 0 : depth = 1;
1794 0 : else if ( gw->ggc->bitmap_col )
1795 0 : depth = 1;
1796 :
1797 0 : check_image_buffers(gdisp, src->width, src->height,depth==1);
1798 0 : if ( base->trans!=COLOR_UNKNOWN || base->image_type == it_rgba ||
1799 : gdisp->supports_alpha_images ) {
1800 0 : if ( base->image_type == it_index ) {
1801 0 : switch ( depth ) {
1802 : case 1:
1803 : default:
1804 : /* all servers can handle bitmaps, so if we don't know how to*/
1805 : /* write to a 13bit screen, we can at least give a bitmap */
1806 0 : gdraw_8_on_1_nomag_dithered_masked(gdisp,image,src);
1807 0 : break;
1808 : case 8:
1809 0 : if ( gdisp->do_dithering && !gdisp->cs.is_grey )
1810 0 : gdraw_8_on_8_nomag_dithered_masked(gdisp,image,src);
1811 : else
1812 0 : gdraw_8_on_8_nomag_nodithered_masked(gdisp,image,src);
1813 0 : break;
1814 : case 16:
1815 0 : gdraw_8_on_16_nomag_masked(gdisp,image,src);
1816 0 : break;
1817 : case 24:
1818 0 : gdraw_8_on_24_nomag_masked(gdisp,image,src);
1819 0 : break;
1820 : case 32:
1821 0 : if ( gdisp->supports_alpha_images )
1822 0 : gdraw_8_on_32a_nomag(gdisp,image,src);
1823 : else
1824 0 : gdraw_8_on_32_nomag_masked(gdisp,image,src);
1825 0 : break;
1826 : }
1827 0 : } else if ( base->image_type == it_true ) {
1828 0 : switch ( depth ) {
1829 : case 1:
1830 : default:
1831 : /* all servers can handle bitmaps, so if we don't know how to*/
1832 : /* write to a 13bit screen, we can at least give a bitmap */
1833 0 : gdraw_32_on_1_nomag_dithered_masked(gdisp,image,src);
1834 0 : break;
1835 : case 8:
1836 0 : if ( gdisp->do_dithering && !gdisp->cs.is_grey )
1837 0 : gdraw_32_on_8_nomag_dithered_masked(gdisp,image,src);
1838 : else
1839 0 : gdraw_32_on_8_nomag_nodithered_masked(gdisp,image,src);
1840 0 : break;
1841 : case 16:
1842 0 : gdraw_32_on_16_nomag_masked(gdisp,image,src);
1843 0 : break;
1844 : case 24:
1845 0 : gdraw_32_on_24_nomag_masked(gdisp,image,src);
1846 0 : break;
1847 : case 32:
1848 0 : if ( gdisp->supports_alpha_images )
1849 0 : gdraw_32_on_32a_nomag(gdisp,image,src);
1850 : else
1851 0 : gdraw_32_on_32_nomag_masked(gdisp,image,src);
1852 0 : break;
1853 : }
1854 0 : } else if ( base->image_type == it_rgba ) {
1855 0 : switch ( depth ) {
1856 : case 1:
1857 : default:
1858 : /* all servers can handle bitmaps, so if we don't know how to*/
1859 : /* write to a 13bit screen, we can at least give a bitmap */
1860 0 : gdraw_32a_on_1_nomag_dithered(gdisp,image,src);
1861 0 : break;
1862 : case 8:
1863 0 : if ( gdisp->do_dithering && !gdisp->cs.is_grey )
1864 0 : gdraw_32a_on_8_nomag_dithered(gdisp,image,src);
1865 : else
1866 0 : gdraw_32a_on_8_nomag_nodithered(gdisp,image,src);
1867 0 : break;
1868 : case 16:
1869 0 : gdraw_32a_on_16_nomag(gdisp,image,src);
1870 0 : break;
1871 : case 24:
1872 0 : gdraw_32a_on_24_nomag(gdisp,image,src);
1873 0 : break;
1874 : case 32:
1875 0 : if ( gdisp->supports_alpha_images )
1876 0 : gdraw_32_on_32a_nomag(gdisp,image,src);
1877 : else
1878 0 : gdraw_32a_on_32_nomag(gdisp,image,src);
1879 0 : break;
1880 : }
1881 : }
1882 : } else { /* no mask */
1883 0 : if ( base->image_type == it_index ) {
1884 0 : switch ( depth ) {
1885 : case 1:
1886 : default:
1887 0 : gdraw_8_on_1_nomag_dithered_nomask(gdisp,image,src);
1888 0 : break;
1889 : case 8:
1890 0 : if ( gdisp->do_dithering && !gdisp->cs.is_grey )
1891 0 : gdraw_8_on_8_nomag_dithered_nomask(gdisp,image,src);
1892 : else
1893 0 : gdraw_8_on_8_nomag_nodithered_nomask(gdisp,image,src);
1894 0 : break;
1895 : case 16:
1896 0 : gdraw_8_on_16_nomag_nomask(gdisp,image,src);
1897 0 : break;
1898 : case 24:
1899 0 : gdraw_8_on_24_nomag_nomask(gdisp,image,src);
1900 0 : break;
1901 : case 32:
1902 0 : gdraw_8_on_32_nomag_nomask(gdisp,image,src);
1903 0 : break;
1904 : }
1905 0 : } else if ( base->image_type == it_true ) {
1906 0 : switch ( depth ) {
1907 : case 1:
1908 : default:
1909 0 : gdraw_32_on_1_nomag_dithered_nomask(gdisp,image,src);
1910 0 : break;
1911 : case 8:
1912 0 : if ( gdisp->do_dithering && !gdisp->cs.is_grey )
1913 0 : gdraw_32_on_8_nomag_dithered_nomask(gdisp,image,src);
1914 : else
1915 0 : gdraw_32_on_8_nomag_nodithered_nomask(gdisp,image,src);
1916 0 : break;
1917 : case 16:
1918 0 : gdraw_32_on_16_nomag_nomask(gdisp,image,src);
1919 0 : break;
1920 : case 24:
1921 0 : gdraw_32_on_24_nomag_nomask(gdisp,image,src);
1922 0 : break;
1923 : case 32:
1924 0 : gdraw_32_on_32_nomag_nomask(gdisp,image,src);
1925 0 : break;
1926 : }
1927 : }
1928 : }
1929 0 : }
1930 :
1931 0 : void _GXDraw_Image( GWindow _w, GImage *image, GRect *src, int32 x, int32 y) {
1932 0 : GXWindow gw = (GXWindow) _w;
1933 0 : GXDisplay *gdisp = gw->display;
1934 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
1935 0 : Display *display=gdisp->display;
1936 0 : Window w = gw->w;
1937 0 : GC gc = gdisp->gcstate[gw->ggc->bitmap_col].gc;
1938 0 : GRect rootPos = {0, 0, XDisplayWidth(display,gdisp->screen),
1939 0 : XDisplayHeight(display,gdisp->screen)};
1940 0 : GRect img_pos = {x+_w->pos.x, y+_w->pos.y, src->width, src->height};
1941 0 : GRect win_pos = {x, y, src->width, src->height};
1942 0 : GRect blend_src = {0, 0, src->width, src->height};
1943 0 : GImage *blended = NULL;
1944 : int depth;
1945 :
1946 : #ifndef _NO_LIBCAIRO
1947 0 : if ( gw->usecairo ) {
1948 0 : _GXCDraw_Image(gw,image,src,x,y);
1949 0 : return;
1950 : }
1951 : #endif
1952 :
1953 0 : _GXDraw_SetClipFunc(gdisp,gw->ggc);
1954 0 : depth = gdisp->pixel_size;
1955 0 : if ( depth!=8 && depth!=16 && depth!=24 && depth!=32 )
1956 0 : depth = 1;
1957 0 : else if ( gw->ggc->bitmap_col )
1958 0 : depth = 1;
1959 :
1960 0 : if ( base->image_type == it_mono ) {
1961 : /* Mono images are easy, because all X servers (no matter what their */
1962 : /* depth) support 1 bit bitmaps */
1963 0 : gdraw_bitmap(gw,image->u.image,base->clut,base->trans,src,x,y);
1964 0 : return;
1965 : }
1966 :
1967 : /* Throws errors in Mac OS X */
1968 : #ifndef __Mac
1969 : /* Can we blend this with background to support an alpha channel? */
1970 : /* it's slow, particularly so on network connections, but that's */
1971 : /* all we can get without reworking GDraw to use XComposite ext. */
1972 0 : if ((depth >= 16) && (base->image_type == it_rgba)) {
1973 : /* This requires caution, as the rectangle being worked */
1974 : /* must be contained within both screen and the window. */
1975 0 : intersect_rectangles(&img_pos, &(_w->pos));
1976 0 : intersect_rectangles(&img_pos, &rootPos);
1977 0 : img_pos.x -= _w->pos.x;
1978 0 : img_pos.y -= _w->pos.y;
1979 0 : win_pos = img_pos;
1980 0 : blend_src = img_pos;
1981 0 : blend_src.x = blend_src.y = 0;
1982 0 : img_pos.x = src->x + (win_pos.x - x);
1983 0 : img_pos.y = src->y + (win_pos.y - y);
1984 0 : src = &img_pos;
1985 0 : x = win_pos.x;
1986 0 : y = win_pos.y;
1987 :
1988 0 : if (src->width>0 && src->height>0)
1989 0 : blended = _GXDraw_CopyScreenToImage(_w, &win_pos);
1990 :
1991 0 : if (blended != NULL) {
1992 0 : GImageBlendOver(blended, image, src, 0, 0);
1993 0 : image = blended;
1994 0 : base = image->list_len==0?image->u.image:image->u.images[0];
1995 0 : src = &blend_src;
1996 : }
1997 : }
1998 : #endif
1999 :
2000 0 : gximage_to_ximage(gw, image, src);
2001 :
2002 0 : if ( !gdisp->supports_alpha_images && (blended == NULL) &&
2003 0 : (base->trans!=COLOR_UNKNOWN || base->image_type==it_rgba )) {
2004 :
2005 : /* ((destination & mask) | src) seems to me to yield the proper behavior */
2006 : /* for transparent backgrounds. This is equivalent to: */
2007 : /* ((destination GXorReverse mask) GXnand src) */
2008 : /* Oh... I think xor works too because the mask and the src will never*/
2009 : /* both be 1 on the same pixel. If the mask is set then the image will*/
2010 : /* be clear. So xor and or are equivalent (the case on which they differ never occurs) */
2011 0 : XSetFunction(display,gc,GXand);
2012 : #if FAST_BITS
2013 : XSetForeground(display,gc, ~((-1)<<gdisp->pixel_size) );
2014 : XSetBackground(display,gc, 0 );
2015 : #endif
2016 0 : XPutImage(display,w,gc,gdisp->gg.mask,0,0,
2017 0 : x,y, src->width, src->height );
2018 : #ifdef _BrokenBitmapImages
2019 : XSetFunction(display,gc,GXxor);
2020 : #else
2021 0 : XSetFunction(display,gc,GXor);
2022 : #endif
2023 0 : XPutImage(display,w,gc,gdisp->gg.img,0,0,
2024 0 : x,y, src->width, src->height );
2025 0 : XSetFunction(display,gc,GXcopy);
2026 0 : gdisp->gcstate[gw->ggc->bitmap_col].fore_col = COLOR_UNKNOWN;
2027 0 : gdisp->gcstate[gw->ggc->bitmap_col].func = df_copy;
2028 : } else { /* no mask */
2029 0 : XPutImage(display,w,gc,gdisp->gg.img,0,0,
2030 0 : x,y, src->width, src->height );
2031 : }
2032 :
2033 0 : if (blended != NULL)
2034 0 : GImageDestroy(blended);
2035 : }
2036 :
2037 0 : void _GXDraw_TileImage( GWindow _w, GImage *image, GRect *src, int32 x, int32 y) {
2038 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
2039 :
2040 : #ifndef _NO_LIBCAIRO
2041 0 : if ( _w->usecairo ) {
2042 0 : _GXCDraw_TileImage((GXWindow) _w,image,src,x,y);
2043 0 : return;
2044 : }
2045 : #endif
2046 0 : if ( src->x/base->width == (src->x+src->width-1)/base->width &&
2047 0 : src->y/base->height == (src->y+src->height-1)/base->height ) {
2048 : /* Ok, the exposed area is entirely covered by one instance of the image*/
2049 0 : int newx = src->x, newy = src->y;
2050 : GRect newr;
2051 0 : newr.x = (src->x-x)%base->width; newr.y = (src->y-y)%base->height;
2052 0 : newr.width = src->width; newr.height = src->height;
2053 0 : _GXDraw_Image(_w,image,&newr,newx,newy);
2054 0 : } else if ( base->trans==COLOR_UNKNOWN || base->image_type==it_mono ) {
2055 : GWindow pixmap;
2056 0 : GXWindow gw = (GXWindow) _w;
2057 0 : GXDisplay *gdisp = gw->display;
2058 0 : Display *display=gdisp->display;
2059 0 : Window w = gw->w;
2060 0 : GC gc = gdisp->gcstate[gw->ggc->bitmap_col].gc;
2061 : GRect full, old;
2062 : int i,j;
2063 :
2064 0 : full.x = full.y = 0; full.width = base->width; full.height = base->height;
2065 0 : pixmap = GDrawCreatePixmap((GDisplay *) gdisp,base->width,base->height);
2066 0 : _GXDraw_Image(pixmap,image,&full,0,0);
2067 0 : GDrawPushClip(_w,src,&old);
2068 0 : _GXDraw_SetClipFunc(gdisp,gw->ggc);
2069 0 : for ( i=y; i<gw->ggc->clip.y+gw->ggc->clip.height; i+=base->height ) {
2070 0 : if ( i+base->height<gw->ggc->clip.y )
2071 0 : continue;
2072 0 : for ( j=x; j<gw->ggc->clip.x+gw->ggc->clip.width; j+=base->width ) {
2073 0 : if ( j+base->width<gw->ggc->clip.x )
2074 0 : continue;
2075 0 : XCopyArea(display,((GXWindow) pixmap)->w,w,gc,
2076 0 : 0,0, base->width, base->height,
2077 : j,i);
2078 : }
2079 : }
2080 0 : GDrawPopClip(_w,&old);
2081 0 : GDrawDestroyWindow(pixmap);
2082 : } else {
2083 : GWindow pixmap, maskmap;
2084 0 : GXWindow gw = (GXWindow) _w;
2085 0 : GXDisplay *gdisp = gw->display;
2086 0 : Display *display=gdisp->display;
2087 0 : Window w = gw->w;
2088 0 : GC gc = gdisp->gcstate[gw->ggc->bitmap_col].gc;
2089 : GRect full, old;
2090 : int i,j;
2091 :
2092 0 : full.x = full.y = 0; full.width = base->width; full.height = base->height;
2093 0 : pixmap = GDrawCreatePixmap((GDisplay *) gdisp,base->width,base->height);
2094 0 : maskmap = GDrawCreatePixmap((GDisplay *) gdisp,base->width,base->height);
2095 0 : gximage_to_ximage(gw, image, &full);
2096 0 : GDrawDestroyWindow(maskmap);
2097 : #if FAST_BITS
2098 : XSetForeground(display,gc, ~((-1)<<gdisp->pixel_size) );
2099 : XSetBackground(display,gc, 0 );
2100 : #endif
2101 0 : XSetFunction(display,gc,GXcopy);
2102 0 : XPutImage(display,((GXWindow) maskmap)->w,gc,gdisp->gg.mask,0,0,
2103 0 : x,y, src->width, src->height );
2104 0 : XPutImage(display,((GXWindow) pixmap)->w,gc,gdisp->gg.img,0,0,
2105 0 : x,y, src->width, src->height );
2106 0 : GDrawPushClip(_w,src,&old);
2107 0 : _GXDraw_SetClipFunc(gdisp,gw->ggc);
2108 0 : for ( i=y; i<gw->ggc->clip.y+gw->ggc->clip.height; i+=base->height ) {
2109 0 : if ( i+base->height<gw->ggc->clip.y )
2110 0 : continue;
2111 0 : for ( j=x; j<gw->ggc->clip.x+gw->ggc->clip.width; j+=base->width ) {
2112 0 : if ( j+base->width<gw->ggc->clip.x )
2113 0 : continue;
2114 0 : XSetFunction(display,gc,GXand);
2115 0 : XCopyArea(display,((GXWindow) maskmap)->w,w,gc,
2116 0 : 0,0, base->width, base->height,
2117 : j,i);
2118 0 : XSetFunction(display,gc,GXor);
2119 0 : XCopyArea(display,((GXWindow) pixmap)->w,w,gc,
2120 0 : 0,0, base->width, base->height,
2121 : j,i);
2122 : }
2123 : }
2124 0 : GDrawPopClip(_w,&old);
2125 0 : GDrawDestroyWindow(pixmap);
2126 0 : GDrawDestroyWindow(maskmap);
2127 0 : XSetFunction(display,gc,GXcopy);
2128 0 : gdisp->gcstate[gw->ggc->bitmap_col].fore_col = COLOR_UNKNOWN;
2129 0 : gdisp->gcstate[gw->ggc->bitmap_col].func = df_copy;
2130 : }
2131 : }
2132 :
2133 : /* When drawing an anti-aliased glyph, I've been pretending that it's an image*/
2134 : /* with colors running from foreground to background and with background be- */
2135 : /* ing transparent. That works reasonably well -- on a blank background, but */
2136 : /* when two glyphs overlap (as in a script font, for instance) we get a faint*/
2137 : /* light halo around the edge of the second glyph. */
2138 : /* What we really want to do is use the grey levels as an alpha channel with */
2139 : /* the foreground color as the color. But alpha channels haven't been avail- */
2140 : /* able on most X-displays. An alternative is to do the composing ourselves */
2141 : /* in an image that's as big as the window, and then transfer that when done */
2142 : /* That sounds slow. */
2143 : /* What should the composing look like? I'm not entirely but it should be */
2144 : /* somewhere between a "max" and a "clipped add" applied component by component*/
2145 : /* of the color. X does not support either of those as primitives -- but X */
2146 : /* does support bitwise boolean operators, and an "or" will always produce */
2147 : /* a value somewhere between those extremes. */
2148 : /* Actually since the color values (black==foreground, white==background) */
2149 : /* generally run in the oposite direction from the alpha channel (100%=fore, */
2150 : /* 0%=back) we will need to reverse the "or" to be an "and", but the idea */
2151 : /* is the same */
2152 0 : void _GXDraw_Glyph( GWindow _w, GImage *image, GRect *src, int32 x, int32 y) {
2153 0 : GXWindow gw = (GXWindow) _w;
2154 0 : GXDisplay *gdisp = gw->display;
2155 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
2156 0 : Color fg = -1;
2157 :
2158 : #ifndef _NO_LIBCAIRO
2159 0 : if ( gw->usecairo ) {
2160 0 : _GXCDraw_Glyph(gw,image,src,x,y);
2161 0 : return;
2162 : }
2163 : #endif
2164 :
2165 0 : if ( base->image_type==it_index )
2166 0 : fg = base->clut->clut[base->clut->clut_len-1];
2167 :
2168 0 : if ( base->image_type!=it_index )
2169 0 : _GXDraw_Image(_w,image,src,x,y);
2170 0 : else if ( gdisp->visual->class != TrueColor ||
2171 0 : gdisp->pixel_size<16 || gw->ggc->bitmap_col || fg!=0 )
2172 0 : _GXDraw_Image(_w,image,src,x,y);
2173 : else {
2174 0 : Display *display=gdisp->display;
2175 0 : Window w = gw->w;
2176 0 : GC gc = gdisp->gcstate[gw->ggc->bitmap_col].gc;
2177 :
2178 0 : _GXDraw_SetClipFunc(gdisp,gw->ggc);
2179 :
2180 0 : check_image_buffers(gdisp, src->width, src->height,false);
2181 0 : if ( gdisp->supports_alpha_images ) {
2182 0 : gdraw_8a_on_32a_nomag( gdisp, image, src, fg );
2183 : } else {
2184 0 : gdraw_8_on_any_nomag_glyph(gdisp, image, src);
2185 0 : XSetFunction(display,gc,GXand);
2186 : }
2187 0 : XPutImage(display,w,gc,gdisp->gg.img,0,0,
2188 0 : x,y, src->width, src->height );
2189 0 : XSetFunction(display,gc,GXcopy);
2190 : }
2191 : }
2192 :
2193 : /* ******************************** Magnified ******************************* */
2194 :
2195 0 : GImage *_GImageExtract(struct _GImage *base,GRect *src,GRect *size,
2196 : double xscale, double yscale) {
2197 : static GImage temp;
2198 : static struct _GImage tbase;
2199 : static uint8 *data;
2200 : static int dlen;
2201 : int r,c;
2202 :
2203 0 : memset(&temp,0,sizeof(temp));
2204 0 : tbase = *base;
2205 0 : temp.u.image = &tbase;
2206 0 : tbase.width = size->width; tbase.height = size->height;
2207 0 : if ( base->image_type==it_mono )
2208 0 : tbase.bytes_per_line = (size->width+7)/8;
2209 0 : else if ( base->image_type==it_index )
2210 0 : tbase.bytes_per_line = size->width;
2211 : else
2212 0 : tbase.bytes_per_line = 4*size->width;
2213 0 : if ( tbase.bytes_per_line*size->height>dlen )
2214 0 : data = realloc(data,dlen = tbase.bytes_per_line*size->height );
2215 0 : tbase.data = data;
2216 :
2217 : /* I used to use rint(x). Now I use floor(x). For normal images rint */
2218 : /* might be better, but for text we need floor */
2219 :
2220 0 : if ( base->image_type==it_mono ) {
2221 0 : memset(data,0,tbase.height*tbase.bytes_per_line);
2222 0 : for ( r=0; r<size->height; ++r ) {
2223 0 : int or = ((int) floor( (r+size->y)/yscale ));
2224 0 : uint8 *pt = data+r*tbase.bytes_per_line;
2225 0 : uint8 *opt = base->data+or*base->bytes_per_line;
2226 0 : for ( c=0; c<size->width; ++c ) {
2227 0 : int oc = ((int) floor( (c+size->x)/xscale));
2228 0 : if ( opt[oc>>3] & (0x80>>(oc&7)) )
2229 0 : pt[c>>3] |= (0x80>>(c&7));
2230 : }
2231 : }
2232 0 : } else if ( base->image_type==it_index ) {
2233 0 : for ( r=0; r<size->height; ++r ) {
2234 0 : int or = ((int) floor( (r+size->y)/yscale ));
2235 0 : uint8 *pt = data+r*tbase.bytes_per_line;
2236 0 : uint8 *opt = base->data+or*base->bytes_per_line;
2237 0 : for ( c=0; c<size->width; ++c ) {
2238 0 : int oc = ((int) floor( (c+size->x)/xscale));
2239 0 : *pt++ = opt[oc];
2240 : }
2241 : }
2242 : } else {
2243 0 : for ( r=0; r<size->height; ++r ) {
2244 0 : int or = ((int) floor( (r+size->y)/yscale ));
2245 0 : uint32 *pt = (uint32 *) (data+r*tbase.bytes_per_line);
2246 0 : uint32 *opt = (uint32 *) (base->data+or*base->bytes_per_line);
2247 0 : for ( c=0; c<size->width; ++c ) {
2248 0 : int oc = ((int) floor( (c+size->x)/xscale));
2249 0 : *pt++ = opt[oc];
2250 : }
2251 : }
2252 : }
2253 0 : return( &temp );
2254 : }
2255 :
2256 : /* Given an image, magnify it so that its width/height are as specified */
2257 : /* then extract the given given rectangle (in magnified coords) and */
2258 : /* place it on the screen at x,y */
2259 0 : void _GXDraw_ImageMagnified(GWindow _w, GImage *image, GRect *magsrc,
2260 : int32 x, int32 y, int32 width, int32 height) {
2261 0 : GXWindow gw = (GXWindow) _w;
2262 0 : GXDisplay *gdisp = gw->display;
2263 0 : struct _GImage *base = image->list_len==0?image->u.image:image->u.images[0];
2264 : double xscale, yscale;
2265 : GRect full, viewable;
2266 : GImage *temp;
2267 : GRect src;
2268 :
2269 : #ifndef _NO_LIBCAIRO
2270 0 : if ( gw->usecairo ) {
2271 0 : _GXCDraw_ImageMagnified(gw,image,magsrc,x,y,width,height);
2272 0 : return;
2273 : }
2274 : #endif
2275 :
2276 0 : _GXDraw_SetClipFunc(gdisp,gw->ggc);
2277 0 : viewable = gw->ggc->clip;
2278 0 : if ( viewable.width > gw->pos.width-viewable.x )
2279 0 : viewable.width = gw->pos.width-viewable.x;
2280 0 : if ( viewable.height > gw->pos.height-viewable.y )
2281 0 : viewable.height = gw->pos.height-viewable.y;
2282 :
2283 0 : xscale = (base->width>=1) ? ((double) (width))/(base->width) : 1;
2284 0 : yscale = (base->height>=1) ? ((double) (height))/(base->height) : 1;
2285 : /* Intersect the clip rectangle with the scaled image to find the */
2286 : /* portion of screen that we want to draw */
2287 0 : if ( viewable.x<x ) {
2288 0 : viewable.width -= (x-viewable.x);
2289 0 : viewable.x = x;
2290 : }
2291 0 : if ( viewable.y<y ) {
2292 0 : viewable.height -= (y-viewable.y);
2293 0 : viewable.y = y;
2294 : }
2295 0 : if ( viewable.x+viewable.width > x+width ) viewable.width = x+width - viewable.x;
2296 0 : if ( viewable.y+viewable.height > y+height ) viewable.height = y+height - viewable.y;
2297 0 : if ( viewable.height<0 || viewable.width<0 )
2298 0 : return;
2299 :
2300 : /* Now find that same rectangle in the coordinates of the unscaled image */
2301 : /* (translation & scale) */
2302 0 : viewable.x -= x; viewable.y -= y;
2303 0 : full.x = viewable.x/xscale; full.y = viewable.y/yscale;
2304 0 : full.width = viewable.width/xscale; full.height = viewable.height/yscale;
2305 0 : if ( full.x+full.width>base->width ) full.width = base->width-full.x; /* Rounding errors */
2306 0 : if ( full.y+full.height>base->height ) full.height = base->height-full.y; /* Rounding errors */
2307 : /* Rounding errors */
2308 :
2309 0 : temp = _GImageExtract(base,&full,&viewable,xscale,yscale);
2310 0 : src.x = src.y = 0; src.width = viewable.width; src.height = viewable.height;
2311 0 : _GXDraw_Image( _w, temp, &src, x+viewable.x, y+viewable.y);
2312 : }
2313 :
2314 0 : static GImage *xi1_to_gi1(GXDisplay *gdisp,XImage *xi) {
2315 : GImage *gi;
2316 : struct _GImage *base;
2317 :
2318 0 : gi = calloc(1,sizeof(GImage));
2319 0 : if ( gi==NULL )
2320 0 : return( NULL );
2321 0 : base = malloc(sizeof(struct _GImage));
2322 0 : if ( base==NULL ) {
2323 0 : free(gi);
2324 0 : return( NULL );
2325 : }
2326 0 : gi->u.image = base;
2327 0 : base->image_type = it_mono;
2328 0 : base->width = xi->width;
2329 0 : base->height = xi->height;
2330 0 : base->bytes_per_line = xi->bytes_per_line;
2331 0 : base->data = (uint8 *) (xi->data);
2332 0 : base->clut = NULL;
2333 0 : base->trans = COLOR_UNKNOWN;
2334 :
2335 0 : if ( xi->bitmap_bit_order==LSBFirst ) {
2336 : /* sigh. The server doesn't use our convention. invert all bytes */
2337 0 : int len = base->height*base->bytes_per_line;
2338 0 : uint8 *newdata = malloc(len), *pt, *ipt, *end;
2339 : int m1,m2,val;
2340 :
2341 0 : for ( ipt = (uint8 *) xi->data, pt=newdata, end=pt+len; pt<end; ++pt, ++ipt ) {
2342 0 : val = 0;
2343 0 : for ( m1=1, m2=0x80; m2!=0; m1<<=1, m2>>=1 )
2344 0 : if ( *ipt&m1 ) val|=m2;
2345 0 : *pt = val;
2346 : }
2347 0 : base->data = newdata;
2348 : } else
2349 0 : xi->data = NULL;
2350 0 : return( gi );
2351 : }
2352 :
2353 0 : static GImage *xi8_to_gi8(GXDisplay *gdisp,XImage *xi) {
2354 : GImage *gi;
2355 : struct _GImage *base;
2356 : GClut *clut;
2357 : int i;
2358 : XColor cols[256];
2359 :
2360 0 : gi = calloc(1,sizeof(GImage));
2361 0 : if ( gi==NULL )
2362 0 : return( NULL );
2363 0 : base = malloc(sizeof(struct _GImage));
2364 0 : if ( base ==NULL ) {
2365 0 : free(gi);
2366 0 : return( NULL );
2367 : }
2368 0 : clut = malloc(sizeof(GClut));
2369 0 : if ( clut ==NULL ) {
2370 0 : free(base);
2371 0 : free(gi);
2372 0 : return( NULL );
2373 : }
2374 0 : gi->u.image = base;
2375 0 : base->image_type = it_index;
2376 0 : base->width = xi->width;
2377 0 : base->height = xi->height;
2378 0 : base->bytes_per_line = xi->bytes_per_line;
2379 0 : base->data = (uint8 *) xi->data;
2380 0 : base->clut = clut;
2381 0 : base->trans = COLOR_UNKNOWN;
2382 :
2383 0 : clut->clut_len = 256;
2384 0 : for ( i=0; i<(1<<gdisp->pixel_size); ++i )
2385 0 : cols[i].pixel = i;
2386 0 : XQueryColors(gdisp->display,gdisp->cmap,cols,1<<gdisp->pixel_size);
2387 0 : for ( i=0; i<(1<<gdisp->pixel_size); ++i )
2388 0 : clut->clut[i] = COLOR_CREATE(cols[i].red>>8, cols[i].green>>8, cols[i].blue>>8);
2389 0 : clut->is_grey = ( gdisp->visual->class==StaticGray || gdisp->visual->class==GrayScale );
2390 0 : return( gi );
2391 : }
2392 :
2393 0 : static GImage *xi16_to_gi32(GXDisplay *gdisp,XImage *xi) {
2394 : GImage *gi;
2395 : struct _GImage *base;
2396 : uint16 *pt; uint32 *ipt, val;
2397 : int i,j,rs,gs,bs;
2398 0 : int rs2,gs2=0,bs2;
2399 : int rm, gm, bm;
2400 :
2401 0 : if (( gi = GImageCreate(it_true,xi->width,xi->height))==NULL )
2402 0 : return( NULL );
2403 0 : base = gi->u.image;
2404 :
2405 0 : rs = gdisp->cs.red_shift; gs = gdisp->cs.green_shift; bs = gdisp->cs.blue_shift;
2406 0 : rm = gdisp->visual->red_mask; gm = gdisp->visual->green_mask; bm = gdisp->visual->blue_mask;
2407 0 : if ( rs>gs && rs>bs ) {
2408 0 : rs2 = 8-(16-rs);
2409 0 : if ( gs>bs ) {
2410 0 : bs2 = 8-gs2;
2411 0 : gs2 = 8-(rs-gs);
2412 : } else {
2413 0 : gs2 = 8-bs;
2414 0 : bs2 = 8-(rs-bs);
2415 : }
2416 0 : } else if ( gs>rs && gs>bs ) {
2417 0 : gs2 = 8-(16-gs);
2418 0 : if ( rs>bs ) {
2419 0 : bs2 = 8-rs;
2420 0 : rs2 = 8-(gs-rs);
2421 : } else {
2422 0 : rs2 = 8-bs;
2423 0 : bs2 = 8-(gs-bs);
2424 : }
2425 : } else {
2426 0 : bs2 = 8-(16-bs);
2427 0 : if ( rs>gs ) {
2428 0 : gs2 = 8-rs;
2429 0 : rs2 = 8-(bs-rs);
2430 : } else {
2431 0 : rs2 = 8-gs;
2432 0 : gs2 = 8-(bs-gs);
2433 : }
2434 : }
2435 :
2436 0 : for ( i=0; i<base->height; ++i ) {
2437 0 : pt = (uint16 *) (xi->data + i*xi->bytes_per_line);
2438 0 : ipt = (uint32 *) (base->data + i*base->bytes_per_line);
2439 0 : for ( j=0; j<base->width; ++j ) {
2440 0 : val = *pt++;
2441 0 : if ( val!=0 )
2442 0 : val = pt[-1];
2443 0 : *ipt++ = COLOR_CREATE(((val&rm)>>rs)<<rs2,((val&gm)>>gs)<<gs2,((val&bm)>>bs)<<bs2);
2444 : }
2445 : }
2446 0 : return( gi );
2447 : }
2448 :
2449 0 : static GImage *xi24_to_gi32(GXDisplay *gdisp,XImage *xi) {
2450 : GImage *gi;
2451 : struct _GImage *base;
2452 : uint8 *pt; uint32 *ipt, val;
2453 : int i,j,rs,gs,bs;
2454 :
2455 0 : if (( gi = GImageCreate(it_true,xi->width,xi->height))==NULL )
2456 0 : return( NULL );
2457 0 : base = gi->u.image;
2458 :
2459 0 : rs = gdisp->cs.red_shift; gs = gdisp->cs.green_shift; bs = gdisp->cs.blue_shift;
2460 0 : for ( i=0; i<base->height; ++i ) {
2461 0 : pt = (uint8 *) xi->data + i*xi->bytes_per_line;
2462 0 : ipt = (uint32 *) (base->data + i*base->bytes_per_line);
2463 0 : for ( j=0; j<base->width; ++j ) {
2464 0 : if ( xi->byte_order==MSBFirst ) {
2465 0 : val = *pt++;
2466 0 : val = (val<<8) + *pt++;
2467 0 : val = (val<<8) + *pt++;
2468 : } else {
2469 0 : val = *pt++;
2470 0 : val |= (*pt++<<8);
2471 0 : val |= (*pt++<<16);
2472 : }
2473 0 : *ipt++ = COLOR_CREATE((val>>rs)&0xff,(val>>gs)&0xff,(val>>bs)&0xff);
2474 : }
2475 : }
2476 0 : return( gi );
2477 : }
2478 :
2479 0 : static GImage *xi32_to_gi32(GXDisplay *gdisp,XImage *xi) {
2480 : GImage *gi;
2481 : struct _GImage *base;
2482 : uint32 *pt; uint32 *ipt, val;
2483 : int i,j,rs,gs,bs;
2484 :
2485 0 : if (( gi = GImageCreate(it_true,xi->width,xi->height))==NULL )
2486 0 : return( NULL );
2487 0 : base = gi->u.image;
2488 :
2489 0 : rs = gdisp->cs.red_shift; gs = gdisp->cs.green_shift; bs = gdisp->cs.blue_shift;
2490 0 : for ( i=0; i<base->height; ++i ) {
2491 0 : pt = (uint32 *) (xi->data + i*xi->bytes_per_line);
2492 0 : ipt = (uint32 *) (base->data + i*base->bytes_per_line);
2493 0 : for ( j=0; j<base->width; ++j ) {
2494 0 : val = *pt++;
2495 0 : *ipt++ = COLOR_CREATE((val>>rs)&0xff,(val>>gs)&0xff,(val>>bs)&0xff);
2496 : }
2497 : }
2498 0 : return( gi );
2499 : }
2500 :
2501 0 : GImage *_GXDraw_CopyScreenToImage(GWindow _w, GRect *rect) {
2502 0 : GXWindow gw = (GXWindow) _w;
2503 0 : GXDisplay *gdisp = gw->display;
2504 0 : Display *display=gdisp->display;
2505 0 : Window w = gw->w;
2506 : int depth;
2507 : XImage *xi;
2508 0 : GImage *gi=NULL;
2509 :
2510 0 : depth = gdisp->pixel_size;
2511 0 : if ( gw->ggc->bitmap_col ) depth = 1;
2512 :
2513 0 : if ( depth!=1 && depth!=8 && depth!=16 && depth!=24 && depth!=32 )
2514 0 : return( NULL );
2515 0 : xi = XGetImage(display,w,rect->x,rect->y, rect->width, rect->height,
2516 : -1,ZPixmap);
2517 0 : if ( xi==NULL )
2518 0 : return( NULL );
2519 0 : switch ( xi->bits_per_pixel ) {
2520 : case 1:
2521 0 : gi = xi1_to_gi1(gdisp,xi);
2522 0 : break;
2523 : case 8:
2524 0 : gi = xi8_to_gi8(gdisp,xi);
2525 0 : break;
2526 : case 16:
2527 0 : gi = xi16_to_gi32(gdisp,xi);
2528 0 : break;
2529 : case 24:
2530 0 : gi = xi24_to_gi32(gdisp,xi);
2531 0 : break;
2532 : case 32:
2533 0 : gi = xi32_to_gi32(gdisp,xi);
2534 0 : break;
2535 : }
2536 0 : XDestroyImage(xi);
2537 0 : return( gi );
2538 : }
2539 : #else /* NO X */
2540 : int gimagexdraw_a_file_must_define_something=3;
2541 : #endif
|