emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 411b516: Render fringe bitmaps correctly on NextSte


From: Anders Lindgren
Subject: [Emacs-diffs] master 411b516: Render fringe bitmaps correctly on NextStep (bug#21301).
Date: Wed, 04 Nov 2015 05:50:50 +0000

branch: master
commit 411b516d65b4e3b88e7b268dac7a32668e8d39c7
Author: Anders Lindgren <address@hidden>
Commit: Anders Lindgren <address@hidden>

    Render fringe bitmaps correctly on NextStep (bug#21301).
    
    The fringe bitmaps were inverted, the background was not transparent,
    the image data was horizontally mirrored, and periodic fringe bitmaps
    were not supported.
    
    * nsimage.m ([EmacsImage initFromXBM:width:height:fg:bg:]): When
    both background and foreground colors are 0, set the background
    alpha channel to 0 (making the background transparent).  When
    copying the image data, do this from the most significant bit
    (leftmost) to the least (rightmost), to avoid mirroring.
    * nsterm.m (ns_draw_fringe_bitmap): Don't invert the image bits. Add
    support for periodic images (e.g. the empty line indicator).
---
 src/nsimage.m |   15 +++++++++++----
 src/nsterm.m  |   45 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/nsimage.m b/src/nsimage.m
index e76a7db..bdaf6a4 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -202,10 +202,13 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
 }
 
 
+/* Create image from monochrome bitmap. If both FG and BG are 0
+   (black), set the background to white and make it transparent. */
 - initFromXBM: (unsigned char *)bits width: (int)w height: (int)h
            fg: (unsigned long)fg bg: (unsigned long)bg
 {
   unsigned char *planes[5];
+  unsigned char bg_alpha = 0xff;
 
   [self initWithSize: NSMakeSize (w, h)];
 
@@ -219,7 +222,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 +250,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..4f97276 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -2456,11 +2456,31 @@ ns_draw_fringe_bitmap (struct window *w, struct 
glyph_row *row,
     External (RIF); fringe-related
    -------------------------------------------------------------------------- 
*/
 {
+  /* Fringe bitmaps comes in two variants, normal and periodic.  A
+     periodic bitmap is used to create a continuous pattern.  Since a
+     bitmap is rendered one text line at a time, the start offset (dh)
+     of the bitmap varies.  Concretely, this is used for the empty
+     line indicator.
+
+     For a bitmap, "h + dh" is the full height and is always
+     invariant.  For a normal bitmap "dh" is zero.
+
+     For example, when the period is three and the full height is 72
+     the following combinations exists:
+
+       h=72 dh=0
+       h=71 dh=1
+       h=70 dh=2 */
+
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   struct face *face = p->face;
   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 +2513,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
+          for (i = 0; i < full_height; i++)
+            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 +2548,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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]