Subject: bug#21415: 25.0.50; Emacs Trunk -- pixelwise width/height for x-create-frame

From: Anders Lindgren <[email-masked]>
Date: Mon, 2 Nov 2015 21:50:39 +0100

Hi,

The empty line indicator seems to be a new kind of fringe bitmap used to
create repetitive patterns. The code was only half-hearted when it comes to
this, as it cashed only the first of the alternative images. I rewrote the
code to cache the full image and select a suitable subpart of the when
drawing.

If you have time, please try out the attached patch.

Thanks!

    -- Anders

On Mon, Nov 2, 2015 at 6:18 AM, Keith David Bershatsky <[email-masked]>
wrote:

> With respect to fringe.diff from October 29, 2015, applied to a latest
> download of Emacs master branch, an issue remains with respect to empty
> line indicators at the end of the buffer.  It looks like two of the
> indicators are correct, then one is reversed, then two are correct, then
> one is reversed, and so on.  The fringe bitmap images prior to the end of
> the buffer looked correct for the few that I tried.
>
> Thanks,
>
> Keith
>
diff --git a/src/nsimage.m b/src/nsimage.m
index e76a7db..a2e0618 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -206,6 +206,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
            fg: (unsigned long)fg bg: (unsigned long)bg
 {
   unsigned char *planes[5];
+  unsigned char bg_alpha = 0xff;
 
   [self initWithSize: NSMakeSize (w, h)];
 
@@ -219,7 +220,10 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
   [bmRep getBitmapDataPlanes: planes];
 
   if (fg == 0 && bg == 0)
-    bg = 0xffffff;
+    {
+      bg = 0xffffff;
+      bg_alpha = 0;
+    }
 
   {
     /* pull bits out to set the (bytewise) alpha mask */
@@ -244,21 +248,22 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
           c = *s++;
           for (k = 0; i < w && k < 8; ++k, ++i)
             {
-              *alpha++ = 0xff;
-              if (c & 1)
+              if (c & 0x80)
                 {
                   *rr++ = fgr;
                   *gg++ = fgg;
                   *bb++ = fgb;
+                  *alpha++ = 0xff;
                 }
               else
                 {
                   *rr++ = bgr;
                   *gg++ = bgg;
                   *bb++ = bgb;
+                  *alpha++ = bg_alpha;
                 }
               idx++;
-              c >>= 1;
+              c <<= 1;
             }
         }
   }
diff --git a/src/nsterm.m b/src/nsterm.m
index 925e9af..1f6b151 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2461,6 +2461,10 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
   static EmacsImage **bimgs = NULL;
   static int nBimgs = 0;
 
+  NSTRACE ("ns_draw_fringe_bitmap");
+  NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d",
+               p->which, p->cursor_p, p->overlay_p, p->wd, p->h, p->dh);
+
   /* grow bimgs if needed */
   if (nBimgs < max_used_fringe_bitmap)
     {
@@ -2493,19 +2497,24 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
 
       if (!img)
         {
-          unsigned short *bits = p->bits + p->dh;
-          int len = p->h;
+          // Note: For "periodic" images, allocate one EmacsImage for
+          // the base image, and use it for all dh:s.
+          unsigned short *bits = p->bits;
+          int full_height = p->h + p->dh;
           int i;
-          unsigned char *cbits = xmalloc (len);
+          unsigned char *cbits = xmalloc (full_height);
 
           for (i = 0; i < len; i++)
-            cbits[i] = ~(bits[i] & 0xff);
-          img = [[EmacsImage alloc] initFromXBM: cbits width: 8 height: p->h
+            cbits[i] = bits[i];
+          img = [[EmacsImage alloc] initFromXBM: cbits width: 8
+                                         height: full_height
                                              fg: 0 bg: 0];
           bimgs[p->which - 1] = img;
           xfree (cbits);
         }
 
+      NSTRACE_RECT ("r", r);
+
       NSRectClip (r);
       /* Since we composite the bitmap instead of just blitting it, we need
          to erase the whole background. */
@@ -2523,9 +2532,15 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
         [img setXBMColor: bm_color];
       }
 
+      // Note: For periodic images, the full image height is "h + hd".
+      // By using the height h, a suitable part of the image is used.
+      NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h);
+
+      NSTRACE_RECT ("fromRect", fromRect);
+
 #ifdef NS_IMPL_COCOA
       [img drawInRect: r
-              fromRect: NSZeroRect
+              fromRect: fromRect
              operation: NSCompositeSourceOver
               fraction: 1.0
            respectFlipped: YES