Created
December 8, 2018 18:45
-
-
Save gnachman/df118759c540cc4c507a43e7cf391ff1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)drawRect:(NSRect)dirtyRect { | |
NSString *string = @"Hello world"; | |
NSDictionary *attributes = @{ (NSString *)kCTForegroundColorAttributeName: (id)[[NSColor blackColor] CGColor], | |
NSFontAttributeName: [NSFont fontWithName:@"PragmataProMono-Regular" size:12], | |
NSLigatureAttributeName: @0, | |
NSUnderlineStyleAttributeName: @1 }; | |
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string | |
attributes:attributes]; | |
CGColorRef cgColor = (__bridge CGColorRef)attributes[(NSString *)kCTForegroundColorAttributeName]; | |
NSGraphicsContext *ctx = [NSGraphicsContext currentContext]; | |
[ctx saveGraphicsState]; | |
[ctx setCompositingOperation:NSCompositingOperationSourceOver]; | |
// We used to use -[NSAttributedString drawWithRect:options] but | |
// it does a lousy job rendering multiple combining marks. This is close | |
// to what WebKit does and appears to be the highest quality text | |
// rendering available. | |
CTLineRef lineRef; | |
lineRef = CTLineCreateWithAttributedString((CFAttributedStringRef)attributedString); | |
CFArrayRef runs = CTLineGetGlyphRuns(lineRef); | |
CGContextRef cgContext = [ctx CGContext]; | |
CGContextSetShouldAntialias(cgContext, NO); | |
CGContextSetFillColorWithColor(cgContext, cgColor); | |
CGContextSetStrokeColorWithColor(cgContext, cgColor); | |
CGFloat c = 0.0; | |
const CGFloat ty = 100; | |
CGAffineTransform textMatrix = CGAffineTransformMake(1.0, 0.0, | |
c, 1.0, | |
100, ty); | |
CGContextSetTextMatrix(cgContext, textMatrix); | |
for (CFIndex j = 0; j < CFArrayGetCount(runs); j++) { | |
CTRunRef run = CFArrayGetValueAtIndex(runs, j); | |
size_t length = CTRunGetGlyphCount(run); | |
const CGGlyph *buffer = CTRunGetGlyphsPtr(run); | |
if (!buffer) { | |
NSMutableData *tempBuffer = | |
[[NSMutableData alloc] initWithLength:sizeof(CGGlyph) * length]; | |
CTRunGetGlyphs(run, CFRangeMake(0, length), (CGGlyph *)tempBuffer.mutableBytes); | |
buffer = tempBuffer.mutableBytes; | |
} | |
NSMutableData *positionsBuffer = | |
[[NSMutableData alloc] initWithLength:sizeof(CGPoint) * length]; | |
CTRunGetPositions(run, CFRangeMake(0, length), (CGPoint *)positionsBuffer.mutableBytes); | |
CGPoint *positions = positionsBuffer.mutableBytes; | |
const CFIndex *glyphIndexToCharacterIndex = CTRunGetStringIndicesPtr(run); | |
if (!glyphIndexToCharacterIndex) { | |
NSMutableData *tempBuffer = | |
[[NSMutableData alloc] initWithLength:sizeof(CFIndex) * length]; | |
CTRunGetStringIndices(run, CFRangeMake(0, length), (CFIndex *)tempBuffer.mutableBytes); | |
glyphIndexToCharacterIndex = (CFIndex *)tempBuffer.mutableBytes; | |
} | |
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName); | |
CTFontDrawGlyphs(runFont, buffer, (NSPoint *)positions, length, cgContext); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment