diff --git a/darwin/drawtext.m b/darwin/drawtext.m index fd7cc7b3..df5cea89 100644 --- a/darwin/drawtext.m +++ b/darwin/drawtext.m @@ -431,6 +431,7 @@ void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metri struct uiDrawTextLayout { CFMutableAttributedStringRef mas; intmax_t *bytesToCharacters; + double width; }; // TODO this is *really* iffy, but we need to know character offsets... @@ -482,7 +483,7 @@ static intmax_t *strToCFStrOffsetList(const char *str, CFMutableStringRef *cfstr return bytesToCharacters; } -uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFont) +uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFont, double width) { uiDrawTextLayout *layout; CFMutableStringRef cfstr; @@ -508,6 +509,8 @@ uiDrawTextLayout *uiDrawNewTextLayout(const char *str, uiDrawTextFont *defaultFo complain("error creating attributed string in uiDrawNewTextLayout()"); CFRelease(immutable); + uiDrawTextLayoutSetWidth(layout, width); + return layout; } @@ -518,6 +521,32 @@ void uiDrawFreeTextLayout(uiDrawTextLayout *layout) uiFree(layout); } +void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width) +{ + layout->width = width; +} + +void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height) +{ + CTLineRef line; + double ascent, descent; + double w; + + // one line + if (layout->width < 0) { + line = CTLineCreateWithAttributedString(layout->mas); + if (line == NULL) + complain("error creating CTLine object in uiDrawTextLayoutExtents()"); + w = CTLineGetTypographicBounds(line, &ascent, &descent, NULL); + // though CTLineGetTypographicBounds() returns 0 on error, it also returns 0 on an empty string, so we can't reasonably check for error + CFRelease(line); + *width = w; + *height = ascent + descent; + return; + } + // TODO +} + // 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? @@ -532,12 +561,15 @@ static void prepareContextForText(CGContextRef c, CGFloat cheight, double *y) *y = cheight - *y; } -// TODO how does this behave with multiple lines? on other platforms? is there a generic way to draw this unbounded? void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextLayout *layout) { CTLineRef line; CGFloat yoff; + // TODO + if (layout->width < 0) {} + else return; + prepareContextForText(c, cheight, &y); line = CTLineCreateWithAttributedString(layout->mas); @@ -546,7 +578,6 @@ void doDrawText(CGContextRef c, CGFloat cheight, double x, double y, uiDrawTextL // CGContextSetTextPosition() positions at the baseline; we need the top-left corner instead CTLineGetTypographicBounds(line, &yoff, NULL, NULL); - // though CTLineGetTypographicBounds() returns 0 on error, it also returns 0 on an empty string, so we can't reasonably check for error // remember that we're flipped, so we subtract y -= yoff; CGContextSetTextPosition(c, x, y); diff --git a/test/page9.c b/test/page9.c index e24f9215..1fda634e 100644 --- a/test/page9.c +++ b/test/page9.c @@ -116,7 +116,7 @@ static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *dp) ypos = 10; uiDrawText(dp->Context, 10, ypos, layout); // TODO make these optional? - uiDrawTextLayoutExtents(dp->Context, &width, &height); + uiDrawTextLayoutExtents(layout, &width, &height); uiDrawFreeTextLayout(layout); layout = uiDrawNewTextLayout("This is a second line", font, -1); @@ -239,6 +239,10 @@ uiBox *makePage9(void) uiComboboxSetSelected(textGravity, uiDrawTextGravitySouth); uiBoxAppend(hbox, uiControl(textGravity), 1); + textWidth = uiNewEntry(); + uiEntrySetText(textWidth, "-1"); + uiBoxAppend(hbox, uiControl(textWidth), 1); + hbox = newHorizontalBox(); uiBoxAppend(vbox, uiControl(hbox), 0);