ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtimg.C
(Generate patch)

Comparing rxvt-unicode/src/rxvtimg.C (file contents):
Revision 1.10 by sf-exg, Mon Jun 4 06:59:50 2012 UTC vs.
Revision 1.22 by sf-exg, Tue Jun 5 15:18:23 2012 UTC

16: s(screen), pm(pixmap), w(width), h(height), format(format), shared(false) 16: s(screen), pm(pixmap), w(width), h(height), format(format), shared(false)
17{ 17{
18} 18}
19 19
20rxvt_img * 20rxvt_img *
21rxvt_img::new_from_root (rxvt_screen *s)
22{
23 Display *dpy = s->display->dpy;
24 unsigned int root_pm_w, root_pm_h;
25 Pixmap root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_XROOTPMAP_ID]);
26 if (root_pixmap == None)
27 root_pixmap = s->display->get_pixmap_property (s->display->xa[XA_ESETROOT_PMAP_ID]);
28
29 if (root_pixmap == None)
30 return 0;
31
32 Window wdummy;
33 int idummy;
34 unsigned int udummy;
35
36 if (!XGetGeometry (dpy, root_pixmap, &wdummy, &idummy, &idummy, &root_pm_w, &root_pm_h, &udummy, &udummy))
37 return 0;
38
39 rxvt_img *img = new rxvt_img (
40 s,
41 XRenderFindVisualFormat (dpy, DefaultVisual (dpy, s->display->screen)),
42 root_pm_w,
43 root_pm_h,
44 root_pixmap
45 );
46
47 img->shared = true;
48
49 return img;
50}
51
52rxvt_img *
21rxvt_img::new_from_file (rxvt_screen *s, const char *filename) 53rxvt_img::new_from_file (rxvt_screen *s, const char *filename)
22{ 54{
23 GError *err; 55 GError *err = 0;
24 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err); 56 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err);
25 57
26 if (!pb) 58 if (!pb)
27 return 0; 59 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
28 60
29 rxvt_img *img = new rxvt_img ( 61 rxvt_img *img = new rxvt_img (
30 s, 62 s,
31 XRenderFindStandardFormat (s->display->dpy, gdk_pixbuf_get_has_alpha (pb) ? PictStandardARGB32 : PictStandardRGB24), 63 XRenderFindStandardFormat (s->display->dpy, gdk_pixbuf_get_has_alpha (pb) ? PictStandardARGB32 : PictStandardRGB24),
32 gdk_pixbuf_get_width (pb), 64 gdk_pixbuf_get_width (pb),
33 gdk_pixbuf_get_height (pb) 65 gdk_pixbuf_get_height (pb)
34 ); 66 );
35 67
36 img->render (pb, 0, 0, img->w, img->h, 0, 0); 68 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);
37 69
38 return img; 70 return img;
39} 71}
40 72
41rxvt_img::~rxvt_img () 73rxvt_img::~rxvt_img ()
42{ 74{
43 if (!shared) 75 if (!shared)
44 XFreePixmap (s->display->dpy, pm); 76 XFreePixmap (s->display->dpy, pm);
77}
78
79void
80rxvt_img::unshare ()
81{
82 if (!shared)
83 return;
84
85 rxvt_img *img = clone ();
86
87 ::swap (pm , img->pm);
88 ::swap (shared, img->shared);
89
90 delete img;
45} 91}
46 92
47void 93void
48rxvt_img::fill (const rxvt_color &c) 94rxvt_img::fill (const rxvt_color &c)
49{ 95{
73 119
74 for (int i = 0; i < width; i++) 120 for (int i = 0; i < width; i++)
75 params[i+2] = XDoubleToFixed (kernel[i] / sum); 121 params[i+2] = XDoubleToFixed (kernel[i] / sum);
76} 122}
77 123
78void 124rxvt_img *
79rxvt_img::blur (int rh, int rv) 125rxvt_img::blur (int rh, int rv)
80{ 126{
81 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 127 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
82 return; 128 return clone ();
83 129
84 Display *dpy = s->display->dpy; 130 Display *dpy = s->display->dpy;
85 int size = max (rh, rv) * 2 + 1; 131 int size = max (rh, rv) * 2 + 1;
86 double *kernel = (double *)malloc (size * sizeof (double)); 132 double *kernel = (double *)malloc (size * sizeof (double));
87 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 133 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
134 rxvt_img *img = new rxvt_img (s, format, w, h);
88 135
89 XRenderPictureAttributes pa; 136 XRenderPictureAttributes pa;
90 137
91 pa.repeat = RepeatPad; 138 pa.repeat = RepeatPad;
92 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 139 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa);
140 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
141
93 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 142 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
94 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 143 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
95 XFreePixmap (dpy, tmp); 144 XFreePixmap (dpy, tmp_pm);
96 145
97 if (kernel && params) 146 if (kernel && params)
98 { 147 {
99 size = rh * 2 + 1; 148 size = rh * 2 + 1;
100 get_gaussian_kernel (rh, size, kernel, params); 149 get_gaussian_kernel (rh, size, kernel, params);
102 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 151 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
103 XRenderComposite (dpy, 152 XRenderComposite (dpy,
104 PictOpSrc, 153 PictOpSrc,
105 src, 154 src,
106 None, 155 None,
107 dst, 156 tmp,
108 0, 0, 157 0, 0,
109 0, 0, 158 0, 0,
110 0, 0, 159 0, 0,
111 w, h); 160 w, h);
112
113 ::swap (src, dst);
114 161
115 size = rv * 2 + 1; 162 size = rv * 2 + 1;
116 get_gaussian_kernel (rv, size, kernel, params); 163 get_gaussian_kernel (rv, size, kernel, params);
117 ::swap (params[0], params[1]); 164 ::swap (params[0], params[1]);
118 165
119 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 166 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
120 XRenderComposite (dpy, 167 XRenderComposite (dpy,
121 PictOpSrc, 168 PictOpSrc,
122 src, 169 tmp,
123 None, 170 None,
124 dst, 171 dst,
125 0, 0, 172 0, 0,
126 0, 0, 173 0, 0,
127 0, 0, 174 0, 0,
130 177
131 free (kernel); 178 free (kernel);
132 free (params); 179 free (params);
133 XRenderFreePicture (dpy, src); 180 XRenderFreePicture (dpy, src);
134 XRenderFreePicture (dpy, dst); 181 XRenderFreePicture (dpy, dst);
182 XRenderFreePicture (dpy, tmp);
183
184 return img;
135} 185}
136 186
137static Picture 187static Picture
138create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 188create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
139{ 189{
184 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 234 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
185 235
186 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 236 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
187} 237}
188 238
189void 239bool
190rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 240rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
191{ 241{
242 Display *dpy = s->display->dpy;
243
244 if (s->visual->c_class != TrueColor)
245 return false;
246
247 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
248
249 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
250 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
251 blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue;
252 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
253
254 int width_r = ecb_popcount32 (red_mask);
255 int width_g = ecb_popcount32 (green_mask);
256 int width_b = ecb_popcount32 (blue_mask);
257 int width_a = ecb_popcount32 (alpha_mask);
258
259 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
260 return false;
261
262 int sh_r = ecb_ctz32 (red_mask);
263 int sh_g = ecb_ctz32 (green_mask);
264 int sh_b = ecb_ctz32 (blue_mask);
265 int sh_a = ecb_ctz32 (alpha_mask);
266
267 if (width > 32767 || height > 32767)
268 return false;
269
270 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
271 width, height, 32, 0);
272 if (!ximage)
273 return false;
274
275 if (height > INT_MAX / ximage->bytes_per_line
276 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
277 {
278 XDestroyImage (ximage);
279 return false;
280 }
281
282 GC gc = XCreateGC (dpy, pm, 0, 0);
283
284 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
285
286 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
287 int channels = gdk_pixbuf_get_n_channels (pixbuf);
288 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
289 char *line = ximage->data;
290
291 rgba c (0, 0, 0);
292
293 if (channels == 4 && alpha_mask == 0)
294 {
295 //pix_colors[Color_bg].get (c);
192 //TODO 296 //TODO
193} 297 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
298 c.r >>= 8;
299 c.g >>= 8;
300 c.b >>= 8;
301 }
194 302
303 for (int y = 0; y < height; y++)
304 {
305 for (int x = 0; x < width; x++)
306 {
307 unsigned char *pixel = row + x * channels;
308 uint32_t value;
309 unsigned char r, g, b, a;
310
311 if (channels == 4)
312 {
313 a = pixel[3];
314 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
315 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
316 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
317 }
318 else
319 {
320 a = 0xff;
321 r = pixel[0];
322 g = pixel[1];
323 b = pixel[2];
324 }
325
326 value = ((r >> (8 - width_r)) << sh_r)
327 | ((g >> (8 - width_g)) << sh_g)
328 | ((b >> (8 - width_b)) << sh_b)
329 | ((a >> (8 - width_a)) << sh_a);
330
331 if (ximage->bits_per_pixel == 32)
332 ((uint32_t *)line)[x] = value;
333 else
334 XPutPixel (ximage, x, y, value);
335 }
336
337 row += rowstride;
338 line += ximage->bytes_per_line;
339 }
340
341 XPutImage (dpy, pm, gc, ximage, 0, 0, dst_x, dst_y, width, height);
342 XDestroyImage (ximage);
343 XFreeGC (dpy, gc);
344
345 return true;
346}
347
195rxvt_img * 348rxvt_img *
196rxvt_img::copy () 349rxvt_img::clone ()
197{ 350{
351 rxvt_img *img = new rxvt_img (s, format, w, h);
352
198 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 353 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
199 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
200 XCopyArea (s->display->dpy, pm, pm2, gc, 0, 0, w, h, 0, 0); 354 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
201 XFreeGC (s->display->dpy, gc); 355 XFreeGC (s->display->dpy, gc);
202 return new rxvt_img (s, format, w, h, pm2);
203}
204 356
205rxvt_img * 357 return img;
206rxvt_img::transform (int new_width, int new_height, double matrix[16])
207{
208 //TODO
209} 358}
210 359
211rxvt_img * 360rxvt_img *
212rxvt_img::scale (int new_width, int new_height) 361rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
213{ 362{
214 // use transform
215 //TODO
216}
217
218rxvt_img *
219rxvt_img::convert_to (XRenderPictFormat *new_format)
220{
221 rxvt_img *img = new rxvt_img (s, new_format, w, h); 363 rxvt_img *img = new rxvt_img (s, format, width, height);
222 364
223 Display *dpy = s->display->dpy; 365 Display *dpy = s->display->dpy;
366 XRenderPictureAttributes pa;
367 pa.repeat = repeat;
224 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 368 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
225 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 369 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
226 370
227 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 371 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height);
228 372
229 XRenderFreePicture (dpy, src); 373 XRenderFreePicture (dpy, src);
230 XRenderFreePicture (dpy, dst); 374 XRenderFreePicture (dpy, dst);
231 375
232 return img; 376 return img;
233} 377}
234 378
379rxvt_img *
380rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat)
381{
382 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
383
384 Display *dpy = s->display->dpy;
385 XRenderPictureAttributes pa;
386 pa.repeat = repeat;
387 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
388 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
389
390 XTransform xfrm;
391
392 for (int i = 0; i < 3; ++i)
393 for (int j = 0; j < 3; ++j)
394 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
395
396 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
397 XRenderSetPictureTransform (dpy, src, &xfrm);
398 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
399
400 XRenderFreePicture (dpy, src);
401 XRenderFreePicture (dpy, dst);
402
403 return img;
404}
405
406rxvt_img *
407rxvt_img::scale (int new_width, int new_height)
408{
409 double matrix[9] = {
410 w / (double)new_width, 0, 0,
411 0, h / (double)new_height, 0,
412 0, 0, 1
413 };
414
415 return transform (new_width, new_height, matrix);
416}
417
418rxvt_img *
419rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat)
420{
421 double s = sin (phi);
422 double c = cos (phi);
423
424 double matrix[9] = {
425 c, -s, -c * x + s * y + x,
426 s, c, -s * x - c * y + y,
427 0, 0, 1
428 };
429
430 return transform (new_width, new_height, matrix, repeat);
431}
432
433rxvt_img *
434rxvt_img::convert_to (XRenderPictFormat *new_format)
435{
436 rxvt_img *img = new rxvt_img (s, new_format, w, h);
437
438 Display *dpy = s->display->dpy;
439 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
440 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
441
442 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
443
444 XRenderFreePicture (dpy, src);
445 XRenderFreePicture (dpy, dst);
446
447 return img;
448}
449
235#endif 450#endif
236 451

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines