Skip to content
Snippets Groups Projects
Commit e1278fc5 authored by George Nachman's avatar George Nachman
Browse files

Revert to old text drawing methos

parent e6484c51
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -9,78 +9,46 @@
#import <Cocoa/Cocoa.h>
#import "PTYFontInfo.h"
#import <ApplicationServices/ApplicationServices.h>
// When drawing lines, we use this object represents a run of cells of
// the same font and attributes, differing only in the characters displayed.
@interface CharacterRun : NSObject <NSCopying> {
BOOL antiAlias_;
NSColor *color_;
BOOL fakeBold_;
CGFloat x_;
PTYFontInfo *fontInfo_;
// Aggregates codes from appendCode:withAdvance: to postpone construction of NSString.
NSMutableData *temp_;
NSMutableArray *parts_;
// Array of advances. Gets realloced. If there are multiple characters in a cell, the first will
// have a positive advance and the others will have a 0 advance. Core Text's positions are used
// for those codes.
float *advances_;
int advancesSize_; // used space
int advancesCapacity_; // available space
BOOL advancedFontRendering_;
// All chars in run are ASCII?
BOOL ascii_;
// Temp storage for result of -glyphs
CGGlyph *glyphStorage_;
// Temp storage for result of -advances
NSSize *advancesStorage_;
#import "ScreenChar.h"
// Backinng storage for character runs.
@interface CRunStorage : NSObject {
unichar *codes_;
CGGlyph *glyphs_;
NSSize *advances_;
int capacity_;
int used_;
}
 
@property (nonatomic, assign) BOOL antiAlias; // Use anti-aliasing?
@property (nonatomic, retain) NSColor *color; // Foreground color
@property (nonatomic, assign) BOOL fakeBold; // Should bold text be rendered by drawing text twice with a 1px shift?
@property (nonatomic, assign) CGFloat x; // x pixel coordinate for the run's start.
@property (nonatomic, retain) PTYFontInfo *fontInfo; // Font to use.
@property (nonatomic, assign) BOOL advancedFontRendering;
// Returns YES if the codes in otherRun can be safely added to this run.
- (BOOL)isCompatibleWith:(CharacterRun *)otherRun;
// Append codes from |string|, which will be rendered in a single cell (perhaps double-width) and may
// include combining marks.
- (void)appendCodesFromString:(NSString *)string withAdvance:(CGFloat)advance;
// This adds the code to temporary storage; call |commit| to actually append.
- (void)appendCode:(unichar)code withAdvance:(CGFloat)advance;
// Returns a newly allocated line.
- (CTLineRef)newLine;
// Commit appended codes to the internal string.
- (void)commit;
// Returns the positions for characters in the given run, which begins at the specified character
// and x position. Returns the number of characters.
- (int)getPositions:(NSPoint *)positions
forRun:(CTRunRef)run
startingAtIndex:(int)firstCharacterIndex
glyphCount:(int)glyphCount
runWidthPtr:(CGFloat *)runWidthPtr;
#pragma mark - ASCII Only
// Are all codes in run ascii?
- (BOOL)isAllAscii;
// Returns array of glyphs. Only ok to call if -isAllAscii returns YES.
- (CGGlyph *)glyphs;
// Number of glyphs. Only ok to call if -isAllAscii returns YES.
- (size_t)length;
// Array of advances. Only ok to call if -isAllAscii returns YES.
- (NSSize *)advances;
+ (CRunStorage *)cRunStorageWithCapacity:(int)capacity;
- (unichar *)codesFromIndex:(int)index;
- (CGGlyph *)glyphsFromIndex:(int)index;
- (NSSize *)advancesFromIndex:(int)index;
- (int)allocate:(int)size;
 
@end
typedef struct {
BOOL antiAlias; // Use anti-aliasing?
NSColor *color; // Foreground color
BOOL fakeBold; // Should bold text be rendered by drawing text twice with a 1px shift?
PTYFontInfo *fontInfo; // Font to use.
} CAttrs;
typedef struct CRun CRun;
struct CRun {
CAttrs attrs;
CGFloat x; // x pixel coordinate for the run's start.
int length;
unichar *codes;
NSString *string;
CGGlyph *glyphs;
NSSize *advances;
BOOL terminated;
CRun *next;
};
// See CharacterRunInline.h for functions that operate on CRun.
void CRunDump(CRun *run);
Loading
Loading
@@ -8,256 +8,82 @@
 
#import "CharacterRun.h"
#import "ScreenChar.h"
#import "PreferencePanel.h"
 
static const int kDefaultAdvancesCapacity = 100;
@interface CharacterRun ()
- (NSAttributedString *)string;
@end
@implementation CharacterRun
@implementation CRunStorage : NSObject {
unichar *codes_;
CGGlyph *glyphs_;
NSSize *advances_;
int capacity_;
int used_;
}
 
@synthesize antiAlias = antiAlias_;
@synthesize color = color_;
@synthesize fakeBold = fakeBold_;
@synthesize x = x_;
@synthesize fontInfo = fontInfo_;
@synthesize advancedFontRendering = advancedFontRendering_;
+ (CRunStorage *)cRunStorageWithCapacity:(int)capacity {
return [[[CRunStorage alloc] initWithCapacity:capacity] autorelease];
}
 
- (id)init {
- (id)initWithCapacity:(int)capacity {
self = [super init];
if (self) {
advancesCapacity_ = kDefaultAdvancesCapacity;
advancesSize_ = 0;
advances_ = malloc(advancesCapacity_ * sizeof(float));
temp_ = [[NSMutableData alloc] init];
parts_ = [[NSMutableArray alloc] init];
ascii_ = YES;
capacity = MAX(capacity, 1);
codes_ = malloc(sizeof(unichar) * capacity);
glyphs_ = malloc(sizeof(CGGlyph) * capacity);
advances_ = malloc(sizeof(NSSize) * capacity);
capacity_ = capacity;
used_ = 0;
}
return self;
}
 
- (void)dealloc {
[color_ release];
[fontInfo_ release];
[temp_ release];
[parts_ release];
free(codes_);
free(glyphs_);
free(advances_);
free(glyphStorage_);
free(advancesStorage_);
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone {
CharacterRun *theCopy = [[CharacterRun alloc] init];
theCopy.antiAlias = antiAlias_;
theCopy.fontInfo = fontInfo_;
theCopy.color = color_;
theCopy.fakeBold = fakeBold_;
theCopy.x = x_;
theCopy->advances_ = (float*)realloc(theCopy->advances_, advancesCapacity_ * sizeof(float));
memcpy(theCopy->advances_, advances_, advancesCapacity_ * sizeof(float));
theCopy->advancesCapacity_ = advancesCapacity_;
theCopy->temp_ = [temp_ mutableCopy];
theCopy->parts_ = [parts_ mutableCopy];
theCopy->advancesSize_ = advancesSize_;
theCopy->ascii_ = ascii_;
theCopy.advancedFontRendering = advancedFontRendering_;
return theCopy;
}
// Align positions into cells.
- (int)getPositions:(NSPoint *)positions
forRun:(CTRunRef)run
startingAtIndex:(int)firstCharacterIndex
glyphCount:(int)glyphCount
runWidthPtr:(CGFloat *)runWidthPtr {
const NSPoint *suggestedPositions = CTRunGetPositionsPtr(run);
const CFIndex *indices = CTRunGetStringIndicesPtr(run);
int characterIndex = firstCharacterIndex;
int indexOfFirstGlyphInCurrentCell = 0;
CGFloat basePosition = 0; // X coord of the current cell relative to the start of this CTRun.
int numChars = 0;
CGFloat width = 0;
for (int glyphIndex = 0; glyphIndex < glyphCount; glyphIndex++) {
if (glyphIndex == 0 || indices[glyphIndex] != characterIndex) {
// This glyph is for a new character in the string.
// Some characters, such as THAI CHARACTER SARA AM, are composed of
// multiple glyphs, which is why this if statement's condition
// isn't always true.
if (advances_[characterIndex] > 0) {
if (glyphIndex > 0) {
// Advance to the next cell.
basePosition += advances_[characterIndex];
}
indexOfFirstGlyphInCurrentCell = glyphIndex;
width += advances_[characterIndex];
}
characterIndex = indices[glyphIndex];
++numChars;
}
CGFloat x = basePosition + suggestedPositions[glyphIndex].x - suggestedPositions[indexOfFirstGlyphInCurrentCell].x;
positions[glyphIndex] = NSMakePoint(x, suggestedPositions[glyphIndex].y);
}
*runWidthPtr = width;
return numChars;
}
- (NSString *)description {
return [[self string] description];
}
- (CTLineRef)newLine {
return CTLineCreateWithAttributedString((CFAttributedStringRef) [[[self string] copy] autorelease]);
}
- (NSAttributedString *)string {
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
for (NSArray *part in parts_) {
NSString *s = [part objectAtIndex:0];
NSDictionary *attributes = [part objectAtIndex:1];
NSAttributedString *as = [[[NSAttributedString alloc] initWithString:s attributes:attributes] autorelease];
[string appendAttributedString:as];
}
return string;
}
- (BOOL)isCompatibleWith:(CharacterRun *)otherRun {
return (antiAlias_ == otherRun.antiAlias &&
color_ == otherRun.color &&
fakeBold_ == otherRun.fakeBold &&
fontInfo_ == otherRun.fontInfo &&
advancedFontRendering_ == otherRun.advancedFontRendering);
}
- (NSDictionary *)attributes {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:fontInfo_.font forKey:NSFontAttributeName];
if (antiAlias_ && advancedFontRendering_) {
double strokeThickness = [[PreferencePanel sharedInstance] strokeThickness];
[dict setObject:[NSNumber numberWithDouble:strokeThickness] forKey:NSStrokeWidthAttributeName];
}
[dict setObject:color_ forKey:NSForegroundColorAttributeName];
// Turn off all ligatures
[dict setObject:[NSNumber numberWithInt:0] forKey:NSLigatureAttributeName];
return dict;
}
- (NSAttributedString *)attributedStringForString:(NSString *)string {
return [[[NSAttributedString alloc] initWithString:string attributes:[self attributes]] autorelease];
}
- (void)appendToAdvances:(float)advance {
if (advancesSize_ + 1 >= advancesCapacity_) {
advancesCapacity_ = (advancesSize_ + 1) * 2;
advances_ = realloc(advances_, advancesCapacity_ * sizeof(float));
}
advances_[advancesSize_++] = advance;
}
- (void)appendCode:(unichar)code withAdvance:(CGFloat)advance {
[temp_ appendBytes:&code length:sizeof(code)];
[self appendToAdvances:advance];
if (code > 127) {
ascii_ = NO;
}
- (unichar *)codesFromIndex:(int)theIndex {
assert(theIndex < used_);
return codes_ + theIndex;
}
 
- (void)appendPartWithString:(NSString *)string {
[parts_ addObject:[NSArray arrayWithObjects:string, [self attributes], nil]];
- (CGGlyph *)glyphsFromIndex:(int)theIndex {
assert(theIndex < used_);
return glyphs_ + theIndex;
}
 
- (void)commit {
if ([temp_ length]) {
[self appendPartWithString:[NSString stringWithCharacters:[temp_ bytes]
length:[temp_ length] / sizeof(unichar)]];
[temp_ setLength:0];
}
- (NSSize *)advancesFromIndex:(int)theIndex {
assert(theIndex < used_);
return advances_ + theIndex;
}
 
- (void)appendCodesFromString:(NSString *)string withAdvance:(CGFloat)advance {
[self commit];
for (int i = 1; i < [string length]; i++) {
[self appendToAdvances:0];
- (int)allocate:(int)size {
int theIndex = used_;
used_ += size;
while (used_ > capacity_) {
capacity_ *= 2;
codes_ = realloc(codes_, sizeof(unichar) * capacity_);
glyphs_ = realloc(glyphs_, sizeof(CGGlyph) * capacity_);
advances_ = realloc(advances_, sizeof(NSSize) * capacity_);
}
[self appendToAdvances:advance];
[self appendPartWithString:string];
ascii_ = NO;
}
- (void)setAntiAlias:(BOOL)antiAlias {
[self commit];
antiAlias_ = antiAlias;
}
- (void)setColor:(NSColor *)color {
[self commit];
[color_ autorelease];
color_ = [color retain];
}
- (void)setFontInfo:(PTYFontInfo *)fontInfo {
[self commit];
[fontInfo_ autorelease];
fontInfo_ = [fontInfo retain];
return theIndex;
}
 
- (BOOL)isAllAscii {
return ascii_;
}
@end
 
- (CGGlyph *)glyphs {
assert(ascii_);
[self commit];
assert([parts_ count] <= 1);
NSArray *part = [parts_ lastObject];
if (!part) {
return nil;
static void CRunDumpWithIndex(CRun *run, int offset) {
if (run->string) {
NSLog(@"run[%d]=%@ advance=%f [complex]", offset++, run->string, (float)run->advances[0].width);
} else {
for (int i = 0; i < run->length; i++) {
NSLog(@"run[%d]=%@ advance=%f", offset++, [NSString stringWithCharacters:run->codes + i length:1], (float)run->advances[i].width);
}
}
NSString *s = [part objectAtIndex:0];
int len = [s length];
if (len == 0) {
return nil;
if (run->next) {
NSLog(@"Successor:");
CRunDumpWithIndex(run->next, offset);
}
unichar chars[len];
[s getCharacters:chars range:NSMakeRange(0, len)];
if (glyphStorage_) {
free(glyphStorage_);
}
glyphStorage_ = malloc(sizeof(CGGlyph) * len);
CTFontGetGlyphsForCharacters((CTFontRef)fontInfo_.font,
chars,
glyphStorage_,
len);
return glyphStorage_;
}
 
- (size_t)length {
assert(ascii_);
[self commit];
assert([parts_ count] <= 1);
NSArray *part = [parts_ lastObject];
if (!part) {
return 0;
}
NSString *s = [part objectAtIndex:0];
return [s length];
}
- (NSSize *)advances {
if (advancesStorage_) {
free(advancesStorage_);
}
size_t length = [self length];
advancesStorage_ = malloc(sizeof(NSSize) * length);
for (int i = 0; i < length; i++) {
advancesStorage_[i] = NSMakeSize(advances_[i], 0);
}
return advancesStorage_;
}
@end
void CRunDump(CRun *run) {
CRunDumpWithIndex(run, 0);
}
\ No newline at end of file
Loading
Loading
@@ -34,6 +34,7 @@
#import "LineBuffer.h"
#import "PointerController.h"
#import "PTYFontInfo.h"
#import "CharacterRun.h"
 
#include <sys/time.h>
#define PRETTY_BOLD
Loading
Loading
@@ -64,6 +65,8 @@ enum {
 
@end
 
@class CRunStorage;
@interface PTYTextView : NSView <NSTextInput, PointerControllerDelegate>
{
// This is a flag to let us know whether we are handling this
Loading
Loading
@@ -332,6 +335,8 @@ enum {
// calls to -updateDirtyRects without making any changes, we only redraw the old and new cursor
// positions.
int prevCursorX, prevCursorY;
NSFont *selectedFont_;
}
 
+ (NSCursor *)textViewCursor;
Loading
Loading
@@ -607,6 +612,8 @@ enum {
 
- (FindContext *)initialFindContext;
 
- (NSString*)_allText;
@end
 
//
Loading
Loading
@@ -636,7 +643,7 @@ typedef enum {
 
- (NSString *)_getURLForX:(int)x y:(int)y;
// Returns true if any char in the line is blinking.
- (BOOL)_drawLine:(int)line AtY:(double)curY toPoint:(NSPoint*)toPoint;
- (BOOL)_drawLine:(int)line AtY:(double)curY toPoint:(NSPoint*)toPoint context:(CGContextRef)ctx;
- (void)_drawCursor;
- (void)_drawCursorTo:(NSPoint*)toOrigin;
- (void)_drawCharacter:(screen_char_t)screenChar
Loading
Loading
@@ -646,7 +653,13 @@ typedef enum {
AtX:(double)X
Y:(double)Y
doubleWidth:(BOOL)double_width
overrideColor:(NSColor*)overrideColor;
overrideColor:(NSColor*)overrideColor
context:(CGContextRef)ctx;
- (void)_drawRunsAt:(NSPoint)initialPoint
run:(CRun *)run
storage:(CRunStorage *)storage
context:(CGContextRef)ctx;
 
- (BOOL)_isBlankLine:(int)y;
- (void)_findUrlInString:(NSString *)aURLString andOpenInBackground:(BOOL)background;
Loading
Loading
@@ -696,7 +709,12 @@ typedef enum {
// xStart, yStart: cell coordinates
// width, height: cell width, height of screen
// cursorHeight: cursor height in pixels
- (BOOL)drawInputMethodEditorTextAt:(int)xStart y:(int)yStart width:(int)width height:(int)height cursorHeight:(double)cursorHeight;
- (BOOL)drawInputMethodEditorTextAt:(int)xStart
y:(int)yStart
width:(int)width
height:(int)height
cursorHeight:(double)cursorHeight
ctx:(CGContextRef)ctx;
 
- (BOOL)_wasAnyCharSelected;
 
Loading
Loading
This diff is collapsed.
Loading
Loading
@@ -242,6 +242,7 @@
1D67ABAC14285D6000D5DA4E /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D67ABAA14285D6000D5DA4E /* NSFileManager+DirectoryLocations.m */; };
1D6944D7169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D6944D5169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.h */; };
1D6944D8169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D6944D6169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.m */; };
1D699BC417CABC060094F0C1 /* CharacterRunInline.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D699BC317CABC060094F0C1 /* CharacterRunInline.h */; };
1D6A5FDF140D7AA000DE19F8 /* IBarCursorXMR.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D6A5FDE140D7AA000DE19F8 /* IBarCursorXMR.png */; };
1D6C18BE12951A3C00937A4A /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DEB293D1288899A00B2CB9F /* Carbon.framework */; };
1D6C4D5A122329F000E0AA3E /* ColorPresets.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D6C4D59122329F000E0AA3E /* ColorPresets.plist */; };
Loading
Loading
@@ -552,6 +553,7 @@
1D67ABAA14285D6000D5DA4E /* NSFileManager+DirectoryLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+DirectoryLocations.m"; sourceTree = "<group>"; };
1D6944D5169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreeFingerTapGestureRecognizer.h; sourceTree = "<group>"; };
1D6944D6169E96AC00C7048A /* ThreeFingerTapGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreeFingerTapGestureRecognizer.m; sourceTree = "<group>"; };
1D699BC317CABC060094F0C1 /* CharacterRunInline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterRunInline.h; sourceTree = "<group>"; };
1D6A5FDE140D7AA000DE19F8 /* IBarCursorXMR.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = IBarCursorXMR.png; path = images/IBarCursorXMR.png; sourceTree = "<group>"; };
1D6C4D59122329F000E0AA3E /* ColorPresets.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ColorPresets.plist; sourceTree = "<group>"; };
1D6C50A51226EEFB00E0AA3E /* ProfileListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProfileListView.h; sourceTree = "<group>"; };
Loading
Loading
@@ -902,6 +904,7 @@
1DA26ABE15007507004B5792 /* BackgroundThread.h */,
1DA26ABF15007507004B5792 /* BackgroundThread.m */,
1D48B377167E809D000046EE /* CharacterRun.h */,
1D699BC317CABC060094F0C1 /* CharacterRunInline.h */,
1D48B378167E809D000046EE /* CharacterRun.m */,
1D9DDD9B142E5FBB00275650 /* Coprocess.m */,
1D237D27131D8741004DD60C /* FindView.m */,
Loading
Loading
@@ -1652,6 +1655,7 @@
1D085F9A16F1135F00B7FCE9 /* PasteEvent.h in Headers */,
1D085F9E16F137D900B7FCE9 /* RoundedRectView.h in Headers */,
1D085FA216F138A100B7FCE9 /* ToastWindowController.h in Headers */,
1D699BC417CABC060094F0C1 /* CharacterRunInline.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment