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.105 by sf-exg, Sat Jan 19 10:04:34 2013 UTC vs.
Revision 1.112 by root, Tue Sep 17 18:31:32 2019 UTC

6 * Copyright (c) 2012 Marc Lehmann <schmorp@schmorp.de> 6 * Copyright (c) 2012 Marc Lehmann <schmorp@schmorp.de>
7 * Copyright (c) 2012 Emanuele Giaquinta <e.giaquinta@glauco.it> 7 * Copyright (c) 2012 Emanuele Giaquinta <e.giaquinta@glauco.it>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version. 12 * (at your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
164 if (!this->dstimg) 164 if (!this->dstimg)
165 this->dstimg = srcimg->new_empty (); 165 this->dstimg = srcimg->new_empty ();
166 else if (!this->dstimg->pm) // somewhat unsatisfying 166 else if (!this->dstimg->pm) // somewhat unsatisfying
167 this->dstimg->alloc (); 167 this->dstimg->alloc ();
168 168
169 dpy = srcimg->s->dpy; 169 dpy = srcimg->d->dpy;
170 src = srcimg->picture (); 170 src = srcimg->picture ();
171 dst = this->dstimg->picture (); 171 dst = this->dstimg->picture ();
172 } 172 }
173 173
174 ecb_noinline 174 ecb_noinline
188 } 188 }
189 189
190 // CreateSolidFill creates a very very very weird picture 190 // CreateSolidFill creates a very very very weird picture
191 void mask (const rgba &c) 191 void mask (const rgba &c)
192 { 192 {
193 // the casts are needed in C++11 (see 8.5.1)
193 XRenderColor rc = { 194 XRenderColor rc = {
194 c.r * c.a / 65535, 195 (unsigned short)(c.r * c.a / 65535),
195 c.g * c.a / 65535, 196 (unsigned short)(c.g * c.a / 65535),
196 c.b * c.a / 65535, 197 (unsigned short)(c.b * c.a / 65535),
197 c.a 198 c.a
198 }; 199 };
199 msk = XRenderCreateSolidFill (dpy, &rc); 200 msk = XRenderCreateSolidFill (dpy, &rc);
200 ecb_assume (msk); 201 ecb_assume (msk);
201 } 202 }
202 203
203 void fill (const rgba &c) 204 void fill (const rgba &c)
204 { 205 {
205 XRenderColor rc = { 206 XRenderColor rc = {
206 c.r * c.a / 65535, 207 (unsigned short)(c.r * c.a / 65535),
207 c.g * c.a / 65535, 208 (unsigned short)(c.g * c.a / 65535),
208 c.b * c.a / 65535, 209 (unsigned short)(c.b * c.a / 65535),
209 c.a 210 c.a
210 }; 211 };
211 212
212 XRenderFillRectangle (dpy, PictOpSrc, msk, &rc, 0, 0, 1, 1); 213 XRenderFillRectangle (dpy, PictOpSrc, msk, &rc, 0, 0, 1, 1);
213 } 214 }
214 215
246 // should be a very good fallback 247 // should be a very good fallback
247 return XRenderFindStandardFormat (dpy, PictStandardARGB32); 248 return XRenderFindStandardFormat (dpy, PictStandardARGB32);
248} 249}
249 250
250rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int x, int y, int width, int height, int repeat) 251rxvt_img::rxvt_img (rxvt_screen *screen, XRenderPictFormat *format, int x, int y, int width, int height, int repeat)
251: s(screen), x(x), y(y), w(width), h(height), format(format), repeat(repeat), 252: d(screen->display), x(x), y(y), w(width), h(height), format(format), repeat(repeat),
252 pm(0), ref(0) 253 pm(0), ref(0)
253{ 254{
254} 255}
255 256
257rxvt_img::rxvt_img (rxvt_display *display, XRenderPictFormat *format, int x, int y, int width, int height, int repeat)
258: d(display), x(x), y(y), w(width), h(height), format(format), repeat(repeat),
259 pm(0), ref(0)
260{
261}
262
256rxvt_img::rxvt_img (const rxvt_img &img) 263rxvt_img::rxvt_img (const rxvt_img &img)
257: s(img.s), x(img.x), y(img.y), w(img.w), h(img.h), format(img.format), repeat(img.repeat), pm(img.pm), ref(img.ref) 264: d(img.d), x(img.x), y(img.y), w(img.w), h(img.h), format(img.format), repeat(img.repeat), pm(img.pm), ref(img.ref)
258{ 265{
259 ++ref->cnt; 266 ++ref->cnt;
260} 267}
261 268
262rxvt_img * 269rxvt_img *
395{ 402{
396 GError *err = 0; 403 GError *err = 0;
397 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err); 404 GdkPixbuf *pb = gdk_pixbuf_new_from_file (filename, &err);
398 405
399 if (!pb) 406 if (!pb)
407 try
408 {
400 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message); 409 rxvt_fatal ("rxvt_img::new_from_file: %s\n", err->message);
410 }
411 catch (...)
412 {
413 g_error_free (err);
414 throw;
415 }
401 416
402 rxvt_img *img = new_from_pixbuf (s, pb); 417 rxvt_img *img = new_from_pixbuf (s, pb);
403 418
404 g_object_unref (pb); 419 g_object_unref (pb);
405 420
413{ 428{
414 if (--ref->cnt) 429 if (--ref->cnt)
415 return; 430 return;
416 431
417 if (pm && ref->ours) 432 if (pm && ref->ours)
418 XFreePixmap (s->dpy, pm); 433 XFreePixmap (d->dpy, pm);
419 434
420 delete ref; 435 delete ref;
421} 436}
422 437
423rxvt_img::~rxvt_img () 438rxvt_img::~rxvt_img ()
426} 441}
427 442
428void 443void
429rxvt_img::alloc () 444rxvt_img::alloc ()
430{ 445{
431 pm = XCreatePixmap (s->dpy, s->display->root, w, h, format->depth); 446 pm = XCreatePixmap (d->dpy, d->root, w, h, format->depth);
432 ref = new pixref (w, h); 447 ref = new pixref (w, h);
433} 448}
434 449
435rxvt_img * 450rxvt_img *
436rxvt_img::new_empty () 451rxvt_img::new_empty ()
437{ 452{
438 rxvt_img *img = new rxvt_img (s, format, x, y, w, h, repeat); 453 rxvt_img *img = new rxvt_img (d, format, x, y, w, h, repeat);
439 img->alloc (); 454 img->alloc ();
440 455
441 return img; 456 return img;
442} 457}
443 458
444Picture 459Picture
445rxvt_img::picture () 460rxvt_img::picture ()
446{ 461{
447 Display *dpy = s->dpy; 462 Display *dpy = d->dpy;
448 463
449 XRenderPictureAttributes pa; 464 XRenderPictureAttributes pa;
450 pa.repeat = repeat; 465 pa.repeat = repeat;
451 Picture pic = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 466 Picture pic = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
452 467
457rxvt_img::unshare () 472rxvt_img::unshare ()
458{ 473{
459 if (ref->cnt == 1 && ref->ours) 474 if (ref->cnt == 1 && ref->ours)
460 return; 475 return;
461 476
462 Pixmap pm2 = XCreatePixmap (s->dpy, s->display->root, ref->w, ref->h, format->depth); 477 Pixmap pm2 = XCreatePixmap (d->dpy, d->root, ref->w, ref->h, format->depth);
463 GC gc = XCreateGC (s->dpy, pm, 0, 0); 478 GC gc = XCreateGC (d->dpy, pm, 0, 0);
464 XCopyArea (s->dpy, pm, pm2, gc, 0, 0, ref->w, ref->h, 0, 0); 479 XCopyArea (d->dpy, pm, pm2, gc, 0, 0, ref->w, ref->h, 0, 0);
465 XFreeGC (s->dpy, gc); 480 XFreeGC (d->dpy, gc);
466 481
467 destroy (); 482 destroy ();
468 483
469 pm = pm2; 484 pm = pm2;
470 ref = new pixref (ref->w, ref->h); 485 ref = new pixref (ref->w, ref->h);
473void 488void
474rxvt_img::fill (const rgba &c, int x, int y, int w, int h) 489rxvt_img::fill (const rgba &c, int x, int y, int w, int h)
475{ 490{
476 XRenderColor rc = { c.r, c.g, c.b, c.a }; 491 XRenderColor rc = { c.r, c.g, c.b, c.a };
477 492
478 Display *dpy = s->dpy; 493 Display *dpy = d->dpy;
479 Picture src = picture (); 494 Picture src = picture ();
480 XRenderFillRectangle (dpy, PictOpSrc, src, &rc, x, y, w, h); 495 XRenderFillRectangle (dpy, PictOpSrc, src, &rc, x, y, w, h);
481 XRenderFreePicture (dpy, src); 496 XRenderFreePicture (dpy, src);
482} 497}
483 498
491rxvt_img::add_alpha () 506rxvt_img::add_alpha ()
492{ 507{
493 if (format->direct.alphaMask) 508 if (format->direct.alphaMask)
494 return; 509 return;
495 510
496 composer cc (this, new rxvt_img (s, find_alpha_format_for (s->dpy, format), x, y, w, h, repeat)); 511 composer cc (this, new rxvt_img (d, find_alpha_format_for (d->dpy, format), x, y, w, h, repeat));
497 512
498 XRenderComposite (cc.dpy, PictOpSrc, cc.src, None, cc.dst, 0, 0, 0, 0, 0, 0, w, h); 513 XRenderComposite (cc.dpy, PictOpSrc, cc.src, None, cc.dst, 0, 0, 0, 0, 0, 0, w, h);
499 514
500 rxvt_img *img = cc; 515 rxvt_img *img = cc;
501 516
527} 542}
528 543
529rxvt_img * 544rxvt_img *
530rxvt_img::blur (int rh, int rv) 545rxvt_img::blur (int rh, int rv)
531{ 546{
532 if (!(s->display->flags & DISPLAY_HAS_RENDER_CONV)) 547 if (!(d->flags & DISPLAY_HAS_RENDER_CONV))
533 return clone (); 548 return clone ();
534 549
535 Display *dpy = s->dpy; 550 Display *dpy = d->dpy;
536 int size = max (rh, rv) * 2 + 1; 551 int size = max (rh, rv) * 2 + 1;
537 nv *kernel = (nv *)malloc (size * sizeof (nv)); 552 nv *kernel = (nv *)malloc (size * sizeof (nv));
538 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 553 XFixed *params = rxvt_temp_buf<XFixed> (size + 2);
539 rxvt_img *img = new_empty (); 554 rxvt_img *img = new_empty ();
540 555
541 XRenderPictureAttributes pa; 556 XRenderPictureAttributes pa;
542 pa.repeat = RepeatPad; 557 pa.repeat = RepeatPad;
543 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa); 558 Picture src = XRenderCreatePicture (dpy, pm, format, CPRepeat, &pa);
578 0, 0, 593 0, 0,
579 w, h); 594 w, h);
580 } 595 }
581 596
582 free (kernel); 597 free (kernel);
583 free (params);
584 598
585 XRenderFreePicture (dpy, src); 599 XRenderFreePicture (dpy, src);
586 XRenderFreePicture (dpy, dst); 600 XRenderFreePicture (dpy, dst);
587 XRenderFreePicture (dpy, tmp); 601 XRenderFreePicture (dpy, tmp);
588 602
592rxvt_img * 606rxvt_img *
593rxvt_img::muladd (nv mul, nv add) 607rxvt_img::muladd (nv mul, nv add)
594{ 608{
595 // STEP 1: double the image width, fill all odd columns with white (==1) 609 // STEP 1: double the image width, fill all odd columns with white (==1)
596 610
597 composer cc (this, new rxvt_img (s, format, 0, 0, w * 2, h, repeat)); 611 composer cc (this, new rxvt_img (d, format, 0, 0, w * 2, h, repeat));
598 612
599 // why the hell does XRenderSetPictureTransform want a writable matrix :( 613 // why the hell does XRenderSetPictureTransform want a writable matrix :(
600 // that keeps us from just static const'ing this matrix. 614 // that keeps us from just static const'ing this matrix.
601 XTransform h_double = { 615 XTransform h_double = {
602 0x08000, 0, 0, 616 0x08000, 0, 0,
669void 683void
670rxvt_img::brightness (int32_t r, int32_t g, int32_t b, int32_t a) 684rxvt_img::brightness (int32_t r, int32_t g, int32_t b, int32_t a)
671{ 685{
672 unshare (); 686 unshare ();
673 687
674 Display *dpy = s->dpy; 688 Display *dpy = d->dpy;
675 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0); 689 Picture dst = XRenderCreatePicture (dpy, pm, format, 0, 0);
676 690
677 // loop should not be needed for brightness, as only -1..1 makes sense 691 // loop should not be needed for brightness, as only -1..1 makes sense
678 //while (r | g | b | a) 692 //while (r | g | b | a)
679 { 693 {
763 // add an alpha channel if... 777 // add an alpha channel if...
764 bool alpha = !format->direct.alphaMask // pixmap has none yet 778 bool alpha = !format->direct.alphaMask // pixmap has none yet
765 && (x || y) // we need one because of non-zero offset 779 && (x || y) // we need one because of non-zero offset
766 && repeat == RepeatNone; // and we have no good pixels to fill with 780 && repeat == RepeatNone; // and we have no good pixels to fill with
767 781
768 composer cc (this, new rxvt_img (s, alpha ? find_alpha_format_for (s->dpy, format) : format, 782 composer cc (this, new rxvt_img (d, alpha ? find_alpha_format_for (d->dpy, format) : format,
769 0, 0, w, h, repeat)); 783 0, 0, w, h, repeat));
770 784
771 if (repeat == RepeatNone) 785 if (repeat == RepeatNone)
772 { 786 {
773 XRenderColor rc = { 0, 0, 0, 0 }; 787 XRenderColor rc = { 0, 0, 0, 0 };
835 int new_width = ceil (rmax [0] - rmin [0]); 849 int new_width = ceil (rmax [0] - rmin [0]);
836 int new_height = ceil (rmax [1] - rmin [1]); 850 int new_height = ceil (rmax [1] - rmin [1]);
837 851
838 mat3x3 inv = (mat3x3::translate (-x, -y) * m * mat3x3::translate (x, y)).inverse (); 852 mat3x3 inv = (mat3x3::translate (-x, -y) * m * mat3x3::translate (x, y)).inverse ();
839 853
840 composer cc (this, new rxvt_img (s, format, nx, ny, new_width, new_height, repeat)); 854 composer cc (this, new rxvt_img (d, format, nx, ny, new_width, new_height, repeat));
841 855
842 XTransform xfrm; 856 XTransform xfrm;
843 857
844 for (int i = 0; i < 3; ++i) 858 for (int i = 0; i < 3; ++i)
845 for (int j = 0; j < 3; ++j) 859 for (int j = 0; j < 3; ++j)
884rxvt_img::convert_format (XRenderPictFormat *new_format, const rgba &bg) 898rxvt_img::convert_format (XRenderPictFormat *new_format, const rgba &bg)
885{ 899{
886 if (new_format == format) 900 if (new_format == format)
887 return clone (); 901 return clone ();
888 902
889 composer cc (this, new rxvt_img (s, new_format, x, y, w, h, repeat)); 903 composer cc (this, new rxvt_img (d, new_format, x, y, w, h, repeat));
890 904
891 int op = PictOpSrc; 905 int op = PictOpSrc;
892 906
893 if (format->direct.alphaMask && !new_format->direct.alphaMask) 907 if (format->direct.alphaMask && !new_format->direct.alphaMask)
894 { 908 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines