Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display hidden characters in NSTextView

I am writing a text editor for Mac OS X. I need to display hidden characters in an NSTextView (such as spaces, tabs, and special characters). I have spent a lot of time searching for how to do this but so far I have not found an answer. If anyone could point me in the right direction I would be grateful.

like image 682
titaniumdecoy Avatar asked Nov 18 '08 20:11

titaniumdecoy


2 Answers

Here's a fully working and clean implementation

@interface GILayoutManager : NSLayoutManager
@end

@implementation GILayoutManager

- (void)drawGlyphsForGlyphRange:(NSRange)range atPoint:(NSPoint)point {
  NSTextStorage* storage = self.textStorage;
  NSString* string = storage.string;
  for (NSUInteger glyphIndex = range.location; glyphIndex < range.location + range.length; glyphIndex++) {
    NSUInteger characterIndex = [self characterIndexForGlyphAtIndex: glyphIndex];
    switch ([string characterAtIndex:characterIndex]) {

      case ' ': {
        NSFont* font = [storage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
        [self replaceGlyphAtIndex:glyphIndex withGlyph:[font glyphWithName:@"periodcentered"]];
        break;
      }

      case '\n': {
        NSFont* font = [storage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
        [self replaceGlyphAtIndex:glyphIndex withGlyph:[font glyphWithName:@"carriagereturn"]];
        break;
      }

    }
  }

  [super drawGlyphsForGlyphRange:range atPoint:point];
}

@end

To install, use:

[myTextView.textContainer replaceLayoutManager:[[GILayoutManager alloc] init]];

To find font glyph names, you have to go to CoreGraphics:

CGFontRef font = CGFontCreateWithFontName(CFSTR("Menlo-Regular"));
for (size_t i = 0; i < CGFontGetNumberOfGlyphs(font); ++i) {
  printf("%s\n", [CFBridgingRelease(CGFontCopyGlyphNameForGlyph(font, i)) UTF8String]);
}
like image 156
Pol Avatar answered Nov 20 '22 01:11

Pol


Have a look at the NSLayoutManager class. Your NSTextView will have a layout manager associated with it, and the layout manager is responsible for associating a character (space, tab, etc.) with a glyph (the image of that character drawn on the screen).

In your case, you would probably be most interested in the replaceGlyphAtIndex:withGlyph: method, which would allow you to replace individual glyphs.

like image 5
e.James Avatar answered Nov 20 '22 00:11

e.James