Fixed the drawing shenanigans.
This commit is contained in:
parent
94883ed620
commit
11a3fcfad0
|
@ -50,7 +50,8 @@ uiDarwinDefineControl(
|
|||
uiAreaDrawParams dp;
|
||||
|
||||
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.AreaHeight = 0;
|
||||
|
|
|
@ -101,14 +101,16 @@ void uiDrawPathEnd(uiDrawPath *p)
|
|||
|
||||
struct uiDrawContext {
|
||||
CGContextRef c;
|
||||
CGFloat height; // needed for text; see below
|
||||
};
|
||||
|
||||
uiDrawContext *newContext(CGContextRef ctxt)
|
||||
uiDrawContext *newContext(CGContextRef ctxt, CGFloat height)
|
||||
{
|
||||
uiDrawContext *c;
|
||||
|
||||
c = uiNew(uiDrawContext);
|
||||
c->c = ctxt;
|
||||
c->height = height;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -685,17 +687,41 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *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?
|
||||
void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
|
||||
{
|
||||
CTLineRef line;
|
||||
CGRect bounds;
|
||||
|
||||
prepareContextForText(c, &y);
|
||||
|
||||
line = CTLineCreateWithAttributedString(layout->mas);
|
||||
if (line == NULL)
|
||||
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);
|
||||
|
||||
// and now we can FINALLY draw the line
|
||||
CTLineDraw(line, c->c);
|
||||
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);
|
||||
|
||||
// draw.m
|
||||
extern uiDrawContext *newContext(CGContextRef);
|
||||
extern uiDrawContext *newContext(CGContextRef, CGFloat);
|
||||
extern void freeContext(uiDrawContext *);
|
||||
|
|
Loading…
Reference in New Issue