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