#import "uipriv_darwin.h"
#import "draw.h"
#import "attrstr.h"
@interface uiprivTextFrame : NSObject {
CFAttributedStringRef attrstr;
NSArray *backgroundParams;
CTFramesetterRef framesetter;
CGSize size;
CGPathRef path;
CTFrameRef frame;
}
- (id)initWithLayoutParams:(uiDrawTextLayoutParams *)p;
- (void)draw:(uiDrawContext *)c textLayout:(uiDrawTextLayout *)tl at:(double)x y:(double)y;
- (void)returnWidth:(double *)width height:(double *)height;
- (CFArrayRef)lines;
@end
@implementation uiprivDrawTextBackgroundParams
- (id)initWithStart:(size_t)s end:(size_t)e r:(double)red g:(double)green b:(double)blue a:(double)alpha
{
self = [super init];
if (self) {
self->start = s;
self->end = e;
self->r = red;
self->g = green;
self->b = blue;
self->a = alpha;
}
return self;
}
- (void)draw:(CGContextRef)c layout:(uiDrawTextLayout *)layout at:(double)x y:(double)y utf8Mapping:(const size_t *)u16tou8
{
}
@end
@implementation uiprivTextFrame
- (id)initWithLayoutParams:(uiDrawTextLayoutParams *)p
{
CFRange range;
CGFloat cgwidth;
CFRange unused;
CGRect rect;
self = [super init];
if (self) {
self->attrstr = uiprivAttributedStringToCFAttributedString(p, &(self->backgroundParams));
self->framesetter = CTFramesetterCreateWithAttributedString(self->attrstr);
if (self->framesetter == NULL) {
}
range.location = 0;
range.length = CFAttributedStringGetLength(self->attrstr);
cgwidth = (CGFloat) (p->Width);
if (cgwidth < 0)
cgwidth = CGFLOAT_MAX;
self->size = CTFramesetterSuggestFrameSizeWithConstraints(self->framesetter,
range,
NULL,
CGSizeMake(cgwidth, CGFLOAT_MAX),
&unused);
rect.origin = CGPointZero;
rect.size = self->size;
self->path = CGPathCreateWithRect(rect, NULL);
self->frame = CTFramesetterCreateFrame(self->framesetter,
range,
self->path,
NULL);
if (self->frame == NULL) {
}
}
return self;
}
- (void)dealloc
{
CFRelease(self->frame);
CFRelease(self->path);
CFRelease(self->framesetter);
[self->backgroundParams release];
CFRelease(self->attrstr);
[super dealloc];
}
- (void)draw:(uiDrawContext *)c textLayout:(uiDrawTextLayout *)tl at:(double)x y:(double)y
{
uiprivDrawTextBackgroundParams *dtb;
CGAffineTransform textMatrix;
CGContextSaveGState(c->c);
textMatrix = CGContextGetTextMatrix(c->c);
for (dtb in self->backgroundParams)
;
CGContextTranslateCTM(c->c, 0, c->height);
CGContextScaleCTM(c->c, 1.0, -1.0);
CGContextSetTextMatrix(c->c, CGAffineTransformIdentity);
y = c->height - self->size.height - y;
CGContextTranslateCTM(c->c, x, y);
CTFrameDraw(self->frame, c->c);
CGContextSetTextMatrix(c->c, textMatrix);
CGContextRestoreGState(c->c);
}
- (void)returnWidth:(double *)width height:(double *)height
{
if (width != NULL)
*width = self->size.width;
if (height != NULL)
*height = self->size.height;
}
- (CFArrayRef)lines
{
return CTFrameGetLines(self->frame);
}
@end
struct uiDrawTextLayout {
uiprivTextFrame *frame;
uiprivTextFrame *forLines;
BOOL empty;
size_t *u8tou16;
size_t nUTF8;
size_t *u16tou8;
size_t nUTF16;
};
uiDrawTextLayout *uiDrawNewTextLayout(uiDrawTextLayoutParams *p)
{
uiDrawTextLayout *tl;
tl = uiprivNew(uiDrawTextLayout);
tl->frame = [[uiprivTextFrame alloc] initWithLayoutParams:p];
if (uiAttributedStringLen(p->String) != 0)
tl->forLines = [tl->frame retain];
else {
uiAttributedString *space;
uiDrawTextLayoutParams p2;
tl->empty = YES;
space = uiNewAttributedString(" ");
p2 = *p;
p2.String = space;
tl->forLines = [[uiprivTextFrame alloc] initWithLayoutParams:&p2];
uiFreeAttributedString(space);
}
tl->u8tou16 = uiprivAttributedStringCopyUTF8ToUTF16Table(p->String, &(tl->nUTF8));
tl->u16tou8 = uiprivAttributedStringCopyUTF16ToUTF8Table(p->String, &(tl->nUTF16));
return tl;
}
void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
{
uiprivFree(tl->u16tou8);
uiprivFree(tl->u8tou16);
[tl->forLines release];
[tl->frame release];
uiprivFree(tl);
}
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
{
[tl->frame draw:c textLayout:tl at:x y:y];
}
void uiDrawTextLayoutExtents(uiDrawTextLayout *tl, double *width, double *height)
{
[tl->frame returnWidth:width height:NULL];
[tl->forLines returnWidth:NULL height:height];
}
void uiLoadControlFont(uiFontDescriptor *f)
{
CTFontRef ctfont;
CTFontDescriptorRef ctdesc;
ctfont = (CTFontRef) [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]];
ctdesc = CTFontCopyFontDescriptor(ctfont);
uiprivFontDescriptorFromCTFontDescriptor(ctdesc, f);
CFRelease(ctdesc);
f->Size = CTFontGetSize(ctfont);
}
void uiFreeFontDescriptor(uiFontDescriptor *desc)
{
uiFreeText((char *) (desc->Family));
}