Skip to content

Instantly share code, notes, and snippets.

@nst
Last active August 29, 2015 14:04
Show Gist options
  • Save nst/77566f5a1b31584bbf75 to your computer and use it in GitHub Desktop.
Save nst/77566f5a1b31584bbf75 to your computer and use it in GitHub Desktop.
Draw all Unicode code points in all 16 planes, see http://seriot.ch/visualization/unicode/
//
// main.m
// Unicode
//
// Created by Nicolas Seriot on 26/07/14.
// Copyright (c) 2014 Nicolas Seriot. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
void drawPlane_planeNumber_usePDF(uint32_t planeNumber, BOOL usePDF) {
assert(planeNumber >= 0);
assert(planeNumber <= 16);
uint32_t plane = planeNumber << 16;
// constants
const CGFloat FONT_SIZE = 32.0;
const CGFloat PADDING = 4.0;
const CGFloat FONT_WIDTH = PADDING + FONT_SIZE + PADDING;
const CGFloat TOP_MARGIN = 50.0;
const CGFloat leftMargin = 50.0;
const uint32_t ROWS = 0xFF + 1;
const uint32_t COLUMNS = 0xFF + 1;
const CGFloat width = leftMargin + FONT_WIDTH * COLUMNS;
const CGFloat HEIGHT = TOP_MARGIN + ROWS * FONT_WIDTH;
NSDictionary *systemFontAttributes = @{ NSFontAttributeName : [NSFont systemFontOfSize:FONT_SIZE] };
NSDictionary *fixedWithFontAttributes = @{ NSFontAttributeName : [NSFont fontWithName:@"Courier" size:28.0] };
CGContextRef pdfContext = nil;
NSImage *image = nil;
NSString *path = nil;
// create file or context
if(usePDF) {
path = [NSString stringWithFormat:@"/tmp/plane_%02x.pdf", planeNumber];
NSURL *fileURL = [NSURL fileURLWithPath:path];
CGRect mediaBox = CGRectMake(0, 0, width, HEIGHT);
pdfContext = CGPDFContextCreateWithURL((CFURLRef)fileURL, &mediaBox, NULL);
CGPDFContextBeginPage(pdfContext, NULL);
NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:pdfContext flipped:NO];
[NSGraphicsContext setCurrentContext:nsContext];
} else {
path = [NSString stringWithFormat:@"/tmp/plane_%02x.png", planeNumber];
NSSize imageSize = NSMakeSize(width, HEIGHT);
image = [[NSImage alloc] initWithSize:imageSize];
[image setBackgroundColor:[NSColor whiteColor]];
[image lockFocus];
}
for(uint32_t highBits = 0x00; highBits < ROWS; highBits++) {
NSLog(@"-- plane %02x, row 0x%02x", planeNumber, highBits);
for(uint32_t lowBits = 0x00; lowBits < COLUMNS; lowBits++) {
uint32_t unicodeInt = plane + (highBits << 8) + lowBits;
NSString *string = [[NSString alloc] initWithBytes:&unicodeInt length:sizeof(uint32_t) encoding:NSUTF32LittleEndianStringEncoding];
CGFloat x = leftMargin + lowBits * FONT_WIDTH + PADDING;
CGFloat y = HEIGHT - TOP_MARGIN - ((highBits + 1) * FONT_WIDTH) + PADDING;
NSPoint p = NSMakePoint(x, y);
[string drawAtPoint:p withAttributes:systemFontAttributes];
}
}
// draw separation lines
NSPoint p0 = NSMakePoint(leftMargin, 0);
NSPoint p1 = NSMakePoint(leftMargin, HEIGHT);
NSPoint p2 = NSMakePoint(0, HEIGHT-TOP_MARGIN);
NSPoint p3 = NSMakePoint(width, HEIGHT-TOP_MARGIN);
if(usePDF) {
CGContextBeginPath(pdfContext);
CGContextMoveToPoint(pdfContext, p0.x, p0.y);
CGContextAddLineToPoint(pdfContext, p1.x, p1.y);
CGContextMoveToPoint(pdfContext, p2.x, p2.y);
CGContextAddLineToPoint(pdfContext, p3.x, p3.y);
CGContextDrawPath(pdfContext, kCGPathFillStroke);
} else {
NSBezierPath *bezierPath = [NSBezierPath bezierPath];
[bezierPath moveToPoint:p0];
[bezierPath lineToPoint:p1];
[bezierPath moveToPoint:p2];
[bezierPath lineToPoint:p3];
[bezierPath stroke];
}
// draw plane number string
{
NSString *planeNumberString = [NSString stringWithFormat:@"%02x", planeNumber];
CGFloat x = leftMargin - FONT_SIZE - 2 * PADDING;
CGFloat y = HEIGHT - TOP_MARGIN + PADDING;
NSPoint p = NSMakePoint(x, y);
[planeNumberString drawAtPoint:p withAttributes:fixedWithFontAttributes];
}
// draw row numbers
for(uint32_t highBits = 0x00; highBits < ROWS; highBits++) {
NSString *highBitsString = [[NSString stringWithFormat:@"%02x", highBits] uppercaseString];
CGFloat x = leftMargin - FONT_SIZE - 2 * PADDING;
CGFloat y = HEIGHT - TOP_MARGIN - ((highBits + 1) * FONT_WIDTH) + PADDING;
NSPoint p = NSMakePoint(x, y);
[highBitsString drawAtPoint:p withAttributes:fixedWithFontAttributes];
}
// draw columns numbers
for(uint32_t lowBits = 0x00; lowBits < COLUMNS; lowBits++) {
NSString *lowBitsString = [[NSString stringWithFormat:@"%02x", lowBits] uppercaseString];
CGFloat x = leftMargin + (lowBits * FONT_WIDTH) + PADDING;
CGFloat y = HEIGHT - TOP_MARGIN + PADDING;
NSPoint p = NSMakePoint(x, y);
[lowBitsString drawAtPoint:p withAttributes:fixedWithFontAttributes];
}
// close context and save file
if(usePDF) {
CGPDFContextEndPage(pdfContext);
CGPDFContextClose(pdfContext);
} else {
[image unlockFocus];
CGImageRef imageRef = [image CGImageForProposedRect:NULL
context:nil
hints:nil];
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
[imageRep setSize:[image size]];
NSData *pngData = [imageRep representationUsingType:NSPNGFileType properties:nil];
[pngData writeToFile:path atomically:YES];
}
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
for(uint32_t i = 0; i <= 16; i++) {
drawPlane_planeNumber_usePDF(i, NO);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment