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.9 by root, Sun Jun 3 20:47:00 2012 UTC vs.
Revision 1.29 by root, Wed Jun 6 20:55:36 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);
69
70 g_object_unref (pb);
37 71
38 return img; 72 return img;
39} 73}
40 74
41rxvt_img::~rxvt_img () 75rxvt_img::~rxvt_img ()
42{ 76{
43 if (!shared) 77 if (!shared)
44 XFreePixmap (s->display->dpy, pm); 78 XFreePixmap (s->display->dpy, pm);
79}
80
81void
82rxvt_img::unshare ()
83{
84 if (!shared)
85 return;
86
87 rxvt_img *img = clone ();
88
89 ::swap (pm , img->pm);
90 ::swap (shared, img->shared);
91
92 delete img;
45} 93}
46 94
47void 95void
48rxvt_img::fill (const rxvt_color &c) 96rxvt_img::fill (const rxvt_color &c)
49{ 97{
73 121
74 for (int i = 0; i < width; i++) 122 for (int i = 0; i < width; i++)
75 params[i+2] = XDoubleToFixed (kernel[i] / sum); 123 params[i+2] = XDoubleToFixed (kernel[i] / sum);
76} 124}
77 125
78void 126rxvt_img *
79rxvt_img::blur (int rh, int rv) 127rxvt_img::blur (int rh, int rv)
80{ 128{
81 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 129 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
82 return; 130 return clone ();
83 131
84 Display *dpy = s->display->dpy; 132 Display *dpy = s->display->dpy;
85 int size = max (rh, rv) * 2 + 1; 133 int size = max (rh, rv) * 2 + 1;
86 double *kernel = (double *)malloc (size * sizeof (double)); 134 double *kernel = (double *)malloc (size * sizeof (double));
87 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 135 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
136 rxvt_img *img = new rxvt_img (s, format, w, h);
88 137
89 XRenderPictureAttributes pa; 138 XRenderPictureAttributes pa;
90 139
91 pa.repeat = RepeatPad; 140 pa.repeat = RepeatPad;
92 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 141 Picture src = XRenderCreatePicture (dpy, pm , format, CPRepeat, &pa);
142 Picture dst = XRenderCreatePicture (dpy, img->pm, format, CPRepeat, &pa);
143
93 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 144 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
94 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 145 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
95 XFreePixmap (dpy, tmp); 146 XFreePixmap (dpy, tmp_pm);
96 147
97 if (kernel && params) 148 if (kernel && params)
98 { 149 {
99 size = rh * 2 + 1; 150 size = rh * 2 + 1;
100 get_gaussian_kernel (rh, size, kernel, params); 151 get_gaussian_kernel (rh, size, kernel, params);
102 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 153 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
103 XRenderComposite (dpy, 154 XRenderComposite (dpy,
104 PictOpSrc, 155 PictOpSrc,
105 src, 156 src,
106 None, 157 None,
107 dst, 158 tmp,
108 0, 0, 159 0, 0,
109 0, 0, 160 0, 0,
110 0, 0, 161 0, 0,
111 w, h); 162 w, h);
112
113 ::swap (src, dst);
114 163
115 size = rv * 2 + 1; 164 size = rv * 2 + 1;
116 get_gaussian_kernel (rv, size, kernel, params); 165 get_gaussian_kernel (rv, size, kernel, params);
117 ::swap (params[0], params[1]); 166 ::swap (params[0], params[1]);
118 167
119 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 168 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
120 XRenderComposite (dpy, 169 XRenderComposite (dpy,
121 PictOpSrc, 170 PictOpSrc,
122 src, 171 tmp,
123 None, 172 None,
124 dst, 173 dst,
125 0, 0, 174 0, 0,
126 0, 0, 175 0, 0,
127 0, 0, 176 0, 0,
130 179
131 free (kernel); 180 free (kernel);
132 free (params); 181 free (params);
133 XRenderFreePicture (dpy, src); 182 XRenderFreePicture (dpy, src);
134 XRenderFreePicture (dpy, dst); 183 XRenderFreePicture (dpy, dst);
184 XRenderFreePicture (dpy, tmp);
185
186 return img;
135} 187}
136 188
137static Picture 189static Picture
138create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 190create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
139{ 191{
162 mask_c.blue = float_to_component (b); 214 mask_c.blue = float_to_component (b);
163 mask_c.alpha = float_to_component (a); 215 mask_c.alpha = float_to_component (a);
164 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 216 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
165 217
166 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 218 XRenderComposite (dpy, PictOpAdd, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
219
220 XRenderFreePicture (dpy, src);
221 XRenderFreePicture (dpy, dst);
167} 222}
168 223
169void 224void
170rxvt_img::contrast (double r, double g, double b, double a) 225rxvt_img::contrast (double r, double g, double b, double a)
171{ 226{
182 mask_c.blue = float_to_component (b); 237 mask_c.blue = float_to_component (b);
183 mask_c.alpha = float_to_component (a); 238 mask_c.alpha = float_to_component (a);
184 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 239 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
185 240
186 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 241 XRenderComposite (dpy, PictOpMultiply, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
187}
188 242
189void 243 XRenderFreePicture (dpy, src);
244 XRenderFreePicture (dpy, dst);
245}
246
247bool
190rxvt_img::render (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y) 248rxvt_img::render_pixbuf (GdkPixbuf *pixbuf, int src_x, int src_y, int width, int height, int dst_x, int dst_y)
191{ 249{
192 //TODO 250 Display *dpy = s->display->dpy;
193}
194 251
252 if (s->visual->c_class != TrueColor)
253 return false;
254
255 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
256
257 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
258 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
259 blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue;
260 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
261
262 int width_r = ecb_popcount32 (red_mask);
263 int width_g = ecb_popcount32 (green_mask);
264 int width_b = ecb_popcount32 (blue_mask);
265 int width_a = ecb_popcount32 (alpha_mask);
266
267 if (width_r > 8 || width_g > 8 || width_b > 8 || width_a > 8)
268 return false;
269
270 int sh_r = ecb_ctz32 (red_mask);
271 int sh_g = ecb_ctz32 (green_mask);
272 int sh_b = ecb_ctz32 (blue_mask);
273 int sh_a = ecb_ctz32 (alpha_mask);
274
275 if (width > 32767 || height > 32767)
276 return false;
277
278 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
279 width, height, 32, 0);
280 if (!ximage)
281 return false;
282
283 if (height > INT_MAX / ximage->bytes_per_line
284 || !(ximage->data = (char *)malloc (height * ximage->bytes_per_line)))
285 {
286 XDestroyImage (ximage);
287 return false;
288 }
289
290 GC gc = XCreateGC (dpy, pm, 0, 0);
291
292 ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
293
294 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
295 int channels = gdk_pixbuf_get_n_channels (pixbuf);
296 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
297 char *line = ximage->data;
298
299 for (int y = 0; y < height; y++)
300 {
301 for (int x = 0; x < width; x++)
302 {
303 unsigned char *pixel = row + x * channels;
304 uint32_t value;
305 unsigned char r, g, b, a;
306
307 if (channels == 4)
308 {
309 a = pixel[3];
310 r = pixel[0] * a / 0xff;
311 g = pixel[1] * a / 0xff;
312 b = pixel[2] * a / 0xff;
313 }
314 else
315 {
316 a = 0xff;
317 r = pixel[0];
318 g = pixel[1];
319 b = pixel[2];
320 }
321
322 value = ((r >> (8 - width_r)) << sh_r)
323 | ((g >> (8 - width_g)) << sh_g)
324 | ((b >> (8 - width_b)) << sh_b)
325 | ((a >> (8 - width_a)) << sh_a);
326
327 if (ximage->bits_per_pixel == 32)
328 ((uint32_t *)line)[x] = value;
329 else
330 XPutPixel (ximage, x, y, value);
331 }
332
333 row += rowstride;
334 line += ximage->bytes_per_line;
335 }
336
337 XPutImage (dpy, pm, gc, ximage, 0, 0, dst_x, dst_y, width, height);
338 XDestroyImage (ximage);
339 XFreeGC (dpy, gc);
340
341 return true;
342}
343
195rxvt_img * 344rxvt_img *
196rxvt_img::copy () 345rxvt_img::clone ()
197{ 346{
347 rxvt_img *img = new rxvt_img (s, format, w, h);
348
198 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 349 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); 350 XCopyArea (s->display->dpy, pm, img->pm, gc, 0, 0, w, h, 0, 0);
201 XFreeGC (s->display->dpy, gc); 351 XFreeGC (s->display->dpy, gc);
202 return new rxvt_img (s, format, w, h, pm2);
203}
204 352
353 return img;
354}
355
205rxvt_img * 356rxvt_img *
357rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
358{
359 rxvt_img *img = new rxvt_img (s, format, width, height);
360
361 Display *dpy = s->display->dpy;
362 XRenderPictureAttributes pa;
363 pa.repeat = repeat;
364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
366
367 XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, width, height);
368
369 XRenderFreePicture (dpy, src);
370 XRenderFreePicture (dpy, dst);
371
372 return img;
373}
374
375rxvt_img *
206rxvt_img::transform (int new_width, int new_height, double matrix[16]) 376rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat)
207{ 377{
208 //TODO 378 rxvt_img *img = new rxvt_img (s, format, new_width, new_height);
379
380 Display *dpy = s->display->dpy;
381 XRenderPictureAttributes pa;
382 pa.repeat = repeat;
383 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
384 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
385
386 XTransform xfrm;
387
388 for (int i = 0; i < 3; ++i)
389 for (int j = 0; j < 3; ++j)
390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
391
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
393 XRenderSetPictureTransform (dpy, src, &xfrm);
394 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
395
396 XRenderFreePicture (dpy, src);
397 XRenderFreePicture (dpy, dst);
398
399 return img;
209} 400}
210 401
211rxvt_img * 402rxvt_img *
212rxvt_img::scale (int new_width, int new_height) 403rxvt_img::scale (int new_width, int new_height)
213{ 404{
214 // use transform 405 double matrix[9] = {
215 //TODO 406 w / (double)new_width, 0, 0,
216} 407 0, h / (double)new_height, 0,
408 0, 0, 1
409 };
217 410
411 return transform (new_width, new_height, matrix);
412}
413
218rxvt_img * 414rxvt_img *
415rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi, int repeat)
416{
417 double s = sin (phi);
418 double c = cos (phi);
419
420 double matrix[9] = {
421 c, -s, -c * x + s * y + x,
422 s, c, -s * x - c * y + y,
423 0, 0, 1
424 };
425
426 return transform (new_width, new_height, matrix, repeat);
427}
428
429rxvt_img *
219rxvt_img::convert_to (XRenderPictFormat *new_format) 430rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
220{ 431{
221 rxvt_img *img = new rxvt_img (s,new_format,w, h); 432 rxvt_img *img = new rxvt_img (s, new_format, w, h);
222 433
223 Display *dpy = s->display->dpy; 434 Display *dpy = s->display->dpy;
224 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
225 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); 436 Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0);
437 int op = PictOpSrc;
226 438
439 if (format->direct.alphaMask && !new_format->direct.alphaMask)
440 {
441 // does it have to be that complicated
442 rgba c;
443 bg.get (c);
444
445 XRenderColor rc = { c.r, c.g, c.b, 0xffff };
446 XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);
447
448 op = PictOpOver;
449 }
450
227 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, w, h); 451 XRenderComposite (dpy, op, src, None, dst, 0, 0, 0, 0, 0, 0, w, h);
228 452
229 XRenderFreePicture (dpy, src);
230 XRenderFreePicture (dpy, dst); 453 XRenderFreePicture (dpy, src);
454 XRenderFreePicture (dpy, dst);
231 455
456 return img;
457}
458
459rxvt_img *
460rxvt_img::blend (rxvt_img *img, double factor)
461{
462 rxvt_img *img2 = clone ();
463 Display *dpy = s->display->dpy;
464 Picture src = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
465 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
466 Picture mask = create_xrender_mask (dpy, img->pm, False);
467
468 XRenderColor mask_c;
469
470 mask_c.alpha = float_to_component (factor);
471 mask_c.red =
472 mask_c.green =
473 mask_c.blue = 0;
474 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
475
476 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
477
478 XRenderFreePicture (dpy, src);
479 XRenderFreePicture (dpy, dst);
480 XRenderFreePicture (dpy, mask);
481
232 return img; 482 return img2;
233} 483}
234 484
235#endif 485#endif
236 486

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines