Fixed the drawing shenanigans.
This commit is contained in:
parent
94883ed620
commit
11a3fcfad0
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in New Issue