diff --git a/darwin/drawtext.m b/darwin/drawtext.m index f3c8e518..218c06d4 100644 --- a/darwin/drawtext.m +++ b/darwin/drawtext.m @@ -349,7 +349,8 @@ void uiDrawTextLayoutByteRangeToRectangle(uiDrawTextLayout *tl, size_t start, si for (i = 0; i < tl->nLines; i++) { line = (CTLineRef) CFArrayGetValueAtIndex(tl->lines, i); range = CTLineGetStringRange(line); - if (start >= range.location) + // TODO explain this check + if (range.location >= start) break; } if (i == tl->nLines) diff --git a/examples/drawtext/hittest.c b/examples/drawtext/hittest.c index dc1f9dce..554e4a8e 100644 --- a/examples/drawtext/hittest.c +++ b/examples/drawtext/hittest.c @@ -4,6 +4,7 @@ static const char *text = "Each of the glyphs an end user interacts with are called graphemes. " "If you enter a byte range in the text boxes below and click the button, you can see the blue box move to surround that byte range, as well as what the actual byte range necessary is. " + // TODO rephrase this; I don't think this code will use those grapheme functions... "You'll also see the index of the first grapheme; uiAttributedString has facilities for converting between UTF-8 code points and grapheme indices. " "Additionally, click on the string to move the caret. Watch the status text at the bottom change too. " "That being said: " @@ -28,6 +29,8 @@ static uiAttributedString *attrstr; static uiBox *panel; static uiCheckbox *showLineBounds; +static size_t cursorPos; + // TODO should be const? static uiDrawBrush fillBrushes[4] = { { @@ -60,10 +63,23 @@ static uiDrawBrush fillBrushes[4] = { }, }; +// TODO this should be const +static uiDrawStrokeParams strokeParams = { + .Cap = uiDrawLineCapFlat, + .Join = uiDrawLineJoinMiter, + .Thickness = 2, + .MiterLimit = uiDrawDefaultMiterLimit, + .Dashes = NULL, + .NumDashes = 0, + .DashPhase = 0, +}; + static void draw(uiAreaDrawParams *p) { uiDrawPath *path; uiDrawTextLayout *layout; + uiDrawTextLayoutByteRangeRectangle r; + uiDrawBrush brush; // only clip the text, not the guides uiDrawSave(p->Context); @@ -83,6 +99,19 @@ static void draw(uiAreaDrawParams *p) uiDrawRestore(p->Context); + uiDrawTextLayoutByteRangeToRectangle(layout, cursorPos, cursorPos, &r); + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathNewFigure(path, margins + r.X, margins + r.Y); + uiDrawPathLineTo(path, margins + r.X, margins + r.Y + r.Height); + uiDrawPathEnd(path); + brush.Type = uiDrawBrushTypeSolid; + brush.R = 0.0; + brush.G = 0.0; + brush.B = 1.0; + brush.A = 1.0; + uiDrawStroke(p->Context, path, &brush, &strokeParams); + uiDrawFreePath(path); + if (uiCheckboxChecked(showLineBounds)) { uiDrawTextLayoutLineMetrics m; int i, n; @@ -132,6 +161,7 @@ struct example *mkHitTestExample(void) hitTestExample.draw = draw; attrstr = uiNewAttributedString(text); + cursorPos = uiAttributedStringLen(attrstr); return &hitTestExample; }