bsnes/HexFiend/HFRepresenterHexTextView.m

96 lines
3.2 KiB
Objective-C

//
// HFRepresenterHexTextView.m
// HexFiend_2
//
// Copyright 2007 ridiculous_fish. All rights reserved.
//
#import <HexFiend/HFRepresenterHexTextView.h>
#import <HexFiend/HFRepresenterTextView_Internal.h>
#import <HexFiend/HFHexTextRepresenter.h>
@implementation HFRepresenterHexTextView
- (void)generateGlyphTable {
const UniChar hexchars[17] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',' '/* Plus a space char at the end for null bytes. */};
_Static_assert(sizeof(CGGlyph[17]) == sizeof(glyphTable), "glyphTable is the wrong type");
NSFont *font = [[self font] screenFont];
bool t = CTFontGetGlyphsForCharacters((CTFontRef)font, hexchars, glyphTable, 17);
HFASSERT(t); // We don't take kindly to strange fonts around here.
CGFloat maxAdv = 0.0;
for(int i = 0; i < 17; i++) maxAdv = HFMax(maxAdv, [font advancementForGlyph:glyphTable[i]].width);
glyphAdvancement = maxAdv;
spaceAdvancement = maxAdv;
}
- (void)setFont:(NSFont *)font {
[super setFont:font];
[self generateGlyphTable];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
HFASSERT([coder allowsKeyedCoding]);
self = [super initWithCoder:coder];
[self generateGlyphTable];
return self;
}
//no need for encodeWithCoder
- (void)extractGlyphsForBytes:(const unsigned char *)bytes count:(NSUInteger)numBytes offsetIntoLine:(NSUInteger)offsetIntoLine intoArray:(struct HFGlyph_t *)glyphs advances:(CGSize *)advances resultingGlyphCount:(NSUInteger *)resultGlyphCount {
HFASSERT(bytes != NULL);
HFASSERT(glyphs != NULL);
HFASSERT(numBytes <= NSUIntegerMax);
HFASSERT(resultGlyphCount != NULL);
const NSUInteger bytesPerColumn = [self bytesPerColumn];
NSUInteger glyphIndex = 0, byteIndex = 0;
NSUInteger remainingBytesInThisColumn = (bytesPerColumn ? bytesPerColumn - offsetIntoLine % bytesPerColumn : NSUIntegerMax);
CGFloat advanceBetweenColumns = [self advanceBetweenColumns];
while (byteIndex < numBytes) {
unsigned char byte = bytes[byteIndex++];
CGFloat glyphAdvancementPlusAnySpace = glyphAdvancement;
if (--remainingBytesInThisColumn == 0) {
remainingBytesInThisColumn = bytesPerColumn;
glyphAdvancementPlusAnySpace += advanceBetweenColumns;
}
BOOL useBlank = (hidesNullBytes && byte == 0);
advances[glyphIndex] = CGSizeMake(glyphAdvancement, 0);
glyphs[glyphIndex++] = (struct HFGlyph_t){.fontIndex = 0, .glyph = glyphTable[(useBlank? 16: byte >> 4)]};
advances[glyphIndex] = CGSizeMake(glyphAdvancementPlusAnySpace, 0);
glyphs[glyphIndex++] = (struct HFGlyph_t){.fontIndex = 0, .glyph = glyphTable[(useBlank? 16: byte & 0xF)]};
}
*resultGlyphCount = glyphIndex;
}
- (CGFloat)advancePerCharacter {
return 2 * glyphAdvancement;
}
- (CGFloat)advanceBetweenColumns {
return glyphAdvancement;
}
- (NSUInteger)maximumGlyphCountForByteCount:(NSUInteger)byteCount {
return 2 * byteCount;
}
- (BOOL)hidesNullBytes {
return hidesNullBytes;
}
- (void)setHidesNullBytes:(BOOL)flag
{
flag = !! flag;
if (hidesNullBytes != flag) {
hidesNullBytes = flag;
[self setNeedsDisplay:YES];
}
}
@end