Annotation of /trunk/cairo/patches/cairo-1.0.0-display_endianness.patch
Parent Directory | Revision Log
Revision 144 -
(hide 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 | niro | 144 | 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 | } |