git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

HexFiend/HFLineCountingRepresenter.m

      1 //
      2 //  HFLineCountingRepresenter.m
      3 //  HexFiend_2
      4 //
      5 //  Copyright 2007 ridiculous_fish. All rights reserved.
      6 //
      7 
      8 #import <HexFiend/HFLineCountingRepresenter.h>
      9 #import <HexFiend/HFLineCountingView.h>
     10 
     11 NSString *const HFLineCountingRepresenterMinimumViewWidthChanged = @"HFLineCountingRepresenterMinimumViewWidthChanged";
     12 
     13 /* Returns the maximum advance in points for a hexadecimal digit for the given font (interpreted as a screen font) */
     14 static CGFloat maximumDigitAdvanceForFont(NSFont *font) {
     15     REQUIRE_NOT_NULL(font);
     16     font = [font screenFont];
     17     CGFloat maxDigitAdvance = 0;
     18     NSDictionary *attributesDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:font, NSFontAttributeName, nil];
     19     NSTextStorage *storage = [[NSTextStorage alloc] init];
     20     NSLayoutManager *manager = [[NSLayoutManager alloc] init];
     21     [storage setFont:font];
     22     [storage addLayoutManager:manager];
     23     
     24     NSSize advancements[16] = {};
     25     NSGlyph glyphs[16];
     26     
     27     /* Generate a glyph for every hex digit */
     28     for (NSUInteger i=0; i < 16; i++) {
     29         char c = "0123456789ABCDEF"[i];
     30         NSString *string = [[NSString alloc] initWithBytes:&c length:1 encoding:NSASCIIStringEncoding];
     31         [storage replaceCharactersInRange:NSMakeRange(0, (i ? 1 : 0)) withString:string];
     32         [string release];
     33         glyphs[i] = [manager glyphAtIndex:0 isValidIndex:NULL];
     34         HFASSERT(glyphs[i] != NSNullGlyph);
     35     }
     36     
     37     /* Get the advancements of each of those glyphs */
     38     [font getAdvancements:advancements forGlyphs:glyphs count:sizeof glyphs / sizeof *glyphs];
     39     
     40     [manager release];
     41     [attributesDictionary release];
     42     [storage release];
     43     
     44     /* Find the widest digit */
     45     for (NSUInteger i=0; i < sizeof glyphs / sizeof *glyphs; i++) {
     46         maxDigitAdvance = HFMax(maxDigitAdvance, advancements[i].width);
     47     }
     48     return maxDigitAdvance;
     49 }
     50 
     51 @implementation HFLineCountingRepresenter
     52 
     53 - (instancetype)init {
     54     if ((self = [super init])) {
     55         minimumDigitCount = 2;
     56         digitsToRepresentContentsLength = minimumDigitCount;
     57         interiorShadowEdge = NSMaxXEdge;
     58         
     59         _borderedEdges = (1 << NSMaxXEdge);
     60         _borderColor = [[NSColor controlShadowColor] retain];
     61         _backgroundColor = [[NSColor windowBackgroundColor] retain];
     62     }
     63     return self;
     64 }
     65 
     66 - (void)encodeWithCoder:(NSCoder *)coder {
     67     HFASSERT([coder allowsKeyedCoding]);
     68     [super encodeWithCoder:coder];
     69     [coder encodeDouble:lineHeight forKey:@"HFLineHeight"];
     70     [coder encodeInt64:minimumDigitCount forKey:@"HFMinimumDigitCount"];
     71     [coder encodeInt64:lineNumberFormat forKey:@"HFLineNumberFormat"];
     72     [coder encodeObject:self.backgroundColor forKey:@"HFBackgroundColor"];
     73     [coder encodeObject:self.borderColor forKey:@"HFBorderColor"];
     74     [coder encodeInt64:self.borderedEdges forKey:@"HFBorderedEdges"];
     75 }
     76 
     77 - (instancetype)initWithCoder:(NSCoder *)coder {
     78     HFASSERT([coder allowsKeyedCoding]);
     79     self = [super initWithCoder:coder];
     80     lineHeight = (CGFloat)[coder decodeDoubleForKey:@"HFLineHeight"];
     81     minimumDigitCount = (NSUInteger)[coder decodeInt64ForKey:@"HFMinimumDigitCount"];
     82     lineNumberFormat = (HFLineNumberFormat)[coder decodeInt64ForKey:@"HFLineNumberFormat"];
     83     
     84     _borderedEdges = [coder decodeObjectForKey:@"HFBorderedEdges"] ? (NSInteger)[coder decodeInt64ForKey:@"HFBorderedEdges"] : 0;
     85     _borderColor = [[NSColor controlShadowColor] retain];
     86     _backgroundColor = [[NSColor windowBackgroundColor] retain];
     87 
     88     return self;
     89 }
     90 
     91 - (void)dealloc {
     92     [_borderColor release];
     93     [_backgroundColor release];
     94     [super dealloc];
     95 }
     96 
     97 - (NSView *)createView {
     98     HFLineCountingView *result = [[HFLineCountingView alloc] initWithFrame:NSMakeRect(0, 0, 60, 10)];
     99     [result setRepresenter:self];
    100     [result setAutoresizingMask:NSViewHeightSizable];
    101     return result;
    102 }
    103 
    104 - (void)postMinimumViewWidthChangedNotification {
    105     [[NSNotificationCenter defaultCenter] postNotificationName:HFLineCountingRepresenterMinimumViewWidthChanged object:self];
    106 }
    107 
    108 - (void)updateDigitAdvanceWithFont:(NSFont *)font {
    109     CGFloat newDigitAdvance = maximumDigitAdvanceForFont(font);
    110     if (digitAdvance != newDigitAdvance) {
    111         digitAdvance = newDigitAdvance;
    112         [self postMinimumViewWidthChangedNotification];
    113     }
    114 }
    115 
    116 - (void)updateFontAndLineHeight {
    117     HFLineCountingView *view = [self view];
    118     HFController *controller = [self controller];
    119     NSFont *font = controller ? [controller font] : [NSFont fontWithName:HFDEFAULT_FONT size:HFDEFAULT_FONTSIZE];
    120     [view setFont:font];
    121     [view setLineHeight: controller ? [controller lineHeight] : HFDEFAULT_FONTSIZE];
    122     [self updateDigitAdvanceWithFont:font];
    123 }
    124 
    125 - (void)updateLineNumberFormat {
    126     [[self view] setLineNumberFormat:lineNumberFormat];
    127 }
    128 
    129 - (void)updateBytesPerLine {
    130     [[self view] setBytesPerLine:[[self controller] bytesPerLine]];
    131 }
    132 
    133 - (void)updateLineRangeToDraw {
    134     HFFPRange lineRange = {0, 0};
    135     HFController *controller = [self controller];
    136     if (controller) {
    137         lineRange = [controller displayedLineRange];
    138     }
    139     [[self view] setLineRangeToDraw:lineRange];
    140 }
    141 
    142 - (CGFloat)preferredWidth {
    143     if (digitAdvance == 0) {
    144         /* This may happen if we were loaded from a nib.  We are lazy about fetching the controller's font to avoid ordering issues with nib unarchival. */
    145         [self updateFontAndLineHeight];
    146     }
    147     return (CGFloat)10. + digitsToRepresentContentsLength * digitAdvance;
    148 }
    149 
    150 - (void)updateMinimumViewWidth {
    151     HFController *controller = [self controller];
    152     if (controller) {
    153         unsigned long long contentsLength = [controller contentsLength];
    154         NSUInteger bytesPerLine = [controller bytesPerLine];
    155         /* We want to know how many lines are displayed.  That's equal to the contentsLength divided by bytesPerLine rounded down, except in the case that we're at the end of a line, in which case we need to show one more.  Hence adding 1 and dividing gets us the right result. */
    156         unsigned long long lineCount = contentsLength / bytesPerLine;
    157         unsigned long long contentsLengthRoundedToLine = HFProductULL(lineCount, bytesPerLine) - 1;
    158         NSUInteger digitCount = [HFLineCountingView digitsRequiredToDisplayLineNumber:contentsLengthRoundedToLine inFormat:lineNumberFormat];
    159         NSUInteger digitWidth = MAX(minimumDigitCount, digitCount);
    160         if (digitWidth != digitsToRepresentContentsLength) {
    161             digitsToRepresentContentsLength = digitWidth;
    162             [self postMinimumViewWidthChangedNotification];
    163         }
    164     }
    165 }
    166 
    167 - (CGFloat)minimumViewWidthForBytesPerLine:(NSUInteger)bytesPerLine {
    168     USE(bytesPerLine);
    169     return [self preferredWidth];
    170 }
    171 
    172 - (HFLineNumberFormat)lineNumberFormat {
    173     return lineNumberFormat;
    174 }
    175 
    176 - (void)setLineNumberFormat:(HFLineNumberFormat)format {
    177     HFASSERT(format < HFLineNumberFormatMAXIMUM);
    178     lineNumberFormat = format;
    179     [self updateLineNumberFormat];
    180     [self updateMinimumViewWidth];
    181 }
    182 
    183 
    184 - (void)cycleLineNumberFormat {
    185     lineNumberFormat = (lineNumberFormat + 1) % HFLineNumberFormatMAXIMUM;
    186     [self updateLineNumberFormat];
    187     [self updateMinimumViewWidth];
    188 }
    189 
    190 - (void)initializeView {
    191     [self updateFontAndLineHeight];
    192     [self updateLineNumberFormat];
    193     [self updateBytesPerLine];
    194     [self updateLineRangeToDraw];
    195     [self updateMinimumViewWidth];
    196 }
    197 
    198 - (void)controllerDidChange:(HFControllerPropertyBits)bits {
    199     if (bits & HFControllerDisplayedLineRange) [self updateLineRangeToDraw];
    200     if (bits & HFControllerBytesPerLine) [self updateBytesPerLine];
    201     if (bits & (HFControllerFont | HFControllerLineHeight)) [self updateFontAndLineHeight];
    202     if (bits & (HFControllerContentLength)) [self updateMinimumViewWidth];
    203 }
    204 
    205 - (void)setMinimumDigitCount:(NSUInteger)width {
    206     minimumDigitCount = width;
    207     [self updateMinimumViewWidth];
    208 }
    209 
    210 - (NSUInteger)minimumDigitCount {
    211     return minimumDigitCount;
    212 }
    213 
    214 - (NSUInteger)digitCount {
    215     return digitsToRepresentContentsLength;
    216 }
    217 
    218 + (NSPoint)defaultLayoutPosition {
    219     return NSMakePoint(-1, 0);
    220 }
    221 
    222 - (void)setInteriorShadowEdge:(NSInteger)edge {
    223     self->interiorShadowEdge = edge;
    224     if ([self isViewLoaded]) {
    225         [[self view] setNeedsDisplay:YES];
    226     }
    227 }
    228 
    229 - (NSInteger)interiorShadowEdge {
    230     return interiorShadowEdge;
    231 }
    232 
    233 
    234 - (void)setBorderColor:(NSColor *)color {
    235     [_borderColor autorelease];
    236     _borderColor = [color copy];
    237     if ([self isViewLoaded]) {
    238         [[self view] setNeedsDisplay:YES];
    239     }
    240 }
    241 
    242 - (void)setBackgroundColor:(NSColor *)color {
    243     [_backgroundColor autorelease];
    244     _backgroundColor = [color copy];
    245     if ([self isViewLoaded]) {
    246         [[self view] setNeedsDisplay:YES];
    247     }
    248 }
    249 
    250 @end

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.