-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: 800b645bd92d68953ada6dc1553e65fb280a7854:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit 800b645bd92d68953ada6dc1553e65fb280a7854
Author: Sasha Vasko <sashavasko@gmail.com>
Date:   Mon Aug 6 22:42:05 2007 +0000

    fleshed out new render_asim function to be generic enough so it can be used with both transparent blended and non-transparent code

diff --git a/src/rxvt.h b/src/rxvt.h

index 9723e2bb5b252a134862c9de2957c45717211498..

index ..959f7d843a00294ca07a425b61c2b6e6637e5654 100644

--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -180,7 +180,7 @@ struct  bgPixmap_t {
 #  ifdef HAVE_AFTERIMAGE
   ASImage *original_asim;

-  ASImage *resize_asim (rxvt_term *target, ASImage *background, XRectangle &dst_rect);
+  bool render_asim (rxvt_term *target, ASImage *background, ARGB32 tint);
 #  endif

 #define bgPmap_defaultScale 100
diff --git a/src/xpm.C b/src/xpm.C

index dc895bdb0a2c3f30fdb6418f48368f2a16fe9791..

index ..268aa1abb2e3bb1859fa839bc4cd34f2b7ee42f4 100644

--- a/src/xpm.C
+++ b/src/xpm.C
@@ -143,9 +143,14 @@ make_align_position (int align, int window_size, int image_size)
 }

 static inline void
