Skip to content

Commit

Permalink
Render private-use range unicode chars (except the four reserved by i…
Browse files Browse the repository at this point in the history
…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 8e3ad6d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 23 deletions.
14 changes: 7 additions & 7 deletions ScreenChar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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];
}

Expand Down
14 changes: 7 additions & 7 deletions ScreenChar.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

NSString* ComplexCharToStr(int key)
{
if (key == UNKNOWN) {
if (key == UNICODE_REPLACEMENT_CHAR) {
return ReplacementString();
}

Expand All @@ -57,7 +57,7 @@

NSString* CharToStr(unichar code, BOOL isComplex)
{
if (code == UNKNOWN) {
if (code == UNICODE_REPLACEMENT_CHAR) {
return ReplacementString();
}

Expand All @@ -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);
Expand Down Expand Up @@ -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]];
Expand All @@ -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];
Expand Down
19 changes: 10 additions & 9 deletions VT100Screen.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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])) {
Expand Down Expand Up @@ -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;
Expand Down

21 comments on commit 8e3ad6d

@shanzi
Copy link

@shanzi shanzi commented on 8e3ad6d Jan 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree with MindTooth.

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

@rtxanson
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Owner Author

@gnachman gnachman commented on 8e3ad6d Jun 23, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@makedonian
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@gnachman
Copy link
Owner Author

@gnachman gnachman commented on 8e3ad6d Jun 23, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@makedonian
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@gnachman
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@gnachman
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes, that does it! Thanks @gnachman

@beaugunderson
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@ettoredn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@ettoredn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@gnachman
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@ettoredn
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@aladine
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Please sign in to comment.