diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index fdace350..8ecff8b3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -6,6 +6,7 @@ list(APPEND _LIBUI_SOURCES common/areaevents.c common/control.c common/debug.c + common/drawtext.c common/matrix.c common/shouldquit.c common/userbugs.c diff --git a/common/drawtext.c b/common/drawtext.c new file mode 100644 index 00000000..41aadb2e --- /dev/null +++ b/common/drawtext.c @@ -0,0 +1,53 @@ +// 10 february 2017 +#include "../ui.h" +#include "uipriv.h" + +void uiDrawCaret(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout, size_t pos, int *line) +{ + double xoff; + uiDrawTextLayoutLineMetrics m; + struct caretDrawParams cdp; + uiDrawPath *path; + uiDrawBrush brush; + + caretDrawParams(c, &cdp); + + xoff = uiDrawTextLayoutByteLocationInLine(layout, pos, *line); + if (xoff < 0) { + size_t start, end; + int incr; + + if (*line > (uiDrawTextLayoutNumLines(layout) - 1)) { + *line = (uiDrawTextLayoutNumLines(layout) - 1); + incr = -1; + } else { + uiDrawTextLayoutLineByteRange(layout, *line, &start, &end); + incr = 1; + if (end < pos) + incr = -1; + } + while (xoff < 0) { + *line += incr; + xoff = uiDrawTextLayoutByteLocationInLine(layout, pos, *line); + } + } + uiDrawTextLayoutLineGetMetrics(layout, *line, &m); + + uiDrawSave(c); + + path = uiDrawNewPath(uiDrawFillModeWinding); + uiDrawPathAddRectangle(path, + // TODO add m.X? + x + xoff, y + m.Y, + cdp.width, m.Height); + uiDrawPathEnd(path); + brush.Type = uiDrawBrushTypeSolid; + brush.R = cdp.r; + brush.G = cdp.g; + brush.B = cdp.b; + brush.A = cdp.a; + uiDrawFill(c, path, &brush); + uiDrawFreePath(path); + + uiDrawRestore(c); +} diff --git a/common/uipriv.h b/common/uipriv.h index 0ad18c14..64954c38 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -89,6 +89,16 @@ extern void attrlistForEach(struct attrlist *alist, uiAttributedString *s, uiAtt extern struct attrlist *attrlistNew(void); extern void attrlistFree(struct attrlist *alist); +// drawtext.c +struct caretDrawParams { + double r; + double g; + double b; + double a; + double width; +}; +extern void caretDrawParams(uiDrawContext *c, struct caretDrawParams *p); + #ifdef __cplusplus } #endif diff --git a/ui_attrstr.h b/ui_attrstr.h index a6e7f896..6254fb02 100644 --- a/ui_attrstr.h +++ b/ui_attrstr.h @@ -161,3 +161,5 @@ _UI_EXTERN void uiDrawTextLayoutHitTest(uiDrawTextLayout *tl, double x, double y // 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); + +_UI_EXTERN void uiDrawCaret(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout, size_t pos, int *line);