]> code.delx.au - gnu-emacs/blobdiff - src/nsimage.m
Rework C source files to avoid ^(
[gnu-emacs] / src / nsimage.m
index f37ad38ad1e8d851e821750377d0a6337909ab59..5b2534b900725e19c65c64174a009bbb02c960f0 100644 (file)
@@ -1,13 +1,13 @@
 /* Image support for the NeXT/Open/GNUstep and MacOSX window system.
-   Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2015 Free Software
+   Copyright (C) 1989, 1992-1994, 2005-2006, 2008-2016 Free Software
    Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -33,15 +33,8 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
 #include "dispextern.h"
 #include "nsterm.h"
 #include "frame.h"
+#include "coding.h"
 
-/* call tracing */
-#if 0
-int image_trace_num = 0;
-#define NSTRACE(x)        fprintf (stderr, "%s:%d: [%d] " #x "\n",         \
-                                __FILE__, __LINE__, ++image_trace_num)
-#else
-#define NSTRACE(x)
-#endif
 
 
 /* ==========================================================================
@@ -53,18 +46,19 @@ int image_trace_num = 0;
    ========================================================================== */
 
 void *
-ns_image_from_XBM (unsigned char *bits, int width, int height)
+ns_image_from_XBM (unsigned char *bits, int width, int height,
+                   unsigned long fg, unsigned long bg)
 {
-  NSTRACE (ns_image_from_XBM);
+  NSTRACE ("ns_image_from_XBM");
   return [[EmacsImage alloc] initFromXBM: bits
                                    width: width height: height
-                                    flip: YES];
+                                      fg: fg bg: bg];
 }
 
 void *
 ns_image_for_XPM (int width, int height, int depth)
 {
-  NSTRACE (ns_image_for_XPM);
+  NSTRACE ("ns_image_for_XPM");
   return [[EmacsImage alloc] initForXPMWithDepth: depth
                                            width: width height: height];
 }
@@ -72,7 +66,7 @@ ns_image_for_XPM (int width, int height, int depth)
 void *
 ns_image_from_file (Lisp_Object file)
 {
-  NSTRACE (ns_image_from_bitmap_file);
+  NSTRACE ("ns_image_from_file");
   return [EmacsImage allocInitFromFile: file];
 }
 
@@ -83,7 +77,7 @@ ns_load_image (struct frame *f, struct image *img,
   EmacsImage *eImg = nil;
   NSSize size;
 
-  NSTRACE (ns_load_image);
+  NSTRACE ("ns_load_image");
 
   if (STRINGP (spec_file))
     {
@@ -101,7 +95,7 @@ ns_load_image (struct frame *f, struct image *img,
 
   if (eImg == nil)
     {
-      add_to_log ("Unable to load image %s", img->spec, Qnil);
+      add_to_log ("Unable to load image %s", img->spec);
       return 0;
     }
 
@@ -168,6 +162,7 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
   found = x_find_image_file (file);
   if (!STRINGP (found))
     return nil;
+  found = ENCODE_FILE (found);
 
   image = [[EmacsImage alloc] initByReferencingFile:
                      [NSString stringWithUTF8String: SSDATA (found)]];
@@ -186,7 +181,11 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
 
   /* The next two lines cause the DPI of the image to be ignored.
      This seems to be the behavior users expect. */
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
   [image setScalesWhenResized: YES];
+#endif
+#endif
   [image setSize: NSMakeSize([imgRep pixelsWide], [imgRep pixelsHigh])];
 
   [image setName: [NSString stringWithUTF8String: SSDATA (file)]];
@@ -203,18 +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
-         flip: (BOOL)flip
+           fg: (unsigned long)fg bg: (unsigned long)bg
 {
-  return [self initFromSkipXBM: bits width: w height: h flip: flip length: 0];
-}
-
-
-- initFromSkipXBM: (unsigned char *)bits width: (int)w height: (int)h
-             flip: (BOOL)flip length: (int)length;
-{
-  int bpr = (w + 7) / 8;
   unsigned char *planes[5];
+  unsigned char bg_alpha = 0xff;
 
   [self initWithSize: NSMakeSize (w, h)];
 
@@ -226,57 +220,62 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
                                     bytesPerRow: w bitsPerPixel: 0];
 
   [bmRep getBitmapDataPlanes: planes];
+
+  if (fg == 0 && bg == 0)
+    {
+      bg = 0xffffff;
+      bg_alpha = 0;
+    }
+
   {
     /* pull bits out to set the (bytewise) alpha mask */
     int i, j, k;
     unsigned char *s = bits;
+    unsigned char *rr = planes[0];
+    unsigned char *gg = planes[1];
+    unsigned char *bb = planes[2];
     unsigned char *alpha = planes[3];
-    unsigned char swt[16] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13,
-                             3, 11, 7, 15};
-    unsigned char c, bitPat;
-
-    for (j = 0; j < h; j++)
-      for (i = 0; i < bpr; i++)
+    unsigned char fgr = (fg >> 16) & 0xff;
+    unsigned char fgg = (fg >> 8) & 0xff;
+    unsigned char fgb = fg & 0xff;
+    unsigned char bgr = (bg >> 16) & 0xff;
+    unsigned char bgg = (bg >> 8) & 0xff;
+    unsigned char bgb = bg & 0xff;
+    unsigned char c;
+
+    int idx = 0;
+    for (j = 0; j < h; ++j)
+      for (i = 0; i < w; )
         {
-          if (length)
+          c = *s++;
+          for (k = 0; i < w && k < 8; ++k, ++i)
             {
-              unsigned char s1, s2;
-              while (*s++ != 'x' && s < bits + length);
-              if (s >= bits + length)
+              if (c & 0x80)
                 {
-                  [bmRep release];
-                  bmRep = nil;
-                  return nil;
+                  *rr++ = fgr;
+                  *gg++ = fgg;
+                  *bb++ = fgb;
+                  *alpha++ = 0xff;
                 }
-#define hexchar(x) ('0' <= (x) && (x) <= '9' ? (x) - '0' : (x) - 'a' + 10)
-              s1 = *s++;
-              s2 = *s++;
-              c = hexchar (s1) * 0x10 + hexchar (s2);
-            }
-          else
-            c = *s++;
-
-          bitPat = flip ? swt[c >> 4] | (swt[c & 0xf] << 4) : c ^ 255;
-          for (k =0; k<8; k++)
-            {
-              *alpha++ = (bitPat & 0x80) ? 0xff : 0;
-              bitPat <<= 1;
+              else
+                {
+                  *rr++ = bgr;
+                  *gg++ = bgg;
+                  *bb++ = bgb;
+                  *alpha++ = bg_alpha;
+                }
+              idx++;
+              c <<= 1;
             }
         }
   }
 
+  xbm_fg = fg;
   [self addRepresentation: bmRep];
-
-  memset (planes[0], 0, w*h);
-  memset (planes[1], 0, w*h);
-  memset (planes[2], 0, w*h);
-  [self setXBMColor: [NSColor blackColor]];
   return self;
 }
 
-
-/* Set color for a bitmap image (see initFromSkipXBM).  Note that the alpha
-   is used as a mask, so we just memset the entire array. */
+/* Set color for a bitmap image.  */
 - setXBMColor: (NSColor *)color
 {
   NSSize s = [self size];
@@ -296,19 +295,21 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
 
   [bmRep getBitmapDataPlanes: planes];
 
-  /* we used to just do this, but Cocoa seems to have a bug when rendering
-     an alpha-masked image onto a dark background where it bloats the mask */
-   /* memset (planes[0..2], r, g, b*0xff, len); */
   {
     int i, len = s.width*s.height;
     int rr = r * 0xff, gg = g * 0xff, bb = b * 0xff;
-    for (i =0; i<len; i++)
-      if (planes[3][i] != 0)
+    unsigned char fgr = (xbm_fg >> 16) & 0xff;
+    unsigned char fgg = (xbm_fg >> 8) & 0xff;
+    unsigned char fgb = xbm_fg & 0xff;
+
+    for (i = 0; i < len; ++i)
+      if (planes[0][i] == fgr && planes[1][i] == fgg && planes[2][i] == fgb)
         {
           planes[0][i] = rr;
           planes[1][i] = gg;
           planes[2][i] = bb;
         }
+    xbm_fg = ((rr << 16) & 0xff) + ((gg << 8) & 0xff) + (bb & 0xff);
   }
 
   return self;
@@ -356,7 +357,11 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
 
           /* The next two lines cause the DPI of the image to be ignored.
              This seems to be the behavior users expect. */
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
           [self setScalesWhenResized: YES];
+#endif
+#endif
           [self setSize: NSMakeSize([bmr pixelsWide], [bmr pixelsHigh])];
 
           break;