TwoTerm/CharacterGenerator.mm

185 lines
4.2 KiB
Plaintext

//
// CharacterGenerator.mm
// 2Term
//
// Created by Kelvin Sherlock on 7/4/2010.
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import "CharacterGenerator.h"
@interface CharacterGenerator ()
-(void)loadImageNamed: (NSString *)imageName;
-(id)initWithImageNamed: (NSString *)imageName;
@end
@implementation CharacterGenerator
@synthesize characterSize = _size;
#if 0
static CGImageRef PNGImage(NSString *path)
{
CGImageRef image = NULL;
CGDataProviderRef provider = NULL;
if (!path) return NULL;
provider = CGDataProviderCreateWithFilename([path fileSystemRepresentation]);
if (provider)
{
image = CGImageCreateWithPNGDataProvider( provider, NULL, NO, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
}
return image;
}
#endif
+(CharacterGenerator *)generatorForCharacterSet: (unsigned)characterSet {
static CharacterGenerator *singletons[4] = {};
static NSString *names[] = {
@"a2-charset-80",
@"a2-charset-40",
@"vt52-charset",
@"vt100-charset",
};
constexpr unsigned MaxCharSet = sizeof(names) / sizeof(names[0]);
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
for (unsigned i = 0; i < MaxCharSet; ++i)
singletons[i] = [[CharacterGenerator alloc] initWithImageNamed: names[i]];
});
if (characterSet >= MaxCharSet) return nil;
return singletons[characterSet];
}
+(id)generator
{
return [self generatorForCharacterSet: CGApple80];
}
-(id)initWithImageNamed: (NSString *)imageName {
if ((self = [super init]))
{
[self loadImageNamed: imageName];
}
return self;
}
/*
* This loads the image then split it up into 256 images.
*
* All representations are handled so it retins any @2x artwork.
*
*/
-(void)loadImageNamed:(NSString *)imageName {
_image = [[NSImage imageNamed: imageName] retain];
_size = [_image size];
_size.width /= 16;
_size.height /= 16;
for (unsigned i = 0; i < sizeof(_characters) / sizeof(_characters[0]); ++i)
_characters[i] = [[NSImage alloc] initWithSize: _size];
for (NSImageRep *rep in [_image representations]) {
CGImageRef mask;
CGImageRef src;
NSSize size;
/* src will auto release */
src = [rep CGImageForProposedRect: NULL context: nil hints: nil];
size.width = CGImageGetWidth(src) / 16;
size.height = CGImageGetHeight(src) / 16;
mask = CGImageMaskCreate(CGImageGetWidth(src),
CGImageGetHeight(src),
CGImageGetBitsPerComponent(src),
CGImageGetBitsPerPixel(src),
CGImageGetBytesPerRow(src),
CGImageGetDataProvider(src),
NULL, NO);
for (unsigned i = 0; i < 16; ++i)
{
for (unsigned j = 0; j < 16; ++j)
{
CGImageRef cgimg = CGImageCreateWithImageInRect(mask, CGRectMake(j * size.width, i * size.height, size.width, size.height));
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithCGImage: cgimg];
NSImage *nsimg = _characters[i * 16 + j];
[nsimg addRepresentation: rep];
[rep release];
CGImageRelease(cgimg);
}
}
CGImageRelease(mask);
}
}
-(void)dealloc
{
[_image release];
for (auto &o : _characters) [o release];
[super dealloc];
}
-(NSImage *)imageForCharacter: (unsigned)character
{
if (character >= sizeof(_characters) / sizeof(_characters[0])) return nil;
return _characters[character];
}
-(void)drawCharacter: (unsigned)character atPoint: (NSPoint)point
{
if (character >= sizeof(_characters) / sizeof(_characters[0])) return;
NSImage *img = _characters[character];
if (!img) return;
[img drawInRect: (NSRect){point, _size}
fromRect: NSZeroRect
operation: NSCompositeCopy
fraction: 1.0
respectFlipped: YES
hints: nil];
}
@end