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.13 by root, Mon Jun 4 15:30:41 2012 UTC vs.
Revision 1.29 by root, Wed Jun 6 20:55:36 2012 UTC

13} 13}
14 14
15rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap) 15rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int width, int height, Pixmap pixmap)
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}
19
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;
18} 50}
19 51
20rxvt_img * 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{
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 ()
87 121
88 for (int i = 0; i < width; i++) 122 for (int i = 0; i < width; i++)
89 params[i+2] = XDoubleToFixed (kernel[i] / sum); 123 params[i+2] = XDoubleToFixed (kernel[i] / sum);
90} 124}
91 125
92void 126rxvt_img *
93rxvt_img::blur (int rh, int rv) 127rxvt_img::blur (int rh, int rv)
94{ 128{
95 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 129 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV))
96 return; 130 return clone ();
97 131
98 Display *dpy = s->display->dpy; 132 Display *dpy = s->display->dpy;
99 int size = max (rh, rv) * 2 + 1; 133 int size = max (rh, rv) * 2 + 1;
100 double *kernel = (double *)malloc (size * sizeof (double)); 134 double *kernel = (double *)malloc (size * sizeof (double));
101 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);
102 137
103 XRenderPictureAttributes pa; 138 XRenderPictureAttributes pa;
104 139
105 pa.repeat = RepeatPad; 140 pa.repeat = RepeatPad;
106 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
107 Pixmap tmp = XCreatePixmap (dpy, pm, w, h, format->depth); 144 Pixmap tmp_pm = XCreatePixmap (dpy, pm, w, h, format->depth);
108 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); 145 Picture tmp = XRenderCreatePicture (dpy, tmp_pm , format, CPRepeat, &pa);
109 XFreePixmap (dpy, tmp); 146 XFreePixmap (dpy, tmp_pm);
110 147
111 if (kernel && params) 148 if (kernel && params)
112 { 149 {
113 size = rh * 2 + 1; 150 size = rh * 2 + 1;
114 get_gaussian_kernel (rh, size, kernel, params); 151 get_gaussian_kernel (rh, size, kernel, params);
116 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 153 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
117 XRenderComposite (dpy, 154 XRenderComposite (dpy,
118 PictOpSrc, 155 PictOpSrc,
119 src, 156 src,
120 None, 157 None,
121 dst, 158 tmp,
122 0, 0, 159 0, 0,
123 0, 0, 160 0, 0,
124 0, 0, 161 0, 0,
125 w, h); 162 w, h);
126
127 ::swap (src, dst);
128 163
129 size = rv * 2 + 1; 164 size = rv * 2 + 1;
130 get_gaussian_kernel (rv, size, kernel, params); 165 get_gaussian_kernel (rv, size, kernel, params);
131 ::swap (params[0], params[1]); 166 ::swap (params[0], params[1]);
132 167
133 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 168 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
134 XRenderComposite (dpy, 169 XRenderComposite (dpy,
135 PictOpSrc, 170 PictOpSrc,
136 src, 171 tmp,
137 None, 172 None,
138 dst, 173 dst,
139 0, 0, 174 0, 0,
140 0, 0, 175 0, 0,
141 0, 0, 176 0, 0,
144 179
145 free (kernel); 180 free (kernel);
146 free (params); 181 free (params);
147 XRenderFreePicture (dpy, src); 182 XRenderFreePicture (dpy, src);
148 XRenderFreePicture (dpy, dst); 183 XRenderFreePicture (dpy, dst);
184 XRenderFreePicture (dpy, tmp);
185
186 return img;
149} 187}
150 188
151static Picture 189static Picture
152create_xrender_mask (Display *dpy, Drawable drawable, Bool argb) 190create_xrender_mask (Display *dpy, Drawable drawable, Bool argb)
153{ 191{
176 mask_c.blue = float_to_component (b); 214 mask_c.blue = float_to_component (b);
177 mask_c.alpha = float_to_component (a); 215 mask_c.alpha = float_to_component (a);
178 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 216 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
179 217
180 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);
181} 222}
182 223
183void 224void
184rxvt_img::contrast (double r, double g, double b, double a) 225rxvt_img::contrast (double r, double g, double b, double a)
185{ 226{
196 mask_c.blue = float_to_component (b); 237 mask_c.blue = float_to_component (b);
197 mask_c.alpha = float_to_component (a); 238 mask_c.alpha = float_to_component (a);
198 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1); 239 XRenderFillRectangle (dpy, PictOpSrc, src, &mask_c, 0, 0, 1, 1);
199 240
200 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);
201}
202 242
203void 243 XRenderFreePicture (dpy, src);
244 XRenderFreePicture (dpy, dst);
245}
246
247bool
204rxvt_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)
205{ 249{
206 //TODO 250 Display *dpy = s->display->dpy;
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;
207} 342}
208 343
209rxvt_img * 344rxvt_img *
210rxvt_img::clone () 345rxvt_img::clone ()
211{ 346{
347 rxvt_img *img = new rxvt_img (s, format, w, h);
348
212 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
213 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
214 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);
215 XFreeGC (s->display->dpy, gc); 351 XFreeGC (s->display->dpy, gc);
216 return new rxvt_img (s, format, w, h, pm2);
217}
218 352
353 return img;
354}
355
219rxvt_img * 356rxvt_img *
220rxvt_img::transform (int new_width, int new_height, int repeat, double matrix[9]) 357rxvt_img::sub_rect (int x, int y, int width, int height, int repeat)
221{ 358{
222 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 359 rxvt_img *img = new rxvt_img (s, format, width, height);
223 360
224 Display *dpy = s->display->dpy; 361 Display *dpy = s->display->dpy;
225 XRenderPictureAttributes pa; 362 XRenderPictureAttributes pa;
226 pa.repeat = repeat; 363 pa.repeat = repeat;
227 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
228 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
229 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 *
376rxvt_img::transform (int new_width, int new_height, double matrix[9], int repeat)
377{
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
230 XTransform xfrm; 386 XTransform xfrm;
231 387
232 for (int i = 0; i < 3; ++i) 388 for (int i = 0; i < 3; ++i)
233 for (int j = 0; j < 3; ++j) 389 for (int j = 0; j < 3; ++j)
234 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
235 391
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
236 XRenderSetPictureTransform (dpy, src, &xfrm); 393 XRenderSetPictureTransform (dpy, src, &xfrm);
237 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); 394 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height);
238 395
239 XRenderFreePicture (dpy, src); 396 XRenderFreePicture (dpy, src);
240 XRenderFreePicture (dpy, dst); 397 XRenderFreePicture (dpy, dst);
244 401
245rxvt_img * 402rxvt_img *
246rxvt_img::scale (int new_width, int new_height) 403rxvt_img::scale (int new_width, int new_height)
247{ 404{
248 double matrix[9] = { 405 double matrix[9] = {
249 new_width / (double)w, 0, 0, 406 w / (double)new_width, 0, 0,
250 0, new_height / (double)h, 0, 407 0, h / (double)new_height, 0,
251 0, 0, 1 408 0, 0, 1
252 }; 409 };
253 410
254 return transform (new_width, new_height, RepeatNormal, matrix); 411 return transform (new_width, new_height, matrix);
255} 412}
256 413
257rxvt_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 *
258rxvt_img::convert_to (XRenderPictFormat *new_format) 430rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg)
259{ 431{
260 rxvt_img *img = new rxvt_img (s, new_format, w, h); 432 rxvt_img *img = new rxvt_img (s, new_format, w, h);
261 433
262 Display *dpy = s->display->dpy; 434 Display *dpy = s->display->dpy;
263 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0); 435 Picture src = XRenderCreatePicture (dpy, pm, format, 0, 0);
264 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;
265 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
266 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);
267 452
268 XRenderFreePicture (dpy, src);
269 XRenderFreePicture (dpy, dst); 453 XRenderFreePicture (dpy, src);
454 XRenderFreePicture (dpy, dst);
270 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
271 return img; 482 return img2;
272} 483}
273 484
274#endif 485#endif
275 486

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines