Mercurial > emacs
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; }