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.7 by sf-exg, Sun Jun 3 20:34:25 2012 UTC vs.
Revision 1.25 by sf-exg, Tue Jun 5 22:00:15 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{
192 //TODO 248 Display *dpy = s->display->dpy;
193}
194 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 for (int y = 0; y < height; y++)
298 {
299 for (int x = 0; x < width; x++)
300 {
301 unsigned char *pixel = row + x * channels;
302 uint32_t value;
303 unsigned char r, g, b, a;
304
305 if (channels == 4)
306 {
307 a = pixel[3];
308 r = pixel[0] * a / 0xff;
309 g = pixel[1] * a / 0xff;
310 b = pixel[2] * a / 0xff;
311 }
312 else
313 {
314 a = 0xff;
315 r = pixel[0];
316 g = pixel[1];
317 b = pixel[2];
318 }
319
320 value = ((r >> (8 - width_r)) << sh_r)
321 | ((g >> (8 - width_g)) << sh_g)
322 | ((b >> (8 - width_b)) << sh_b)
323 | ((a >> (8 - width_a)) << sh_a);
324
325 if (ximage->bits_per_pixel == 32)
326 ((uint32_t *)line)[x] = value;
327 else
328 XPutPixel (ximage, x, y, value);
329 }
330
331 row += rowstride;
332 line += ximage->bytes_per_line;
333 }
334
335 XPutImage (dpy, pm, gc, ximage, 0, 0, dst_x, dst_y, width, height);
336 XDestroyImage (ximage);
337 XFreeGC (dpy, gc);
338
339 return true;
340}
341
195rxvt_img * 342rxvt_img *
196rxvt_img::copy () 343rxvt_img::clone ()
197{ 344{
345 rxvt_img *img = new rxvt_img (s, format, w, h);
346
198 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 347 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); 348 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
201 XFreeGC (s->display->dpy, gc); 349 XFreeGC (s->display->dpy, gc);
202 return new rxvt_img (s, format, w, h, pm2);
203}
204 350
351 return img;
352}
353
205rxvt_img * 354rxvt_img *
355rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
356{
357 rxvt_img *img = new rxvt_img (s, format, width, height);
358
359 Display *dpy = s->display->dpy;
360 XRenderPictureAttributes pa;
361 pa.repeat = repeat;
362 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
363 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
364
365 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height);
366
367 XRenderFreePicture (dpy, src);
368 XRenderFreePicture (dpy, dst);
369
370 return img;
371}
372
373rxvt_img *
206rxvt_img::transform (int new_width, int new_height, double matrix[16]) 374rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat)
207{ 375{
208 //TODO 376 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
377
378 Display *dpy = s->display->dpy;
379 XRenderPictureAttributes pa;
380 pa.repeat = repeat;
381 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
382 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
383
384 XTransform xfrm;
385
386 for (int i = 0; i < 3; ++i)
387 for (int j = 0; j < 3; ++j)
388 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
389
390 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
391 XRenderSetPictureTransform (dpy, src, &xfrm);
392 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
393
394 XRenderFreePicture (dpy, src);
395 XRenderFreePicture (dpy, dst);
396
397 return img;
209} 398}
210 399
211rxvt_img * 400rxvt_img *
212rxvt_img::scale (int new_width, int new_height) 401rxvt_img::scale (int new_width, int new_height)
213{ 402{
214 // use transform 403 double matrix[9] = {
215 //TODO 404 w / (double)new_width, 0, 0,
405 0, h / (double)new_height, 0,
406 0, 0, 1
407 };
408
409 return transform (new_width, new_height, matrix);
410}
411
412rxvt_img *
413rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat)
414{
415 double s = sin (phi);
416 double c = cos (phi);
417
418 double matrix[9] = {
419 c, -s, -c * x + s * y + x,
420 s, c, -s * x - c * y + y,
421 0, 0, 1
422 };
423
424 return transform (new_width, new_height, matrix, repeat);
216} 425}
217 426
218rxvt_img * 427rxvt_img *
219rxvt_img::convert_to (XRenderPictFormat *new_format) 428rxvt_img::convert_to (XRenderPictFormat *new_format)
220{ 429{
430 rxvt_img *img = new rxvt_img (s, new_format, w, h);
431
221 Display *dpy = s->display->dpy; 432 Display *dpy = s->display->dpy;
222 Pixmap new_pm = XCreatePixmap (dpy, pm, w, h, new_format->depth);
223 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 433 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
224 Picture dst = XRenderCreatePicture (dpy, new_pm, new_format, 0, 0); 434 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
225 435
226 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 436 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
227 437
228 XRenderFreePicture (dpy, src); 438 XRenderFreePicture (dpy, src);
229 XRenderFreePicture (dpy, dst); 439 XRenderFreePicture (dpy, dst);
230 440
231 rxvt_img *img = new rxvt_img ( 441 return img;
232 s, 442}
233 new_format,
234 w,
235 h,
236 new_pm
237 );
238 443
444rxvt_img *
445rxvt_img::blend (rxvt_img *img, double factor)
446{
447 rxvt_img *img2 = clone ();
448 Display *dpy = s->display->dpy;
449 Picture src = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
450 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
451 Picture mask = create_xrender_mask (dpy, img->pm, False);
452
453 XRenderColor mask_c;
454
455 mask_c.alpha = float_to_component (factor);
456 mask_c.red =
457 mask_c.green =
458 mask_c.blue = 0;
459 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
460
461 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
462
463 XRenderFreePicture (dpy, src);
464 XRenderFreePicture (dpy, dst);
465 XRenderFreePicture (dpy, mask);
466
239 return img; 467 return img2;
240} 468}
241 469
242#endif 470#endif
243 471

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines