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.14 by root, Mon Jun 4 15:53:12 2012 UTC vs.
Revision 1.26 by sf-exg, Wed Jun 6 18:13:03 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{
33 gdk_pixbuf_get_height (pb) 65 gdk_pixbuf_get_height (pb)
34 ); 66 );
35 67
36 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0); 68 img->render_pixbuf (pb, 0, 0, img->w, img->h, 0, 0);
37 69
70 g_object_unref (pb);
71
38 return img; 72 return img;
39} 73}
40 74
41rxvt_img::~rxvt_img () 75rxvt_img::~rxvt_img ()
42{ 76{
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);
242
243 XRenderFreePicture (dpy, src);
244 XRenderFreePicture (dpy, dst);
201} 245}
202 246
203bool 247bool
204rxvt_img::render_pixbuf (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 bool argb = format->id == PictStandardARGB32;
207
208 Display *dpy = s->display->dpy; 250 Display *dpy = s->display->dpy;
209 251
210 if (s->visual->c_class != TrueColor) 252 if (s->visual->c_class != TrueColor)
211 return false; 253 return false;
212 254
213 uint32_t red_mask, green_mask, blue_mask, alpha_mask; 255 uint32_t red_mask, green_mask, blue_mask, alpha_mask;
214 256
215 if (argb) 257 red_mask = (uint32_t)format->direct.redMask << format->direct.red;
216 { 258 green_mask = (uint32_t)format->direct.greenMask << format->direct.green;
217 red_mask = 0xff << 16; 259 blue_mask = (uint32_t)format->direct.blueMask << format->direct.blue;
218 green_mask = 0xff << 8;
219 blue_mask = 0xff;
220 alpha_mask = 0xff << 24;
221 }
222 else
223 {
224 red_mask = s->visual->red_mask;
225 green_mask = s->visual->green_mask;
226 blue_mask = s->visual->blue_mask;
227 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha; 260 alpha_mask = (uint32_t)format->direct.alphaMask << format->direct.alpha;
228 }
229 261
230 int width_r = ecb_popcount32 (red_mask); 262 int width_r = ecb_popcount32 (red_mask);
231 int width_g = ecb_popcount32 (green_mask); 263 int width_g = ecb_popcount32 (green_mask);
232 int width_b = ecb_popcount32 (blue_mask); 264 int width_b = ecb_popcount32 (blue_mask);
233 int width_a = ecb_popcount32 (alpha_mask); 265 int width_a = ecb_popcount32 (alpha_mask);
241 int sh_a = ecb_ctz32 (alpha_mask); 273 int sh_a = ecb_ctz32 (alpha_mask);
242 274
243 if (width > 32767 || height > 32767) 275 if (width > 32767 || height > 32767)
244 return false; 276 return false;
245 277
246 XImage *ximage = XCreateImage (dpy, s->visual, argb ? 32 : format->depth, ZPixmap, 0, 0, 278 XImage *ximage = XCreateImage (dpy, s->visual, format->depth, ZPixmap, 0, 0,
247 width, height, 32, 0); 279 width, height, 32, 0);
248 if (!ximage) 280 if (!ximage)
249 return false; 281 return false;
250 282
251 if (height > INT_MAX / ximage->bytes_per_line 283 if (height > INT_MAX / ximage->bytes_per_line
261 293
262 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 294 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
263 int channels = gdk_pixbuf_get_n_channels (pixbuf); 295 int channels = gdk_pixbuf_get_n_channels (pixbuf);
264 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels; 296 unsigned char *row = gdk_pixbuf_get_pixels (pixbuf) + src_y * rowstride + src_x * channels;
265 char *line = ximage->data; 297 char *line = ximage->data;
266
267 rgba c (0, 0, 0);
268
269 if (channels == 4 && alpha_mask == 0)
270 {
271 //pix_colors[Color_bg].get (c);
272 //TODO
273 c.r >>= 8;
274 c.g >>= 8;
275 c.b >>= 8;
276 }
277 298
278 for (int y = 0; y < height; y++) 299 for (int y = 0; y < height; y++)
279 { 300 {
280 for (int x = 0; x < width; x++) 301 for (int x = 0; x < width; x++)
281 { 302 {
284 unsigned char r, g, b, a; 305 unsigned char r, g, b, a;
285 306
286 if (channels == 4) 307 if (channels == 4)
287 { 308 {
288 a = pixel[3]; 309 a = pixel[3];
289 r = (pixel[0] * a + c.r * (0xff - a)) / 0xff; 310 r = pixel[0] * a / 0xff;
290 g = (pixel[1] * a + c.g * (0xff - a)) / 0xff; 311 g = pixel[1] * a / 0xff;
291 b = (pixel[2] * a + c.b * (0xff - a)) / 0xff; 312 b = pixel[2] * a / 0xff;
292 } 313 }
293 else 314 else
294 { 315 {
295 a = 0xff; 316 a = 0xff;
296 r = pixel[0]; 317 r = pixel[0];
321} 342}
322 343
323rxvt_img * 344rxvt_img *
324rxvt_img::clone () 345rxvt_img::clone ()
325{ 346{
347 rxvt_img *img = new rxvt_img (s, format, w, h);
348
326 GC gc = XCreateGC (s->display->dpy, pm, 0, 0); 349 GC gc = XCreateGC (s->display->dpy, pm, 0, 0);
327 Pixmap pm2 = XCreatePixmap (s->display->dpy, pm, w, h, format->depth);
328 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);
329 XFreeGC (s->display->dpy, gc); 351 XFreeGC (s->display->dpy, gc);
330 return new rxvt_img (s, format, w, h, pm2);
331}
332 352
353 return img;
354}
355
333rxvt_img * 356rxvt_img *
334rxvt_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)
335{ 358{
336 rxvt_img *img = new rxvt_img (s, format, new_width, new_height); 359 rxvt_img *img = new rxvt_img (s, format, width, height);
337 360
338 Display *dpy = s->display->dpy; 361 Display *dpy = s->display->dpy;
339 XRenderPictureAttributes pa; 362 XRenderPictureAttributes pa;
340 pa.repeat = repeat; 363 pa.repeat = repeat;
341 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 364 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
342 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); 365 Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
343 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
344 XTransform xfrm; 386 XTransform xfrm;
345 387
346 for (int i = 0; i < 3; ++i) 388 for (int i = 0; i < 3; ++i)
347 for (int j = 0; j < 3; ++j) 389 for (int j = 0; j < 3; ++j)
348 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); 390 xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]);
349 391
392 XRenderSetPictureFilter (dpy, src, "good", 0, 0);
350 XRenderSetPictureTransform (dpy, src, &xfrm); 393 XRenderSetPictureTransform (dpy, src, &xfrm);
351 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);
352 395
353 XRenderFreePicture (dpy, src); 396 XRenderFreePicture (dpy, src);
354 XRenderFreePicture (dpy, dst); 397 XRenderFreePicture (dpy, dst);
358 401
359rxvt_img * 402rxvt_img *
360rxvt_img::scale (int new_width, int new_height) 403rxvt_img::scale (int new_width, int new_height)
361{ 404{
362 double matrix[9] = { 405 double matrix[9] = {
363 new_width / (double)w, 0, 0, 406 w / (double)new_width, 0, 0,
364 0, new_height / (double)h, 0, 407 0, h / (double)new_height, 0,
365 0, 0, 1 408 0, 0, 1
366 }; 409 };
367 410
368 return transform (new_width, new_height, RepeatNormal, matrix); 411 return transform (new_width, new_height, matrix);
412}
413
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);
369} 427}
370 428
371rxvt_img * 429rxvt_img *
372rxvt_img::convert_to (XRenderPictFormat *new_format) 430rxvt_img::convert_to (XRenderPictFormat *new_format)
373{ 431{
383 XRenderFreePicture (dpy, dst); 441 XRenderFreePicture (dpy, dst);
384 442
385 return img; 443 return img;
386} 444}
387 445
446rxvt_img *
447rxvt_img::blend (rxvt_img *img, double factor)
448{
449 rxvt_img *img2 = clone ();
450 Display *dpy = s->display->dpy;
451 Picture src = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0);
452 Picture dst = XRenderCreatePicture (dpy, img2->pm, img2->format, 0, 0);
453 Picture mask = create_xrender_mask (dpy, img->pm, False);
454
455 XRenderColor mask_c;
456
457 mask_c.alpha = float_to_component (factor);
458 mask_c.red =
459 mask_c.green =
460 mask_c.blue = 0;
461 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
462
463 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, w, h);
464
465 XRenderFreePicture (dpy, src);
466 XRenderFreePicture (dpy, dst);
467 XRenderFreePicture (dpy, mask);
468
469 return img2;
470}
471
388#endif 472#endif
389 473

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines