Fixed the drawing shenanigans.

This commit is contained in:
Pietro Gagliardi 2016-01-08 13:51:39 -05:00
parent 94883ed620
commit 11a3fcfad0
3 changed files with 32 additions and 5 deletions

View File

@ -50,7 +50,8 @@ uiDarwinDefineControl(
uiAreaDrawParams dp; uiAreaDrawParams dp;
c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
dp.Context = newContext(c); // see draw.m under text for why we need the height
dp.Context = newContext(c, [self bounds].size.height);
dp.AreaWidth = 0; dp.AreaWidth = 0;
dp.AreaHeight = 0; dp.AreaHeight = 0;

View File

@ -101,14 +101,16 @@ void uiDrawPathEnd(uiDrawPath *p)
struct uiDrawContext { struct uiDrawContext {
CGContextRef c; CGContextRef c;
CGFloat height; // needed for text; see below
}; };
uiDrawContext *newContext(CGContextRef ctxt) uiDrawContext *newContext(CGContextRef ctxt, CGFloat height)
{ {
uiDrawContext *c; uiDrawContext *c;
c = uiNew(uiDrawContext); c = uiNew(uiDrawContext);
c->c = ctxt; c->c = ctxt;
c->height = height;
return c; return c;
} }
@ -685,17 +687,41 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
uiFree(layout); uiFree(layout);
} }
// Core Text doesn't draw onto a flipped view correctly; we have to do this
// see the iOS bits of the first example at https://developer.apple.com/library/mac/documentation/StringsTextFonts/Conceptual/CoreText_Programming/LayoutOperations/LayoutOperations.html#//apple_ref/doc/uid/TP40005533-CH12-SW1 (iOS is naturally flipped)
static void prepareContextForText(uiDrawContext *c, double *y)
{
CGContextSaveGState(c->c);
CGContextTranslateCTM(c->c, 0, c->height);
CGContextScaleCTM(c->c, 1.0, -1.0);
CGContextSetTextMatrix(c->c, CGAffineTransformIdentity);
// wait, that's not enough; we need to offset y values to account for our new flipping
*y = c->height - *y;
}
// TODO how does this behave with multiple lines? on other platforms? is there a generic way to draw this unbounded? // TODO how does this behave with multiple lines? on other platforms? is there a generic way to draw this unbounded?
void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout) void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
{ {
CTLineRef line; CTLineRef line;
CGRect bounds;
prepareContextForText(c, &y);
line = CTLineCreateWithAttributedString(layout->mas); line = CTLineCreateWithAttributedString(layout->mas);
if (line == NULL) if (line == NULL)
complain("error creating CTLine object in uiDrawText()"); complain("error creating CTLine object in uiDrawText()");
// TODO figure out why this fixes text rendering
CGContextSetTextMatrix(c->c, CGAffineTransformIdentity); // oh, and (x, y) is the bottom-left corner; we need the top-left
// remember that we're flipped, so we subtract
bounds = CTLineGetImageBounds(line, c->c);
// though CTLineGetImageBounds() returns CGRectNull on error, it also returns CGRectNull on an empty string, so we can't reasonably check for error
y -= bounds.size.height;
CGContextSetTextPosition(c->c, x, y); CGContextSetTextPosition(c->c, x, y);
// and now we can FINALLY draw the line
CTLineDraw(line, c->c); CTLineDraw(line, c->c);
CFRelease(line); CFRelease(line);
CGContextRestoreGState(c->c);
} }

View File

@ -78,5 +78,5 @@ extern BOOL fromKeycode(unsigned short keycode, uiAreaKeyEvent *ke);
extern BOOL keycodeModifier(unsigned short keycode, uiModifiers *mod); extern BOOL keycodeModifier(unsigned short keycode, uiModifiers *mod);
// draw.m // draw.m
extern uiDrawContext *newContext(CGContextRef); extern uiDrawContext *newContext(CGContextRef, CGFloat);
extern void freeContext(uiDrawContext *); extern void freeContext(uiDrawContext *);