-make_clip_rectangle (int pos, int size, int target_size, short &clip_pos, unsigned short &clip_size)
+make_clip_rectangle (int pos, int size, int target_size, int &clip_pos, int &clip_size)
 {
-  if (pos < 0)
+  if (size <= 0)
+    { /* special case - tiling */
+      clip_pos = pos;
+      clip_size = target_size;
+    }
+  else if (pos < 0)
     {
       clip_pos = 0;
       clip_size = MIN (target_size, size + pos);
@@ -353,24 +358,168 @@ bgPixmap_t::handle_geometry (const char *geom)
 }

 #ifdef HAVE_AFTERIMAGE
-ASImage *
-bgPixmap_t::resize_asim (rxvt_term *target, ASImage *background, XRectangle &dst_rect)
+bool
+bgPixmap_t::render_asim (rxvt_term *target, ASImage *background, ARGB32 background_tint)
 {
-  if (original_asim == NULL || target == NULL)
-    return NULL;
+  if (target == NULL)
+    return false;

   int target_width = (int)target->szHint.width;
   int target_height = (int)target->szHint.height;
+  int new_pmap_width = target_width, new_pmap_height = target_height;
+  ASImage *result = NULL;
+
+  int x = 0;
+  int y = 0;
   int w = h_scale * target_width / 100;
   int h = v_scale * target_height / 100;
-  int x = make_align_position (h_align, target_width, w);
-  int y = make_align_position (v_align, target_height, h);

-  make_clip_rectangle (x, w, target_width, dst_rect.x, dst_rect.width);
-  make_clip_rectangle (y, h, target_height, dst_rect.y, dst_rect.height);
+  if (original_asim)
+    {
+      x = make_align_position (h_align, target_width, w > 0 ? w : (int)original_asim->width);
+      y = make_align_position (v_align, target_height, h > 0 ? h : (int)original_asim->height);
+    }
+
+  int dst_x, dst_y;
+  int clip_width, clip_height;
+
+  make_clip_rectangle (x, w, target_width, dst_x, clip_width);
+  make_clip_rectangle (y, h, target_height, dst_y, clip_height);

   /* TODO : actuall scaling code :) */
+  if (dst_x >= target_width || dst_y >= target_height
+      || clip_width <= 0 || clip_height <= 0 || original_asim == NULL)
+    {
+      result = background;
+      dst_x = dst_y = 0;
+      if (background)
+        {
+          new_pmap_width = clip_width = background->width;
+          new_pmap_height = clip_height = background->height;
+        }
+      else
+          new_pmap_width = new_pmap_height = 0;
+    }
+  else
+    {
+      result = original_asim;
+      if ((w > 0 && w != original_asim->width)
+          || (h > 0 && h != original_asim->height))
+        {
+          result = scale_asimage (target->asv, original_asim,
+                                  w > 0 ? w : original_asim->width,
+                                  h > 0 ? h : original_asim->height,
+                                  background ? ASA_ASImage : ASA_XImage,
+                                  100, ASIMAGE_QUALITY_DEFAULT);
+        }
+      if (background == NULL)
+        {/* if tiling - pixmap has to be sized exactly as the image */
+          if (h_scale == 0)
+            new_pmap_width = result->width;
+          if (v_scale == 0)
+            new_pmap_height = result->height;
+        }
+      else
+        {/* if blending background and image - pixmap has to be sized same as target window */
+          ASImageLayer *layers = create_image_layers (2);
+          ASImage *merged_im = NULL;
+
+          layers[0].im = background;
+          layers[0].clip_width = target_width;
+          layers[0].clip_height = target_height;
+          layers[0].tint = background_tint;
+          layers[1].im = result;
+          if (w <= 0)
+            {/* tile horizontally */
+              layers[1].dst_x = dst_x - (int)result->width;
+              layers[1].clip_width = result->width;
+            }
+          else
+            {/* clip horizontally */
+              layers[1].dst_x = dst_x;
+              layers[1].clip_width = clip_width;
+            }
+          if (h <= 0)
+            {
+              layers[1].dst_y = dst_y - (int)result->height;
+              layers[1].clip_height = result->height;
+            }
+          else
+            {
+              layers[1].dst_y = dst_y;
+              layers[1].clip_height = clip_height;
+            }
+          if (target->rs[Rs_blendtype])
+            {
+              layers[1].merge_scanlines = blend_scanlines_name2func (target->rs[Rs_blendtype]);
+              if (layers[1].merge_scanlines == NULL)
+                layers[1].merge_scanlines = alphablend_scanlines;
+            }
+          ASImage *tmp = merge_layers (target->asv, layers, 2, target_width, target_height,
+                                       ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT);
+          if (tmp)
+            {
+              if (result != original_asim)
+                destroy_asimage (&result);
+              result = tmp;
+              dst_x = dst_y = 0;
+              clip_width = target_width;
+              clip_height = target_height;
+            }
+          free (layers);
+        }
+    }
+
+  if (pixmap)
+    {
+      if (result == NULL
+          || pmap_width != new_pmap_width
+          || pmap_height != new_pmap_height
+          || pmap_depth != target->depth)
+        {
+          XFreePixmap (target->dpy, pixmap);
+          pixmap = None;
+        }
+    }
+
+  if (result)
+    {
+      XGCValues gcv;
+      GC gc;
+
+      /* create Pixmap */
+      if (pixmap == None)
+        {
+          pixmap = XCreatePixmap (target->dpy, target->vt, new_pmap_width, new_pmap_height, target->depth);
+          pmap_width = new_pmap_width;
+          pmap_height = new_pmap_height;
+          pmap_depth = target->depth;
+        }
+      /* fill with background color ( if result's not completely overlapping it)*/
+      gcv.foreground = target->pix_colors[Color_bg];
+      gc = XCreateGC (target->dpy, target->vt, GCForeground, &gcv);
+
+      if (dst_x > 0 || dst_y > 0
+          || dst_x + clip_width < new_pmap_width
+          || dst_y + clip_height < new_pmap_height)
+        {
+          XFillRectangle (target->dpy, pixmap, gc, 0, 0, new_pmap_width, new_pmap_height);
+        }
+      /* put result on pixmap */
+      asimage2drawable (target->asv, pixmap, result, gc, 0, 0, dst_x, dst_y, clip_width, clip_height, True);
+
+      /* set target's background to pixmap */
+      XSetWindowBackgroundPixmap (target->dpy, target->vt, pixmap);
+
+      XFreeGC (target->dpy, gc);
+    }
+  else
+    {
+      /* set target background to a pixel */
+      XSetWindowBackground (target->dpy, target->vt, target->pix_colors[Color_bg]);
+    }

+  return true;
 }
 #endif

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 12:14:14 2024