changeset 55030:44eb66585062

(x_draw_relief_rect): Add top_p and bot_p args. (x_draw_glyph_string_box): Fix call to x_draw_relief_rect. (x_draw_image_foreground, x_draw_image_relief) (x_draw_image_foreground_1, x_draw_image_glyph_string): Draw sliced images.
author Kim F. Storm <storm@cua.dk>
date Tue, 20 Apr 2004 22:19:23 +0000
parents 01ecdd56871c
children 488c36800dcc
files src/xterm.c
diffstat 1 files changed, 90 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Tue Apr 20 22:19:09 2004 +0000
+++ b/src/xterm.c	Tue Apr 20 22:19:23 2004 +0000
@@ -981,7 +981,8 @@
 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
 					   int, int, int));
 static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
-				    int, int, int, int, XRectangle *));
+				    int, int, int, int, int, int,
+				    XRectangle *));
 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
 				 int, int, int, XRectangle *));
 
@@ -2019,9 +2020,10 @@
 
 static void
 x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
-		    raised_p, left_p, right_p, clip_rect)
+		    raised_p, top_p, bot_p, left_p, right_p, clip_rect)
      struct frame *f;
-     int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p;
+     int left_x, top_y, right_x, bottom_y, width;
+     int top_p, bot_p, left_p, right_p, raised_p;
      XRectangle *clip_rect;
 {
   Display *dpy = FRAME_X_DISPLAY (f);
@@ -2036,10 +2038,11 @@
   XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
 
   /* Top.  */
-  for (i = 0; i < width; ++i)
-    XDrawLine (dpy, window, gc,
-	       left_x + i * left_p, top_y + i,
-	       right_x + 1 - i * right_p, top_y + i);
+  if (top_p)
+    for (i = 0; i < width; ++i)
+      XDrawLine (dpy, window, gc,
+		 left_x + i * left_p, top_y + i,
+		 right_x + 1 - i * right_p, top_y + i);
 
   /* Left.  */
   if (left_p)
@@ -2055,10 +2058,11 @@
   XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
 
   /* Bottom.  */
-  for (i = 0; i < width; ++i)
-    XDrawLine (dpy, window, gc,
-	       left_x + i * left_p, bottom_y - i,
-	       right_x + 1 - i * right_p, bottom_y - i);
+  if (bot_p)
+    for (i = 0; i < width; ++i)
+      XDrawLine (dpy, window, gc,
+		 left_x + i * left_p, bottom_y - i,
+		 right_x + 1 - i * right_p, bottom_y - i);
 
   /* Right.  */
   if (right_p)
@@ -2166,7 +2170,7 @@
     {
       x_setup_relief_colors (s);
       x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
-			  width, raised_p, left_p, right_p, &clip_rect);
+			  width, raised_p, 1, 1, left_p, right_p, &clip_rect);
     }
 }
 
@@ -2177,21 +2181,22 @@
 x_draw_image_foreground (s)
      struct glyph_string *s;
 {
-  int x;
-  int y = s->ybase - image_ascent (s->img, s->face);
+  int x = s->x;
+  int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
-  else
-    x = s->x;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
@@ -2216,11 +2221,12 @@
 	  get_glyph_string_clip_rect (s, &clip_rect);
 	  image_rect.x = x;
 	  image_rect.y = y;
-	  image_rect.width = s->img->width;
-	  image_rect.height = s->img->height;
+	  image_rect.width = s->slice.width;
+	  image_rect.height = s->slice.height;
 	  if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
 	    XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
-		       r.x - x, r.y - y, r.width, r.height, r.x, r.y);
+		       s->slice.x + r.x - x, s->slice.y + r.y - y,
+		       r.width, r.height, r.x, r.y);
 	}
       else
 	{
@@ -2229,11 +2235,12 @@
 	  get_glyph_string_clip_rect (s, &clip_rect);
 	  image_rect.x = x;
 	  image_rect.y = y;
-	  image_rect.width = s->img->width;
-	  image_rect.height = s->img->height;
+	  image_rect.width = s->slice.width;
+	  image_rect.height = s->slice.height;
 	  if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
 	    XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
-		       r.x - x, r.y - y, r.width, r.height, r.x, r.y);
+		       s->slice.x + r.x - x, s->slice.y + r.y - y,
+		       r.width, r.height, r.x, r.y);
 
 	  /* When the image has a mask, we can expect that at
 	     least part of a mouse highlight or a block cursor will
@@ -2245,15 +2252,17 @@
 	    {
 	      int r = s->img->relief;
 	      if (r < 0) r = -r;
-	      XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
-			      s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+	      XDrawRectangle (s->display, s->window, s->gc,
+			      x - r, y - r,
+			      s->slice.width + r*2 - 1,
+			      s->slice.height + r*2 - 1);
 	    }
 	}
     }
   else
     /* Draw a rectangle if image could not be loaded.  */
     XDrawRectangle (s->display, s->window, s->gc, x, y,
-		    s->img->width - 1, s->img->height - 1);
+		    s->slice.width - 1, s->slice.height - 1);
 }
 
 
