Permalink
Browse files

Render private-use range unicode chars (except the four reserved by i…

…term). Some fonts use them for fancy special characters and it's nice to support that. The down side is that for normal fonts they'll render a bit uglier as a double-width character, but you shouldn't get them often anyway
  • Loading branch information...
gnachman committed Jan 10, 2013
1 parent 2528ccc commit 8e3ad6dabf83c60b8cf4a3e3327c596401744af6
Showing with 24 additions and 23 deletions.
  1. +7 −7 ScreenChar.h
  2. +7 −7 ScreenChar.m
  3. +10 −9 VT100Screen.m
@@ -43,8 +43,8 @@
// copy-pasting.
#define TAB_FILLER 0xf001
// If a private-use character is received as input, we convert it to this
// meaningless character.
// If DWC_SKIP appears in the input, we convert it to this to avoid causing confusion.
// NOTE: I think this isn't used because DWC_SKIP is caught early and converted to a '?'.
#define BOGUS_CHAR 0xf002
// Double-width characters have their "real" code in one cell and this code in
@@ -57,15 +57,15 @@
#define EOL_SOFT 1 // Soft line break (a long line was wrapped)
#define EOL_DWC 2 // Double-width character wrapped to next line
// The range of private codes we use, with specific instances defined right
// The range of private codes we use, with specific instances defined
// above here.
#define ITERM2_PRIVATE_BEGIN 0xf000
#define ITERM2_PRIVATE_END 0xf8fe
#define ITERM2_PRIVATE_END 0xf003
// This is the standard unicode replacement character for when input couldn't
// be parsed properly but we need to render something there.
#define UNKNOWN 0xfffd
#define ONECHAR_UNKNOWN ('#') // Used for encodings other than utf-8.
#define UNICODE_REPLACEMENT_CHAR 0xfffd
#define ONECHAR_UNKNOWN ('?') // Used for encodings other than utf-8.
// Alternate semantics definitions
// Default background color
@@ -136,7 +136,7 @@ typedef struct screen_char_t
// Standard unicode replacement string. Is a double-width character.
static inline NSString* ReplacementString()
{
const unichar kReplacementCharacter = 0xfffd;
const unichar kReplacementCharacter = UNICODE_REPLACEMENT_CHAR;
return [NSString stringWithCharacters:&kReplacementCharacter length:1];
}
@@ -43,7 +43,7 @@
NSString* ComplexCharToStr(int key)
{
if (key == UNKNOWN) {
if (key == UNICODE_REPLACEMENT_CHAR) {
return ReplacementString();
}
@@ -57,7 +57,7 @@
NSString* CharToStr(unichar code, BOOL isComplex)
{
if (code == UNKNOWN) {
if (code == UNICODE_REPLACEMENT_CHAR) {
return ReplacementString();
}
@@ -70,7 +70,7 @@
int ExpandScreenChar(screen_char_t* sct, unichar* dest) {
NSString* value = nil;
if (sct->code == UNKNOWN) {
if (sct->code == UNICODE_REPLACEMENT_CHAR) {
value = ReplacementString();
} else if (sct->complexChar) {
value = ComplexCharToStr(sct->code);
@@ -126,8 +126,8 @@ int GetOrSetComplexChar(NSString* str)
int AppendToComplexChar(int key, unichar codePoint)
{
if (key == UNKNOWN) {
return UNKNOWN;
if (key == UNICODE_REPLACEMENT_CHAR) {
return UNICODE_REPLACEMENT_CHAR;
}
NSString* str = [complexCharMap objectForKey:[NSNumber numberWithInt:key]];
@@ -145,8 +145,8 @@ int AppendToComplexChar(int key, unichar codePoint)
int BeginComplexChar(unichar initialCodePoint, unichar combiningChar)
{
if (initialCodePoint == UNKNOWN) {
return UNKNOWN;
if (initialCodePoint == UNICODE_REPLACEMENT_CHAR) {
return UNICODE_REPLACEMENT_CHAR;
}
unichar temp[2];
@@ -144,11 +144,11 @@ void StringToScreenChars(NSString *s,
lastInitializedChar = j;
}
if ((sc[i] >= 0xe000 && sc[i] <= ITERM2_PRIVATE_END) ||
sc[i] >= 0xfffd) {
// Translate private-use characters into a replacement char.
// Unfortunately, the proper replacement char U+fffd is double-width
// (at least for some fonts) which screws up formatting.
if (sc[i] >= ITERM2_PRIVATE_BEGIN && sc[i] <= ITERM2_PRIVATE_END) {
// Translate iTerm2's private-use characters into a "?". Although the replacement
// character renders as a double-width char in a single-width char's space and is ugly,
// some fonts use dwc's to add extra glyphs. It's kinda sketch, but it's better form to
// render what you get than to try to be clever and break such edge cases.
buf[j].code = '?';
} else if (sc[i] > 0xa0 && [NSString isDoubleWidthCharacter:sc[i]
encoding:encoding
@@ -166,10 +166,10 @@ void StringToScreenChars(NSString *s,
buf[j].backgroundColor = bg.backgroundColor;
buf[j].alternateBackgroundSemantics = bg.alternateBackgroundSemantics;
} else if (sc[i] == 0xfeff ||
sc[i] == 0x200b ||
sc[i] == 0x200c ||
sc[i] == 0x200d) {
} else if (sc[i] == 0xfeff || // zero width no-break space
sc[i] == 0x200b || // zero width space
sc[i] == 0x200c || // zero width non-joiner
sc[i] == 0x200d) { // zero width joiner
j--;
lastInitializedChar--;
} else if (IsCombiningMark(sc[i]) || IsLowSurrogate(sc[i])) {
@@ -2702,6 +2702,7 @@ - (void)setString:(NSString *)string ascii:(BOOL)ascii
NSAssert(buffer[idx].code != DWC_RIGHT, @"DWC cut off");
if (buffer[idx].code == DWC_SKIP) {
// I'm pretty sure this can never happen and that this code is just a historical leftover.
// This is an invalid unicode character that iTerm2 has appropriated
// for internal use. Change it to something invalid but safe.
buffer[idx].code = BOGUS_CHAR;

21 comments on commit 8e3ad6d

@shanzi

This comment has been minimized.

shanzi replied Jan 23, 2013

agree with MindTooth.

the newest version of iterm2 on google code having trouble displaying the fancy character in powerline for vim now.

@rtxanson

This comment has been minimized.

rtxanson replied Jun 21, 2013

Just tried it in the current nightly, because the current release has it regressed as well, and the current nightly has also regressed. Alas.

@gnachman

This comment has been minimized.

Owner

gnachman replied Jun 23, 2013

@makedonian

This comment has been minimized.

makedonian replied Jun 23, 2013

If it matters, I just tried compiling from master, it still fails rendering some characters (good example is vim-poweline for example)

@gnachman

This comment has been minimized.

Owner

gnachman replied Jun 23, 2013

@makedonian

This comment has been minimized.

makedonian replied Jun 24, 2013

Sure, here is screenshot of both side by side (the same special chars are used in all versions of powerline, vim, tmux, etc.)
The font used is the patched Menlo for Poweline. I was running the latest beta versions which were fine until recently, but few days ago or so they broke this font rendering.

screen shot 2013-06-23 at 8 57 39 pm

@rtxanson

This comment has been minimized.

rtxanson replied Jun 24, 2013

This is precisely how my issue looks as well, just to confirm.

@gnachman

This comment has been minimized.

Owner

gnachman replied Jun 24, 2013

Can you copy paste the actual characters in the status line in here? I guess I need a copy of the font as well to be able to reproduce this.

@rtxanson

This comment has been minimized.

rtxanson replied Jun 24, 2013

Powerline's documentation contains a list of glyphs used, as well as an explanation of the font patching process.

@gnachman

This comment has been minimized.

Owner

gnachman replied Jun 24, 2013

There was recently a change that fixed a bug where the ASCII font was used for non-ASCII characters. Make sure you set both fonts to the powerline font and then this should work for you.

@makedonian

This comment has been minimized.

makedonian replied Jun 24, 2013

Ahh yes, that does it! Thanks @gnachman

@beaugunderson

This comment has been minimized.

beaugunderson replied Jun 24, 2013

I have both fonts set to Deja Vu Sans Mono for Powerline and my glyphs don't display correctly (they match the failed screenshot above except instead of a square with an X mine are a square with a circle).

The characters are as follows:

  n  ⮀ [No Name] ⮀                       ⮂unix utf-8 ⮃ ⭢⭣ n/a ⮂ 100% ⮂ ⭡   0:0
@beaugunderson

This comment has been minimized.

beaugunderson replied Jun 25, 2013

Never mind, I was on an old version of powerline that still used the other glyphs.

@ettoredn

This comment has been minimized.

ettoredn replied Dec 9, 2013

After setting the non ASCII font, the problem is still not fixed. On iTerm2 nightly with Solarized dark and Meslo for powerline (on OS X 10.9), the color of the arrow is slightly darker.
screen shot 2013-12-09 at 3 09 12 pm

@gnachman

This comment has been minimized.

Owner

gnachman replied Dec 9, 2013

@ettoredn, what should it look like? Can you provide a session log so I can try to reproduce?

@ettoredn

This comment has been minimized.

ettoredn replied Dec 9, 2013

It should look like https://gist.github.com/agnoster/3712874, more specifically: https://gist.github.com/agnoster/3712874/raw/5d28e2d9fe2e4d0a4fda0315ad97bdafa399425c/screenshot.png

Honestly I'm not so sure it's related to iTerm since I checked on Terminal and it shows a similar difference in colors. Anyway, in past versions it worked, as you can see from that screenshot.

To reproduce:

  1. import Solarized Dark color scheme
  2. install oh-my-zsh
  3. set 'agnoster' as theme for zsh
  4. set Meslo LG S Regular for Powerline (https://github.com/Lokaltog/powerline-fonts/tree/master/Meslo) as font for both ASCII and non-ASCII characters
@ettoredn

This comment has been minimized.

ettoredn replied Dec 9, 2013

Nevermind, I just realized it's related to window's transparency. Setting it to 100% opaque solved the "problem".

@gnachman

This comment has been minimized.

Owner

gnachman replied Dec 29, 2013

The characters ± ➦ ✔ ✘ show up fine for me with Meslo LG S Regular and transparency. Weird.

@ettoredn

This comment has been minimized.

ettoredn replied Dec 29, 2013

Yep, the characters are fine. Check this screenshot: what I was saying is that I was expecting also the |> character (sorry but copy+paste doesn't correctly copy the character) to appear as transparent as the rest. I'm not sure whether this is expected or not.

screen shot 2013-12-29 at 2 36 06 am

@gnachman

This comment has been minimized.

Owner

gnachman replied Dec 29, 2013

That's working as intended: the background is translucent but the foreground is always opqaue.

@aladine

This comment has been minimized.

aladine replied May 31, 2014

I use ettoredn step 4 , update font for non-ASCII characters and it works

Please sign in to comment.