… | |
… | |
391 | rxvt_img::clone () |
391 | rxvt_img::clone () |
392 | { |
392 | { |
393 | return new rxvt_img (*this); |
393 | return new rxvt_img (*this); |
394 | } |
394 | } |
395 | |
395 | |
|
|
396 | |
|
|
397 | static XRenderPictFormat * |
|
|
398 | find_alpha_format_for (Display *dpy, XRenderPictFormat *format) |
|
|
399 | { |
|
|
400 | if (format->direct.alphaMask) |
|
|
401 | return format; // already has alpha |
|
|
402 | |
|
|
403 | // try to find a suitable alpha format, one bit alpha is enough for our purposes |
|
|
404 | if (format->type == PictTypeDirect) |
|
|
405 | for (int n = 0; XRenderPictFormat *f = XRenderFindFormat (dpy, 0, 0, n); ++n) |
|
|
406 | if (f->direct.alphaMask |
|
|
407 | && f->type == PictTypeDirect |
|
|
408 | && ecb_popcount32 (f->direct.redMask ) >= ecb_popcount32 (format->direct.redMask ) |
|
|
409 | && ecb_popcount32 (f->direct.greenMask) >= ecb_popcount32 (format->direct.greenMask) |
|
|
410 | && ecb_popcount32 (f->direct.blueMask ) >= ecb_popcount32 (format->direct.blueMask )) |
|
|
411 | return f; |
|
|
412 | |
|
|
413 | // should be a very good fallback |
|
|
414 | return XRenderFindStandardFormat (dpy, PictStandardARGB32); |
|
|
415 | } |
|
|
416 | |
396 | rxvt_img * |
417 | rxvt_img * |
397 | rxvt_img::reify () |
418 | rxvt_img::reify () |
398 | { |
419 | { |
399 | if (x == 0 && y == 0 && w == ref->w && h == ref->h) |
420 | if (x == 0 && y == 0 && w == ref->w && h == ref->h) |
400 | return clone (); |
421 | return clone (); |
… | |
… | |
403 | |
424 | |
404 | bool alpha = !format->direct.alphaMask |
425 | bool alpha = !format->direct.alphaMask |
405 | && (x || y) |
426 | && (x || y) |
406 | && repeat == RepeatNone; |
427 | && repeat == RepeatNone; |
407 | |
428 | |
408 | rxvt_img *img = new rxvt_img (s, alpha ? XRenderFindStandardFormat (dpy, PictStandardARGB32) : format, 0, 0, w, h, repeat); |
429 | rxvt_img *img = new rxvt_img (s, alpha ? find_alpha_format_for (dpy, format) : format, 0, 0, w, h, repeat); |
409 | img->alloc (); |
430 | img->alloc (); |
410 | |
431 | |
411 | Picture src = src_picture (); |
432 | Picture src = src_picture (); |
412 | Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); |
433 | Picture dst = XRenderCreatePicture (dpy, img->pm, img->format, 0, 0); |
413 | |
434 | |
|
|
435 | if (alpha) |
|
|
436 | { |
|
|
437 | XRenderColor rc = { 0, 0, 0, 0 }; |
|
|
438 | XRenderFillRectangle (dpy, PictOpSrc, dst, &rc, 0, 0, w, h);//TODO: split into four fillrectangles |
|
|
439 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, -x, -y, ref->w, ref->h); |
|
|
440 | } |
|
|
441 | else |
414 | XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h); |
442 | XRenderComposite (dpy, PictOpSrc, src, None, dst, x, y, 0, 0, 0, 0, w, h); |
415 | |
443 | |
416 | XRenderFreePicture (dpy, src); |
444 | XRenderFreePicture (dpy, src); |
417 | XRenderFreePicture (dpy, dst); |
445 | XRenderFreePicture (dpy, dst); |
418 | |
446 | |
419 | return img; |
447 | return img; |
420 | } |
448 | } |
… | |
… | |
454 | |
482 | |
455 | for (int i = 0; i < 3; ++i) |
483 | for (int i = 0; i < 3; ++i) |
456 | for (int j = 0; j < 3; ++j) |
484 | for (int j = 0; j < 3; ++j) |
457 | xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); |
485 | xfrm.matrix [i][j] = XDoubleToFixed (matrix [i * 3 + j]); |
458 | |
486 | |
|
|
487 | #if 0 |
459 | xfrm.matrix [0][2] += XDoubleToFixed (x);//TODO |
488 | xfrm.matrix [0][2] -= XDoubleToFixed (x);//TODO |
460 | xfrm.matrix [0][3] += XDoubleToFixed (y); |
489 | xfrm.matrix [1][2] -= XDoubleToFixed (y); |
|
|
490 | #endif |
461 | |
491 | |
462 | XRenderSetPictureFilter (dpy, src, "good", 0, 0); |
492 | XRenderSetPictureFilter (dpy, src, "good", 0, 0); |
463 | XRenderSetPictureTransform (dpy, src, &xfrm); |
493 | XRenderSetPictureTransform (dpy, src, &xfrm); |
464 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); |
494 | XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, new_width, new_height); |
465 | |
495 | |
… | |
… | |
470 | } |
500 | } |
471 | |
501 | |
472 | rxvt_img * |
502 | rxvt_img * |
473 | rxvt_img::scale (int new_width, int new_height) |
503 | rxvt_img::scale (int new_width, int new_height) |
474 | { |
504 | { |
|
|
505 | if (w == new_width && h == new_height) |
|
|
506 | return clone (); |
|
|
507 | |
475 | double matrix[9] = { |
508 | double matrix[9] = { |
476 | w / (double)new_width, 0, 0, |
509 | w / (double)new_width, 0, 0, |
477 | 0, h / (double)new_height, 0, |
510 | 0, h / (double)new_height, 0, |
478 | 0, 0, 1 |
511 | 0, 0, 1 |
479 | }; |
512 | }; |
480 | |
513 | |
|
|
514 | int old_repeat_mode = repeat; |
|
|
515 | repeat = RepeatPad; // not right, but xrender can't proeprly scale it seems |
|
|
516 | |
481 | return transform (new_width, new_height, matrix); |
517 | rxvt_img *img = transform (new_width, new_height, matrix); |
|
|
518 | |
|
|
519 | repeat = old_repeat_mode; |
|
|
520 | img->repeat = repeat; |
|
|
521 | |
|
|
522 | return img; |
482 | } |
523 | } |
483 | |
524 | |
484 | rxvt_img * |
525 | rxvt_img * |
485 | rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi) |
526 | rxvt_img::rotate (int new_width, int new_height, int x, int y, double phi) |
486 | { |
527 | { |
… | |
… | |
495 | |
536 | |
496 | return transform (new_width, new_height, matrix); |
537 | return transform (new_width, new_height, matrix); |
497 | } |
538 | } |
498 | |
539 | |
499 | rxvt_img * |
540 | rxvt_img * |
500 | rxvt_img::convert_to (XRenderPictFormat *new_format, const rxvt_color &bg) |
541 | rxvt_img::convert_format (XRenderPictFormat *new_format, const rxvt_color &bg) |
501 | { |
542 | { |
502 | if (new_format == format) |
543 | if (new_format == format) |
503 | return clone (); |
544 | return clone (); |
504 | |
545 | |
505 | rxvt_img *img = new rxvt_img (s, new_format, 0, 0, w, h, repeat); |
546 | rxvt_img *img = new rxvt_img (s, new_format, x, y, w, h, repeat); |
506 | img->alloc (); |
547 | img->alloc (); |
507 | |
548 | |
508 | Display *dpy = s->display->dpy; |
549 | Display *dpy = s->display->dpy; |
509 | Picture src = src_picture (); |
550 | Picture src = src_picture (); |
510 | Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); |
551 | Picture dst = XRenderCreatePicture (dpy, img->pm, new_format, 0, 0); |