BLGenerateOFLabel.c [plain text]
#include <CoreFoundation/CoreFoundation.h>
#include <sys/types.h>
#include "bless.h"
#include "bless_private.h"
static const char clut[] =
{
0x00,
0xF6,
0xF7,
0x2A,
0xF8,
0xF9,
0x55,
0xFA,
0xFB,
0x80,
0xFC,
0xFD,
0xAB,
0xFE,
0xFF,
0xD6,
};
static int makeLabelOfSize(const char *label, unsigned char *bitmapData,
uint16_t width, uint16_t height, int scale, uint16_t *newwidth);
static int refitToWidth(unsigned char *bitmapData,
uint16_t width, uint16_t height, uint16_t newwidth);
int BLGenerateLabelData(BLContextPtr context, const char *label, int scale, CFDataRef *data)
{
uint16_t width = 340 * scale;
uint16_t height = 12 * scale;
uint16_t newwidth;
int err;
int i;
CFDataRef bits = NULL;
unsigned char *bitmapData;
contextprintf(context, kBLLogLevelError,
"CoreGraphics is not available for rendering\n");
return 1;
bitmapData = (unsigned char *)malloc(width*height+5);
if (!bitmapData) {
contextprintf(context, kBLLogLevelError,
"Could not alloc CoreGraphics backing store\n");
return 1;
}
bzero(bitmapData, width*height+5);
err = makeLabelOfSize(label, bitmapData+5, width, height, scale, &newwidth);
if (err) {
free(bitmapData);
*data = NULL;
return 2;
}
if (newwidth > width) newwidth = width;
contextprintf(context, kBLLogLevelVerbose, "Refitting to width %d\n", newwidth);
err = refitToWidth(bitmapData+5, width, height, newwidth);
if (err) {
free(bitmapData);
*data = NULL;
return 3;
}
bitmapData = realloc(bitmapData, newwidth*height+5);
if (!bitmapData) {
contextprintf(context, kBLLogLevelError,
"Could not realloc to shrink CoreGraphics backing store\n");
return 4;
}
bitmapData[0] = 1;
*(uint16_t *)&bitmapData[1] = CFSwapInt16HostToBig(newwidth);
*(uint16_t *)&bitmapData[3] = CFSwapInt16HostToBig(height);
for(i=5; i < newwidth*height+5; i++) {
bitmapData[i] = clut[bitmapData[i] >> 4];
}
bits = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *)bitmapData, newwidth*height+5, kCFAllocatorMalloc);
if(bits == NULL) {
contextprintf(context, kBLLogLevelError,
"Could not create CFDataRef\n");
return 6;
}
*data = (void *)bits;
return 0;
}
int BLGenerateOFLabel(BLContextPtr context,
const char label[],
CFDataRef* data) {
uint16_t width = 340;
uint16_t height = 12;
uint16_t newwidth;
int err;
int i;
CFDataRef bits = NULL;
unsigned char *bitmapData;
contextprintf(context, kBLLogLevelError,
"CoreGraphics is not available for rendering\n");
return 1;
bitmapData = (unsigned char *)malloc(width*height+5);
if(!bitmapData) {
contextprintf(context, kBLLogLevelError,
"Could not alloc CoreGraphics backing store\n");
return 1;
}
bzero(bitmapData, width*height+5);
err = makeLabelOfSize(label, bitmapData+5, width, height, 1, &newwidth);
if(err) {
free(bitmapData);
*data = NULL;
return 2;
}
if(newwidth > width) newwidth = width;
contextprintf(context, kBLLogLevelVerbose, "Refitting to width %d\n", newwidth);
err = refitToWidth(bitmapData+5, width, height, newwidth);
if(err) {
free(bitmapData);
*data = NULL;
return 3;
}
bitmapData = realloc(bitmapData, newwidth*height+5);
if(NULL == bitmapData) {
contextprintf(context, kBLLogLevelError,
"Could not realloc to shrink CoreGraphics backing store\n");
return 4;
}
bitmapData[0] = 1;
*(uint16_t *)&bitmapData[1] = CFSwapInt16HostToBig(newwidth);
*(uint16_t *)&bitmapData[3] = CFSwapInt16HostToBig(height);
for(i=5; i < newwidth*height+5; i++) {
bitmapData[i] = clut[bitmapData[i] >> 4];
}
bits = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *)bitmapData, newwidth*height+5, kCFAllocatorMalloc);
if(bits == NULL) {
contextprintf(context, kBLLogLevelError,
"Could not create CFDataRef\n");
return 6;
}
*data = (void *)bits;
return 0;
}
#undef USE_COREGRAPHICS
#define USE_COREGRAPHICS 0
#if USE_COREGRAPHICS
#include <ApplicationServices/ApplicationServices.h>
static int makeLabelOfSize(const char *label, unsigned char *bitmapData,
uint16_t width, uint16_t height, int scale, uint16_t *newwidth) {
int bitmapByteCount;
int bitmapBytesPerRow;
CGContextRef context = NULL;
CGColorSpaceRef colorSpace = NULL;
bitmapBytesPerRow = width*1;
bitmapByteCount = bitmapBytesPerRow * height;
colorSpace = CGColorSpaceCreateDeviceGray();
context = CGBitmapContextCreate( bitmapData,
width,
height,
8,
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaNone);
if(context == NULL) {
fprintf(stderr, "Could not init CoreGraphics context\n");
return 1;
}
#if USE_CORETEXT
{
CFStringRef s1;
CFAttributedStringRef s2;
CTLineRef ct1;
CGRect rect;
CFMutableDictionaryRef dict;
CGColorRef color;
CTFontRef fontRef;
const CGFloat components[] = {
(CGFloat)1.0, (CGFloat)1.0
};
color = CGColorCreate(colorSpace, components);
if(color == NULL) return 1;
fontRef = CTFontCreateWithName(CFSTR("Helvetica"), 10.0 * scale, NULL);
if(fontRef == NULL) return 1;
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(dict, kCTForegroundColorAttributeName, color);
CFDictionarySetValue(dict, kCTFontAttributeName, fontRef);
CFRelease(color);
CFRelease(fontRef);
s1 = CFStringCreateWithCString(kCFAllocatorDefault, label, kCFStringEncodingUTF8);
s2 = CFAttributedStringCreate(kCFAllocatorDefault,s1,dict);
CFRelease(s1);
CFRelease(dict);
ct1 = CTLineCreateWithAttributedString(s2);
CFRelease(s2);
if(ct1 == NULL) return 2;
rect = CTLineGetImageBounds(ct1, context);
CGContextSetTextPosition(context, 2.0 * scale, 2.0 * scale);
CTLineDraw(ct1, context);
CGContextFlush(context);
CFRelease(ct1);
if(newwidth) { *newwidth = (int)rect.size.width + 4 * scale; }
}
#else
{
CGPoint pt;
CGContextSetTextDrawingMode(context, kCGTextFill);
CGContextSelectFont(context, "Helvetica", 10.0 * scale, kCGEncodingMacRoman);
CGContextSetGrayFillColor(context, 1.0, 1.0);
CGContextSetShouldAntialias(context, 1);
CGContextSetCharacterSpacing(context, 0.5 * scale);
pt = CGContextGetTextPosition(context);
CGContextShowTextAtPoint(context, 2.0 * scale, 2.0 * scale, label, strlen(label));
pt = CGContextGetTextPosition(context);
if(newwidth) { *newwidth = (int)pt.x + 2; }
}
#endif
#if 0
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, bitmapData, height*width, NULL);
CGImageRef imageRef = CGImageCreate(width,height,8,8,bitmapBytesPerRow,colorSpace,0, dataProvider, NULL, 0, 0);
CFURLRef output = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)"foo.tiff", strlen("foo.tiff"), 0);
CGImageDestinationRef dest = CGImageDestinationCreateWithURL(output, CFSTR("public.tiff"), 1, NULL);
CGImageDestinationAddImage(dest, imageRef, NULL);
CGImageDestinationFinalize(dest);
CFRelease(dest);
CFRelease(output);
CFRelease(imageRef);
CFRelease(dataProvider);
#endif
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
return 0;
}
#else // !USE_COREGRAPHICS
static int makeLabelOfSize(const char *label, unsigned char *bitmapData,
uint16_t width, uint16_t height, int scale, uint16_t *newwidth) {
*newwidth = 10;
return 0;
}
#endif // !USE_COREGRAPHICS
static int refitToWidth(unsigned char *bitmapData,
uint16_t width, uint16_t height, uint16_t newwidth)
{
uint16_t row;
for(row=1; row < height; row++) {
bcopy(&bitmapData[row*width], &bitmapData[row*newwidth], newwidth);
}
return 0;
}