Contents of /trunk/cairo/patches/cairo-1.0.0-display_endianness.patch
Parent Directory | Revision Log
Revision 144 -
(show annotations)
(download)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 5142 byte(s)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 5142 byte(s)
-import
1 | diff -NurdB cairo-1.0.0/src/cairo-xlib-surface.c cairo-1.0.0-patched/src/cairo-xlib-surface.c |
2 | --- cairo-1.0.0/src/cairo-xlib-surface.c 2005-08-24 00:42:19.000000000 -0500 |
3 | +++ cairo-1.0.0-patched/src/cairo-xlib-surface.c 2005-09-02 10:12:59.000000000 -0500 |
4 | @@ -60,6 +60,9 @@ |
5 | static cairo_bool_t |
6 | _cairo_surface_is_xlib (cairo_surface_t *surface); |
7 | |
8 | +static cairo_bool_t |
9 | +_native_byte_order_lsb (void); |
10 | + |
11 | /* |
12 | * Instead of taking two round trips for each blending request, |
13 | * assume that if a particular drawable fails GetImage that it will |
14 | @@ -302,6 +305,116 @@ |
15 | return False; |
16 | } |
17 | |
18 | +static void |
19 | +_swap_ximage_2bytes (XImage *ximage) |
20 | +{ |
21 | + int i, j; |
22 | + char *line = ximage->data; |
23 | + |
24 | + for (j = ximage->height; j; j--) { |
25 | + uint16_t *p = (uint16_t *)line; |
26 | + for (i = ximage->width; i; i--) { |
27 | + *p = (((*p & 0x00ff) << 8) | |
28 | + ((*p) >> 8)); |
29 | + p++; |
30 | + } |
31 | + |
32 | + line += ximage->bytes_per_line; |
33 | + } |
34 | +} |
35 | + |
36 | +static void |
37 | +_swap_ximage_4bytes (XImage *ximage) |
38 | +{ |
39 | + int i, j; |
40 | + char *line = ximage->data; |
41 | + |
42 | + for (j = ximage->height; j; j--) { |
43 | + uint32_t *p = (uint32_t *)line; |
44 | + for (i = ximage->width; i; i--) { |
45 | + *p = (((*p & 0x000000ff) << 24) | |
46 | + ((*p & 0x0000ff00) << 8) | |
47 | + ((*p & 0x00ff0000) >> 8) | |
48 | + ((*p) >> 24)); |
49 | + p++; |
50 | + } |
51 | + |
52 | + line += ximage->bytes_per_line; |
53 | + } |
54 | +} |
55 | + |
56 | +static void |
57 | +_swap_ximage_bits (XImage *ximage) |
58 | +{ |
59 | + int i, j; |
60 | + char *line = ximage->data; |
61 | + int unit = ximage->bitmap_unit; |
62 | + int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8; |
63 | + |
64 | + for (j = ximage->height; j; j--) { |
65 | + char *p = line; |
66 | + |
67 | + for (i = line_bytes; i; i--) { |
68 | + char b = *p; |
69 | + b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55); |
70 | + b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33); |
71 | + b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f); |
72 | + *p = b; |
73 | + |
74 | + p++; |
75 | + } |
76 | + |
77 | + line += ximage->bytes_per_line; |
78 | + } |
79 | +} |
80 | + |
81 | +static void |
82 | +_swap_ximage_to_native (XImage *ximage) |
83 | +{ |
84 | + int unit_bytes = 0; |
85 | + int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst; |
86 | + |
87 | + if (ximage->bits_per_pixel == 1 && |
88 | + ximage->bitmap_bit_order != native_byte_order) { |
89 | + _swap_ximage_bits (ximage); |
90 | + if (ximage->bitmap_bit_order == ximage->byte_order) |
91 | + return; |
92 | + } |
93 | + |
94 | + if (ximage->byte_order == native_byte_order) |
95 | + return; |
96 | + |
97 | + switch (ximage->bits_per_pixel) { |
98 | + case 1: |
99 | + unit_bytes = ximage->bitmap_unit / 8; |
100 | + break; |
101 | + case 8: |
102 | + case 16: |
103 | + case 32: |
104 | + unit_bytes = ximage->bits_per_pixel / 8; |
105 | + break; |
106 | + default: |
107 | + /* This could be hit on some uncommon but possible cases, |
108 | + * such as bpp=4. These are cases that libpixman can't deal |
109 | + * with in any case. |
110 | + */ |
111 | + ASSERT_NOT_REACHED; |
112 | + } |
113 | + |
114 | + switch (unit_bytes) { |
115 | + case 1: |
116 | + return; |
117 | + case 2: |
118 | + _swap_ximage_2bytes (ximage); |
119 | + break; |
120 | + case 4: |
121 | + _swap_ximage_4bytes (ximage); |
122 | + break; |
123 | + default: |
124 | + ASSERT_NOT_REACHED; |
125 | + } |
126 | +} |
127 | + |
128 | static cairo_status_t |
129 | _get_image_surface (cairo_xlib_surface_t *surface, |
130 | cairo_rectangle_t *interest_rect, |
131 | @@ -405,6 +518,8 @@ |
132 | } |
133 | if (!ximage) |
134 | return CAIRO_STATUS_NO_MEMORY; |
135 | + |
136 | + _swap_ximage_to_native (ximage); |
137 | |
138 | /* |
139 | * Compute the pixel format masks from either a visual or a |
140 | @@ -545,40 +660,35 @@ |
141 | int dst_x, |
142 | int dst_y) |
143 | { |
144 | - XImage *ximage; |
145 | - unsigned bitmap_pad; |
146 | - |
147 | - /* XXX this is wrong */ |
148 | - if (image->depth > 16) |
149 | - bitmap_pad = 32; |
150 | - else if (image->depth > 8) |
151 | - bitmap_pad = 16; |
152 | - else |
153 | - bitmap_pad = 8; |
154 | - |
155 | - ximage = XCreateImage (surface->dpy, |
156 | - DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)), |
157 | - image->depth, |
158 | - ZPixmap, |
159 | - 0, |
160 | - (char *) image->data, |
161 | - image->width, |
162 | - image->height, |
163 | - bitmap_pad, |
164 | - image->stride); |
165 | - if (ximage == NULL) |
166 | - return CAIRO_STATUS_NO_MEMORY; |
167 | + XImage ximage; |
168 | + int bpp, alpha, red, green, blue; |
169 | + int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst; |
170 | + |
171 | + pixman_format_get_masks (pixman_image_get_format (image->pixman_image), |
172 | + &bpp, &alpha, &red, &green, &blue); |
173 | + |
174 | + ximage.width = image->width; |
175 | + ximage.height = image->height; |
176 | + ximage.format = ZPixmap; |
177 | + ximage.data = (char *)image->data; |
178 | + ximage.byte_order = native_byte_order; |
179 | + ximage.bitmap_unit = 32; /* always for libpixman */ |
180 | + ximage.bitmap_bit_order = native_byte_order; |
181 | + ximage.bitmap_pad = 32; /* always for libpixman */ |
182 | + ximage.depth = image->depth; |
183 | + ximage.bytes_per_line = image->stride; |
184 | + ximage.bits_per_pixel = bpp; |
185 | + ximage.red_mask = red; |
186 | + ximage.green_mask = green; |
187 | + ximage.blue_mask = blue; |
188 | |
189 | + XInitImage (&ximage); |
190 | + |
191 | _cairo_xlib_surface_ensure_gc (surface); |
192 | XPutImage(surface->dpy, surface->drawable, surface->gc, |
193 | - ximage, 0, 0, dst_x, dst_y, |
194 | + &ximage, 0, 0, dst_x, dst_y, |
195 | image->width, image->height); |
196 | |
197 | - /* Foolish XDestroyImage thinks it can free my data, but I won't |
198 | - stand for it. */ |
199 | - ximage->data = NULL; |
200 | - XDestroyImage (ximage); |
201 | - |
202 | return CAIRO_STATUS_SUCCESS; |
203 | |
204 | } |