summaryrefslogtreecommitdiff
path: root/src/ui/text.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-08-24 14:35:14 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-08-24 14:35:14 +0300
commiteb732a09382d14aeac2fa17646d09a1f15bb2da3 (patch)
treea01f5d9541ecccb7c381de3a15ce3545a2ecc714 /src/ui/text.c
parentb181150bad024e35a85386085efb096abd7d6901 (diff)
Text: Character hit test vs. clusters
When multiple codepoints are in the same cluster, the hit test should only consider the first codepoint of the cluster, or otherwise the cursor is positioned somewhere in the middle of the cluster and not at the start.
Diffstat (limited to 'src/ui/text.c')
-rw-r--r--src/ui/text.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index a499d293..006a4d0b 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -1433,7 +1433,6 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1433 iBool isFirst = iTrue; 1433 iBool isFirst = iTrue;
1434 const iBool checkHitPoint = wrap && !isEqual_I2(wrap->hitPoint, zero_I2()); 1434 const iBool checkHitPoint = wrap && !isEqual_I2(wrap->hitPoint, zero_I2());
1435 const iBool checkHitChar = wrap && wrap->hitChar; 1435 const iBool checkHitChar = wrap && wrap->hitChar;
1436 //iBool wasCharHit = iFalse;
1437 while (!isEmpty_Range(&wrapRuns)) { 1436 while (!isEmpty_Range(&wrapRuns)) {
1438 if (isFirst) { 1437 if (isFirst) {
1439 isFirst = iFalse; 1438 isFirst = iFalse;
@@ -1447,15 +1446,16 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1447 if (wrap && (wrap->maxWidth > 0 || checkHitPoint)) { 1446 if (wrap && (wrap->maxWidth > 0 || checkHitPoint)) {
1448 const iBool isHitPointOnThisLine = (checkHitPoint && wrap->hitPoint.y >= orig.y + yCursor && 1447 const iBool isHitPointOnThisLine = (checkHitPoint && wrap->hitPoint.y >= orig.y + yCursor &&
1449 wrap->hitPoint.y < orig.y + yCursor + d->height); 1448 wrap->hitPoint.y < orig.y + yCursor + d->height);
1449 iBool wasCharHit = iFalse; /* on this line */
1450 float breakAdvance = -1.0f; 1450 float breakAdvance = -1.0f;
1451 iAssert(wrapPosRange.end == textLen); 1451 iAssert(wrapPosRange.end == textLen);
1452 /* Determine ends of wrapRuns and wrapVisRange. */ 1452 /* Determine ends of wrapRuns and wrapVisRange. */
1453 for (size_t runIndex = wrapRuns.start; runIndex < wrapRuns.end; runIndex++) { 1453 for (size_t runIndex = wrapRuns.start; runIndex < wrapRuns.end; runIndex++) {
1454 const iAttributedRun *run = at_Array(&attrText.runs, runIndex); 1454 const iAttributedRun *run = at_Array(&attrText.runs, runIndex);
1455 if (run->flags.isLineBreak) { 1455 if (run->flags.isLineBreak) {
1456 if (checkHitChar && wrap->hitChar == sourcePtr_AttributedText_(&attrText, run->logical.start)) { 1456 if (checkHitChar &&
1457 wrap->hitChar == sourcePtr_AttributedText_(&attrText, run->logical.start)) {
1457 wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); 1458 wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor);
1458// wasCharHit = iTrue;
1459 } 1459 }
1460 wrapPosRange.end = run->logical.start; 1460 wrapPosRange.end = run->logical.start;
1461 wrapResumePos = run->logical.end; 1461 wrapResumePos = run->logical.end;
@@ -1479,9 +1479,10 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1479 if (logPos < wrapPosRange.start || logPos >= wrapPosRange.end) { 1479 if (logPos < wrapPosRange.start || logPos >= wrapPosRange.end) {
1480 continue; 1480 continue;
1481 } 1481 }
1482 if (checkHitChar && wrap->hitChar == sourcePtr_AttributedText_(&attrText, logPos)) { 1482 if (checkHitChar && !wasCharHit &&
1483 wrap->hitChar == sourcePtr_AttributedText_(&attrText, logPos)) {
1483 wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor); 1484 wrap->hitAdvance_out = init_I2(wrapAdvance, yCursor);
1484 //wasCharHit = iTrue; 1485 wasCharHit = iTrue; /* variation selectors etc. have matching cluster */
1485 } 1486 }
1486 /* Check if the hit point is on the left side of this line. */ 1487 /* Check if the hit point is on the left side of this line. */
1487 if (isHitPointOnThisLine && !wrap->hitChar_out && wrap->hitPoint.x < orig.x) { 1488 if (isHitPointOnThisLine && !wrap->hitChar_out && wrap->hitPoint.x < orig.x) {