Display hidden characters in NSTextView

前端 未结 6 1570
孤城傲影
孤城傲影 2020-12-15 01:14

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 se

6条回答
  •  别那么骄傲
    2020-12-15 02:10

    I wrote a text editor a few years back - here's some meaningless code that should get you looking in (hopefully) the right direction (this is an NSLayoutManager subclass btw - and yes I know it's leaking like the proverbial kitchen sink):

    - (void)drawGlyphsForGlyphRange:(NSRange)glyphRange atPoint:(NSPoint)containerOrigin
    {
        if ([[[[MJDocumentController sharedDocumentController] currentDocument] editor] showInvisibles])
        {
            //init glyphs
            unichar crlf = 0x00B6; 
            NSString *CRLF = [[NSString alloc] initWithCharacters:&crlf length:1];
            unichar space = 0x00B7;
            NSString *SPACE = [[NSString alloc] initWithCharacters:&space length:1];
            unichar tab = 0x2192; 
            NSString *TAB = [[NSString alloc] initWithCharacters:&tab length:1];
    
            NSString *docContents = [[self textStorage] string];
            NSString *glyph;
            NSPoint glyphPoint;
            NSRect glyphRect;
            NSDictionary *attr = [[NSDictionary alloc] initWithObjectsAndKeys:[NSUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:@"invisiblesColor"]], NSForegroundColorAttributeName, nil];
    
            //loop thru current range, drawing glyphs
            int i;
            for (i = glyphRange.location; i < NSMaxRange(glyphRange); i++)
            {
                glyph = @"";
    
                //look for special chars
                switch ([docContents characterAtIndex:i])
                {
                    //space
                    case ' ':
                        glyph = SPACE;
                        break;
    
                    //tab
                    case '\t':
                        glyph = TAB;
                        break;
    
                    //eol
                    case 0x2028:
                    case 0x2029:
                    case '\n':
                    case '\r':
                        glyph = CRLF;
                        break;
    
                    //do nothing
                    default:
                        glyph = @"";
                        break;                  
                }
    
                //should we draw?
                if ([glyph length])
                {
                    glyphPoint = [self locationForGlyphAtIndex:i];
                    glyphRect = [self lineFragmentRectForGlyphAtIndex:i effectiveRange:NULL];
                    glyphPoint.x += glyphRect.origin.x;
                    glyphPoint.y = glyphRect.origin.y;
                    [glyph drawAtPoint:glyphPoint withAttributes:attr];
                }
            }
        }
    
        [super drawGlyphsForGlyphRange:glyphRange atPoint:containerOrigin];
    }
    

提交回复
热议问题