From 49d36b340c4ece8e9cf5dd1b073bbf98a4e0eb2c Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 10 Feb 2017 10:54:37 -0500 Subject: [PATCH] Started adjusting all the implementations to the new API's formal definition. There's bugs in uiAttributedString... --- darwin/drawtext.m | 20 +++++++++++++++----- examples/drawtext/hittest.c | 7 +------ ui_attrstr.h | 27 +-------------------------- 3 files changed, 17 insertions(+), 37 deletions(-) diff --git a/darwin/drawtext.m b/darwin/drawtext.m index 53763ce3..82b99ac3 100644 --- a/darwin/drawtext.m +++ b/darwin/drawtext.m @@ -421,10 +421,20 @@ void uiDrawTextLayoutHitTest(uiDrawTextLayout *tl, double x, double y, size_t *p double uiDrawTextLayoutByteLocationInLine(uiDrawTextLayout *tl, size_t pos, int line) { - CTLineRef ln; + CTLineRef lr; + CFRange range; - ln = (CTLineRef) CFArrayGetValueAtIndex(tl->lines, line); - // TODO what happens if the byte location is not in this line? a return of 0? - // TODO check return? see if this can return 0, anyway, and if so make a note I guess - return CTLineGetOffsetForStringIndex(ln, tl->u8tou16[pos], NULL); +printf("= %zd %zd ", pos, tl->nUTF8); + pos = tl->u8tou16[pos]; +printf("-> %zd %zd\n", pos, tl->nUTF16); + if (line < 0 || line >= tl->nLines) + return -1; + lr = (CTLineRef) CFArrayGetValueAtIndex(tl->lines, line); + range = CTLineGetStringRange(lr); + // note: >, not >=, because the position at end is valid! +printf("%zd %zd\n", pos, (size_t)(range.location+range.length)); + if (pos < range.location || pos > (range.location + range.length)) + return -1; + // no point in checking the return; we already validated everything and 0 is a valid return for the first index :/ + return CTLineGetOffsetForStringIndex(lr, pos, NULL); } diff --git a/examples/drawtext/hittest.c b/examples/drawtext/hittest.c index f655fb74..0ae2df5d 100644 --- a/examples/drawtext/hittest.c +++ b/examples/drawtext/hittest.c @@ -113,6 +113,7 @@ static void draw(uiAreaDrawParams *p) } caretX = uiDrawTextLayoutByteLocationInLine(layout, caretPos, caretLine); +printf("%g\n", caretX); uiDrawTextLayoutLineGetMetrics(layout, caretLine, &m); path = uiDrawNewPath(uiDrawFillModeWinding); uiDrawPathNewFigure(path, margins + caretX, margins + m.Y); @@ -146,12 +147,6 @@ static void draw(uiAreaDrawParams *p) uiDrawFreeTextLayout(layout); } -static const char *positions[] = { - [uiDrawTextLayoutHitTestPositionBefore] = "before", - [uiDrawTextLayoutHitTestPositionInside] = "inside", - [uiDrawTextLayoutHitTestPositionAfter] = "after", -}; - static void mouse(uiAreaMouseEvent *e) { uiDrawTextLayout *layout; diff --git a/ui_attrstr.h b/ui_attrstr.h index c2ded0d0..a6e7f896 100644 --- a/ui_attrstr.h +++ b/ui_attrstr.h @@ -87,8 +87,6 @@ struct uiDrawFontDescriptor { typedef struct uiDrawTextLayout uiDrawTextLayout; typedef struct uiDrawTextLayoutLineMetrics uiDrawTextLayoutLineMetrics; -typedef struct uiDrawTextLayoutHitTestResult uiDrawTextLayoutHitTestResult; -typedef struct uiDrawTextLayoutByteRangeRectangle uiDrawTextLayoutByteRangeRectangle; struct uiDrawTextLayoutLineMetrics { // This describes the overall bounding box of the line. @@ -121,30 +119,6 @@ struct uiDrawTextLayoutLineMetrics { // TODO trailing whitespace? }; -struct uiDrawTextLayoutHitTestResult { - // The byte position of the character at the given point. - size_t Pos; - // Line is the line at the given point. If the point is on the space - // after the end of a line, Pos will be Line's end index. In this case, - // the rectangle for that character will actually be on the *next* - // line. This disparity is only relevant for caret positioning when - // using the mouse; in that case, to ensure proper behavior, use - // the Caret fields below. In all other cases (including keyboard - // caret movement), use the actual rectangle for the grapheme - // at Pos (via uiDrawTextLayoutByteRangeToRectangle()). - int Line; - uiDrawTextLayoutHitTestPosition XPosition; - uiDrawTextLayoutHitTestPosition YPosition; - -// TODO? -// int InTrailingWhitespace; -// TODO? -// double XFraction; -// extra TODO? -// double YFraction; -// or just have offsets instead? in addition? -}; - // TODO // - allow creating a layout out of a substring // - allow marking compositon strings @@ -185,4 +159,5 @@ _UI_EXTERN void uiDrawTextLayoutHitTest(uiDrawTextLayout *tl, double x, double y // the correct offset, even if pos is at the end of the line. If pos is not // in the range [start, end], a negative value will be returned, // indicating you need to move the cursor to another line. +// TODO make sure this works right for right-aligned and center-aligned lines and justified lines and RTL text _UI_EXTERN double uiDrawTextLayoutByteLocationInLine(uiDrawTextLayout *tl, size_t pos, int line);