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.6 by sf-exg, Sun Jun 3 18:49:55 2012 UTC vs.
Revision 1.23 by sf-exg, Tue Jun 5 18:48:21 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{
162 mask_c.blue = float_to_component (b); 212 mask_c.blue = float_to_component (b);
163 mask_c.alpha = float_to_component (a); 213 mask_c.alpha = float_to_component (a);
164 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 214 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
165 215
166 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 216 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
217
218 XRenderFreePicture (dpy, src);
219 XRenderFreePicture (dpy, dst);
167} 220}
168 221
169void 222void
170rxvt_img::contrast (double r, double g, double b, double a) 223rxvt_img::contrast (double r, double g, double b, double a)
171{ 224{
182 mask_c.blue = float_to_component (b); 235 mask_c.blue = float_to_component (b);
183 mask_c.alpha = float_to_component (a); 236 mask_c.alpha = float_to_component (a);
184 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 237 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
185 238
186 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 239 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
187}
188 240
189void 241 XRenderFreePicture (dpy, src);
242 XRenderFreePicture (dpy, dst);
243}
244
245bool
190rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 246rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
191{ 247{
248 Display *dpy = s->display->dpy;
249
250 if (s->visual->c_class != TrueColor)
251 return false;
252
253 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
254
255 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
256 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
257 blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue;
258 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
259
260 int width_r = ecb_popcount32 (red_mask);
261 int width_g = ecb_popcount32 (green_mask);
262 int width_b = ecb_popcount32 (blue_mask);
263 int width_a = ecb_popcount32 (alpha_mask);
264
265 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
266 return false;
267
268 int sh_r = ecb_ctz32 (red_mask);
269 int sh_g = ecb_ctz32 (green_mask);
270 int sh_b = ecb_ctz32 (blue_mask);
271 int sh_a = ecb_ctz32 (alpha_mask);
272
273 if (width > 32767 || height > 32767)
274 return false;
275
276 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
277 width, height, 32, 0);
278 if (!ximage)
279 return false;
280
281 if (height > INT_MAX / ximage->bytes_per_line
282 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
283 {
284 XDestroyImage (ximage);
285 return false;
286 }
287
288 GC gc = XCreateGC (dpy, pm, 0, 0);
289
290 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
291
292 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
293 int channels = gdk_pixbuf_get_n_channels (pixbuf);
294 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
295 char *line = ximage->data;
296
297 rgba c (0, 0, 0);
298
299 if (channels == 4 && alpha_mask == 0)
300 {
301 //pix_colors[Color_bg].get (c);
192 //TODO 302 //TODO
193} 303 c.r = 0xffff; c.g = 0xc0c0; c.b = 0xcbcb;//D
304 c.r >>= 8;
305 c.g >>= 8;
306 c.b >>= 8;
307 }
194 308
309 for (int y = 0; y < height; y++)
310 {
311 for (int x = 0; x < width; x++)
312 {
313 unsigned char *pixel = row + x * channels;
314 uint32_t value;
315 unsigned char r, g, b, a;
316
317 if (channels == 4)
318 {
319 a = pixel[3];
320 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff;
321 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff;
322 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff;
323 }
324 else
325 {
326 a = 0xff;
327 r = pixel[0];
328 g = pixel[1];
329 b = pixel[2];
330 }
331
332 value = ((r >> (8 - width_r)) << sh_r)
333 | ((g >> (8 - width_g)) << sh_g)
334 | ((b >> (8 - width_b)) << sh_b)
335 | ((a >> (8 - width_a)) << sh_a);
336
337 if (ximage->bits_per_pixel == 32)
338 ((uint32_t *)line)[x] = value;
339 else
340 XPutPixel (ximage, x, y, value);
341 }
342
343 row += rowstride;
344 line += ximage->bytes_per_line;
345 }
346
347 XPutImage (dpy, pm, gc, ximage, 0, 0, dst_x, dst_y, width, height);
348 XDestroyImage (ximage);
349 XFreeGC (dpy, gc);
350
351 return true;
352}
353
195rxvt_img * 354rxvt_img *
196rxvt_img::copy () 355rxvt_img::clone ()
197{ 356{
357 rxvt_img *img = new rxvt_img (s, format, w, h);
358
198 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 359 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); 360 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
201 XFreeGC (s->display->dpy, gc); 361 XFreeGC (s->display->dpy, gc);
202 return new rxvt_img (s, format, w, h, pm2);
203}
204 362
363 return img;
364}
365
205rxvt_img * 366rxvt_img *
367rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
368{
369 rxvt_img *img = new rxvt_img (s, format, width, height);
370
371 Display *dpy = s->display->dpy;
372 XRenderPictureAttributes pa;
373 pa.repeat = repeat;
374 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
375 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
376
377 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height);
378
379 XRenderFreePicture (dpy, src);
380 XRenderFreePicture (dpy, dst);
381
382 return img;
383}
384
385rxvt_img *
206rxvt_img::transform (int new_width, int new_height, double matrix[16]) 386rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat)
207{ 387{
208 //TODO 388 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
389
390 Display *dpy = s->display->dpy;
391 XRenderPictureAttributes pa;
392 pa.repeat = repeat;
393 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
394 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
395
396 XTransform xfrm;
397
398 for (int i = 0; i < 3; ++i)
399 for (int j = 0; j < 3; ++j)
400 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
401
402 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
403 XRenderSetPictureTransform (dpy, src, &xfrm);
404 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
405
406 XRenderFreePicture (dpy, src);
407 XRenderFreePicture (dpy, dst);
408
409 return img;
209} 410}
210 411
211rxvt_img * 412rxvt_img *
212rxvt_img::scale (int new_width, int new_height) 413rxvt_img::scale (int new_width, int new_height)
213{ 414{
214 // use transform 415 double matrix[9] = {
215 //TODO 416 w / (double)new_width, 0, 0,
216} 417 0, h / (double)new_height, 0,
418 0, 0, 1
419 };
217 420
421 return transform (new_width, new_height, matrix);
422}
423
424rxvt_img *
425rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat)
426{
427 double s = sin (phi);
428 double c = cos (phi);
429
430 double matrix[9] = {
431 c, -s, -c * x + s * y + x,
432 s, c, -s * x - c * y + y,
433 0, 0, 1
434 };
435
436 return transform (new_width, new_height, matrix, repeat);
437}
438
439rxvt_img *
440rxvt_img::convert_to (XRenderPictFormat *new_format)
441{
442 rxvt_img *img = new rxvt_img (s, new_format, w, h);
443
444 Display *dpy = s->display->dpy;
445 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
446 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
447
448 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
449
450 XRenderFreePicture (dpy, src);
451 XRenderFreePicture (dpy, dst);
452
453 return img;
454}
218 455
219#endif 456#endif
220 457

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines