changeset 104398:73dca9808fbe

* nsterm.m (ns_get_color): Update documentation properly for last change, and clean up loose ends in the code left by it. Fix longstanding bug with 16-bit hex parsing, and add support for yet another X11 format (rgb:r/g/b) for compatibility.
author Adrian Robert <Adrian.B.Robert@gmail.com>
date Fri, 21 Aug 2009 19:31:48 +0000
parents f6163beaa505
children 1aa0b1f2d2d1
files src/nsterm.m
diffstat 1 files changed, 46 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/nsterm.m	Fri Aug 21 19:29:31 2009 +0000
+++ b/src/nsterm.m	Fri Aug 21 19:31:48 2009 +0000
@@ -1346,13 +1346,14 @@
 /* --------------------------------------------------------------------------
      Parse a color name
 /* --------------------------------------------------------------------------
-/* On *Step, we recognize several color formats, in addition to a catalog
-   of colors found in the file Emacs.clr. Color formats include:
-   - #rrggbb where rr, gg, bb specify red, green and blue in hex. */
-{
-  NSColor * new = nil;
-  const char *hex = NULL;
-  enum { rgb } color_space;
+/* On *Step, we attempt to mimic the X11 platform here, down to installing an
+   X11 rgb.txt-compatible color list in Emacs.clr (see ns_term_init()).
+   See: http://thread.gmane.org/gmane.emacs.devel/113050/focus=113272). */
+{
+  NSColor *new = nil;
+  static char hex[20];
+  int scaling;
+  float r = -1.0, g, b;
   NSString *nsname = [NSString stringWithUTF8String: name];
 
 /*fprintf (stderr, "ns_get_color: '%s'\n", name); */
@@ -1364,60 +1365,53 @@
       name = [ns_selection_color UTF8String];
     }
 
-  if (name[0] == '0' || name[0] == '1' || name[0] == '.')
+  /* First, check for some sort of numeric specification. */
+  hex[0] = '\0';
+
+  if (name[0] == '0' || name[0] == '1' || name[0] == '.')  /* RGB decimal */
     {
-      /* RGB decimal */
       NSScanner *scanner = [NSScanner scannerWithString: nsname];
-      float r, g, b;
       [scanner scanFloat: &r];
       [scanner scanFloat: &g];
       [scanner scanFloat: &b];
+    }
+  else if (!strncmp(name, "rgb:", 4))  /* A newer X11 format -- rgb:r/g/b */
+    {
+      strcpy(hex, name + 4);
+      scaling = (strlen(hex) - 2) / 4;
+    }
+  else if (name[0] == '#')        /* An old X11 format; convert to newer */
+    {
+      int len = (strlen(name) - 1);
+      int start = (len % 3 == 0) ? 1 : len / 4 + 1;
+      int i;
+      scaling = strlen(name+start) / 3;
+      for (i=0; i<3; i++) {
+        strncpy(hex + i * (scaling + 1), name + start + i * scaling, scaling);
+        hex[(i+1) * (scaling + 1) - 1] = '/';
+      }
+      hex[3 * (scaling + 1) - 1] = '\0';
+    }
+
+  if (hex[0])
+    {
+      int rr, gg, bb;
+      float fscale = scaling == 4 ? 65535.0 : (scaling == 2 ? 255.0 : 15.0);
+      if (sscanf (hex, "%x/%x/%x", &rr, &gg, &bb))
+        {
+          r = rr / fscale;
+          g = gg / fscale;
+          b = bb / fscale;
+        }
+    }
+
+  if (r >= 0.0)
+    {
       *col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0];
       UNBLOCK_INPUT;
       return 0;
     }
 
-  if (name[0] == '#')             /* X11 format */
-    {
-      hex = name + 1;
-      color_space = rgb;
-    }
-
-  /* Direct colors (hex values) */
-  if (hex)
-    {
-      unsigned long long color = 0;
-      if (sscanf (hex, "%x", &color))
-        {
-          float f1, f2, f3, f4;
-          /* Assume it's either 1 byte or 2 per channel... */
-          if (strlen(hex) > 8) {
-            f1 = ((color >> 48) & 0xffff) / 65535.0;
-            f2 = ((color >> 32) & 0xffff) / 65535.0;
-            f3 = ((color >> 16) & 0xffff) / 65535.0;
-            f4 = ((color      ) & 0xffff) / 65535.0;
-          } else {
-            f1 = ((color >> 24) & 0xff) / 255.0;
-            f2 = ((color >> 16) & 0xff) / 255.0;
-            f3 = ((color >>  8) & 0xff) / 255.0;
-            f4 = ((color      ) & 0xff) / 255.0;
-          }
-
-          switch (color_space)
-            {
-            case rgb:
-              *col = [NSColor colorWithCalibratedRed: f2
-                                               green: f3
-                                                blue: f4
-                                               alpha: 1.0];
-              break;
-            }
-          *col = [*col colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
-          UNBLOCK_INPUT;
-          return 0;
-        }
-    }
-
   /* Otherwise, color is expected to be from a list */
   {
     NSEnumerator *lenum, *cenum;
@@ -1444,10 +1438,8 @@
       }
   }
 
-  if ( new )
+  if (new)
     *col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
-/*     else
-       NSLog (@"Failed to find color '%@'", nsname); */
   UNBLOCK_INPUT;
   return new ? 0 : 1;
 }