@@ -2265,21 +2274,22 @@
 {
   int x0, y0, x1, y1, thick, raised_p;
   XRectangle r;
-  int x;
-  int y = s->ybase - image_ascent (s->img, s->face);
+  int x = s->x;
+  int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = s->x + abs (s->face->box_line_width);
-  else
-    x = s->x;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
@@ -2295,12 +2305,17 @@
 
   x0 = x - thick;
   y0 = y - thick;
-  x1 = x + s->img->width + thick - 1;
-  y1 = y + s->img->height + thick - 1;
+  x1 = x + s->slice.width + thick - 1;
+  y1 = y + s->slice.height + thick - 1;
 
   x_setup_relief_colors (s);
   get_glyph_string_clip_rect (s, &r);
-  x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
+  x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
+		      s->slice.y == 0,
+		      s->slice.y + s->slice.height == s->img->height,
+		      s->slice.x == 0,
+		      s->slice.x + s->slice.width == s->img->width,
+		      &r);
 }
 
 
@@ -2311,21 +2326,22 @@
      struct glyph_string *s;
      Pixmap pixmap;
 {
-  int x;
-  int y = s->ybase - s->y - image_ascent (s->img, s->face);
+  int x = 0;
+  int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
 
   /* If first glyph of S has a left box line, start drawing it to the
      right of that line.  */
   if (s->face->box != FACE_NO_BOX
-      && s->first_glyph->left_box_line_p)
-    x = abs (s->face->box_line_width);
-  else
-    x = 0;
+      && s->first_glyph->left_box_line_p
+      && s->slice.x == 0)
+    x += abs (s->face->box_line_width);
 
   /* If there is a margin around the image, adjust x- and y-position
      by that margin.  */
-  x += s->img->hmargin;
-  y += s->img->vmargin;
+  if (s->slice.x == 0)
+    x += s->img->hmargin;
+  if (s->slice.y == 0)
+    y += s->img->vmargin;
 
   if (s->img->pixmap)
     {
@@ -2347,13 +2363,15 @@
 	  XChangeGC (s->display, s->gc, mask, &xgcv);
 
 	  XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
-		     0, 0, s->img->width, s->img->height, x, y);
+		     s->slice.x, s->slice.y,
+		     s->slice.width, s->slice.height, x, y);
 	  XSetClipMask (s->display, s->gc, None);
 	}
       else
 	{
 	  XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
-		     0, 0, s->img->width, s->img->height, x, y);
+		     s->slice.x, s->slice.y,
+		     s->slice.width, s->slice.height, x, y);
 
 	  /* When the image has a mask, we can expect that at
 	     least part of a mouse highlight or a block cursor will
@@ -2366,14 +2384,15 @@
 	      int r = s->img->relief;
 	      if (r < 0) r = -r;
 	      XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
-			      s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+			      s->slice.width + r*2 - 1,
+			      s->slice.height + r*2 - 1);
 	    }
 	}
     }
   else
     /* Draw a rectangle if image could not be loaded.  */
     XDrawRectangle (s->display, pixmap, s->gc, x, y,
-		    s->img->width - 1, s->img->height - 1);
+		    s->slice.width - 1, s->slice.height - 1);
 }
 
 
@@ -2415,33 +2434,28 @@
 x_draw_image_glyph_string (s)
      struct glyph_string *s;
 {
-  int x, y;
   int box_line_hwidth = abs (s->face->box_line_width);
   int box_line_vwidth = max (s->face->box_line_width, 0);
   int height;
   Pixmap pixmap = None;
 
-  height = s->height - 2 * box_line_vwidth;
-
+  height = s->height;
+  if (s->slice.y == 0)
+    height -= box_line_vwidth;
+  if (s->slice.y + s->slice.height >= s->img->height)
+    height -= box_line_vwidth;
 
   /* Fill background with face under the image.  Do it only if row is
      taller than image or if image has a clip mask to reduce
      flickering.  */
   s->stippled_p = s->face->stipple != 0;
-  if (height > s->img->height
+  if (height > s->slice.height
       || s->img->hmargin
       || s->img->vmargin
       || s->img->mask
       || s->img->pixmap == 0
       || s->width != s->background_width)
     {
-      if (box_line_hwidth && s->first_glyph->left_box_line_p)
-	x = s->x + box_line_hwidth;
-      else
-	x = s->x;
-
-      y = s->y + box_line_vwidth;
-
       if (s->img->mask)
 	{
 	  /* Create a pixmap as large as the glyph string.  Fill it
@@ -2480,7 +2494,19 @@
 	    }
 	}
       else
-	x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
+	{
+	  int x = s->x;
+	  int y = s->y;
+
+	  if (s->first_glyph->left_box_line_p
+	      && s->slice.x == 0)
+	    x += box_line_hwidth;
+
+	  if (s->slice.y == 0)
+	    y += box_line_vwidth;
+
+	  x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
+	}
 
       s->background_filled_p = 1;
     }