Some more work on the new Cocoa text drawing code.
This commit is contained in:
parent
6212ac7238
commit
1bd2ca22c2
|
@ -44,6 +44,7 @@ list(APPEND _LIBUI_SOURCES
|
||||||
)
|
)
|
||||||
set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
|
set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
|
||||||
|
|
||||||
|
// TODO is this correct?
|
||||||
list(APPEND _LIBUI_INCLUDEDIRS
|
list(APPEND _LIBUI_INCLUDEDIRS
|
||||||
darwin
|
darwin
|
||||||
)
|
)
|
||||||
|
|
|
@ -227,54 +227,6 @@ void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *he
|
||||||
freeFramesetter(&fs);
|
freeFramesetter(&fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
|
||||||
// TODO how is this affected by the CTM?
|
|
||||||
static void prepareContextForText(CGContextRef c, CGFloat cheight, double *y)
|
|
||||||
{
|
|
||||||
CGContextSaveGState(c);
|
|
||||||
CGContextTranslateCTM(c, 0, cheight);
|
|
||||||
CGContextScaleCTM(c, 1.0, -1.0);
|
|
||||||
CGContextSetTextMatrix(c, CGAffineTransformIdentity);
|
|
||||||
|
|
||||||
// wait, that's not enough; we need to offset y values to account for our new flipping
|
|
||||||
*y = cheight - *y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO placement is incorrect for Helvetica
|
|
||||||
void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextLayout *layout)
|
|
||||||
{
|
|
||||||
struct framesetter fs;
|
|
||||||
CGRect rect;
|
|
||||||
CGPathRef path;
|
|
||||||
CTFrameRef frame;
|
|
||||||
|
|
||||||
prepareContextForText(c, cheight, &y);
|
|
||||||
mkFramesetter(layout, &fs);
|
|
||||||
|
|
||||||
// oh, and since we're flipped, y is the bottom-left coordinate of the rectangle, not the top-left
|
|
||||||
// since we are flipped, we subtract
|
|
||||||
y -= fs.extents.height;
|
|
||||||
|
|
||||||
rect.origin = CGPointMake(x, y);
|
|
||||||
rect.size = fs.extents;
|
|
||||||
path = CGPathCreateWithRect(rect, NULL);
|
|
||||||
|
|
||||||
frame = CTFramesetterCreateFrame(fs.fs,
|
|
||||||
CFRangeMake(0, 0),
|
|
||||||
path,
|
|
||||||
fs.frameAttrib);
|
|
||||||
if (frame == NULL)
|
|
||||||
complain("error creating CTFrame object in doDrawText()");
|
|
||||||
CTFrameDraw(frame, c);
|
|
||||||
CFRelease(frame);
|
|
||||||
|
|
||||||
CFRelease(path);
|
|
||||||
|
|
||||||
freeFramesetter(&fs);
|
|
||||||
CGContextRestoreGState(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// LONGTERM provide an equivalent to CTLineGetTypographicBounds() on uiDrawTextLayout?
|
// LONGTERM provide an equivalent to CTLineGetTypographicBounds() on uiDrawTextLayout?
|
||||||
|
|
||||||
// LONGTERM keep this for later features and documentation purposes
|
// LONGTERM keep this for later features and documentation purposes
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// 6 january 2017
|
||||||
|
|
||||||
|
struct uiDrawContext {
|
||||||
|
CGContextRef c;
|
||||||
|
CGFloat height; // needed for text; see below
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
// 6 september 2015
|
// 6 september 2015
|
||||||
#import "uipriv_darwin.h"
|
#import "uipriv_darwin.h"
|
||||||
|
#import "draw.h"
|
||||||
|
|
||||||
struct uiDrawPath {
|
struct uiDrawPath {
|
||||||
CGMutablePathRef path;
|
CGMutablePathRef path;
|
||||||
|
@ -103,11 +104,6 @@ void uiDrawPathEnd(uiDrawPath *p)
|
||||||
p->ended = TRUE;
|
p->ended = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct uiDrawContext {
|
|
||||||
CGContextRef c;
|
|
||||||
CGFloat height; // needed for text; see below
|
|
||||||
};
|
|
||||||
|
|
||||||
uiDrawContext *newContext(CGContextRef ctxt, CGFloat height)
|
uiDrawContext *newContext(CGContextRef ctxt, CGFloat height)
|
||||||
{
|
{
|
||||||
uiDrawContext *c;
|
uiDrawContext *c;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// 2 january 2017
|
// 2 january 2017
|
||||||
#import "uipriv_darwin.h"
|
#import "uipriv_darwin.h"
|
||||||
|
#import "draw.h"
|
||||||
|
|
||||||
struct uiDrawTextLayout {
|
struct uiDrawTextLayout {
|
||||||
CFAttributedStringRef attrstr;
|
CFAttributedStringRef attrstr;
|
||||||
|
@ -124,9 +125,31 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *tl)
|
||||||
uiFree(tl);
|
uiFree(tl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO what is y, the top-left corner, bottom-left corner, topmost baseline, or bottommost baseline?
|
// TODO double-check helvetica
|
||||||
|
// TODO document that (x,y) is the top-left corner of the *entire frame*
|
||||||
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
void uiDrawText(uiDrawContext *c, uiDrawTextLayout *tl, double x, double y)
|
||||||
{
|
{
|
||||||
|
CGContextSaveGState(c->c);
|
||||||
|
|
||||||
|
// Core Text doesn't draw onto a flipped view correctly; we have to pretend it was unflipped
|
||||||
|
// 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)
|
||||||
|
// TODO how is this affected by a non-identity CTM?
|
||||||
|
CGContextTranslateCTM(c->c, 0, cheight);
|
||||||
|
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;
|
||||||
|
|
||||||
|
// CTFrameDraw() draws in the path we specified when creating the frame
|
||||||
|
// this means that in our usage, CTFrameDraw() will draw at (0,0)
|
||||||
|
// so move the origin to be at (x,y) instead
|
||||||
|
// TODO are the signs correct?
|
||||||
|
CGContextTranslateCTM(c->c, x, y);
|
||||||
|
|
||||||
|
CTFrameDraw(tl->frame, c->c);
|
||||||
|
|
||||||
|
CGContextRestoreGState(c->c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO document that the width and height of a layout is not necessarily the sum of the widths and heights of its constituent lines; this is definitely untrue on OS X, where lines are placed in such a way that the distance between baselines is always integral
|
// TODO document that the width and height of a layout is not necessarily the sum of the widths and heights of its constituent lines; this is definitely untrue on OS X, where lines are placed in such a way that the distance between baselines is always integral
|
||||||
|
|
Loading…
Reference in New Issue