diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-20 09:01:25 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-07-20 09:01:25 +0300 |
commit | dc1528e89d48947780e00fc1a49ce57cccdfbfe5 (patch) | |
tree | 4bd888f70dcf7bdd3ad166b43176232c42920594 /src/ui/text.c | |
parent | 3ccdfae64b82d9716de1f94f7d81de9c8765b607 (diff) |
Revising InputWidget
`InputWidget` needs to be better at handling multiple lines. The previous implementation assumed that the content was short enough to be fully redrawn each frame, which is not a great idea when you have thousands of lines.
Diffstat (limited to 'src/ui/text.c')
-rw-r--r-- | src/ui/text.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/src/ui/text.c b/src/ui/text.c index b283d700..49b3f0cd 100644 --- a/src/ui/text.c +++ b/src/ui/text.c | |||
@@ -855,18 +855,6 @@ static void finishRun_AttributedText_(iAttributedText *d, iAttributedRun *run, i | |||
855 | run->logical.start = endAt; | 855 | run->logical.start = endAt; |
856 | } | 856 | } |
857 | 857 | ||
858 | size_t length_Rangecc(const iRangecc d) { | ||
859 | size_t n = 0; | ||
860 | for (const char *i = d.start; i < d.end; ) { | ||
861 | iChar ch; | ||
862 | const int chLen = decodeBytes_MultibyteChar(i, d.end, &ch); | ||
863 | if (chLen <= 0) break; | ||
864 | i += chLen; | ||
865 | n++; | ||
866 | } | ||
867 | return n; | ||
868 | } | ||
869 | |||
870 | static enum iFontId fontId_Text_(const iFont *font) { | 858 | static enum iFontId fontId_Text_(const iFont *font) { |
871 | return (enum iFontId) (font - text_.fonts); | 859 | return (enum iFontId) (font - text_.fonts); |
872 | } | 860 | } |
@@ -1436,7 +1424,14 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1436 | int wrapResumePos = textLen; /* logical position where next line resumes */ | 1424 | int wrapResumePos = textLen; /* logical position where next line resumes */ |
1437 | size_t wrapResumeRunIndex = runCount; /* index of run where next line resumes */ | 1425 | size_t wrapResumeRunIndex = runCount; /* index of run where next line resumes */ |
1438 | const int layoutBound = (args->wrap ? args->wrap->maxWidth : 0); | 1426 | const int layoutBound = (args->wrap ? args->wrap->maxWidth : 0); |
1427 | iBool isFirst = iTrue; | ||
1439 | while (!isEmpty_Range(&wrapRuns)) { | 1428 | while (!isEmpty_Range(&wrapRuns)) { |
1429 | if (isFirst) { | ||
1430 | isFirst = iFalse; | ||
1431 | } | ||
1432 | else { | ||
1433 | yCursor += d->height; | ||
1434 | } | ||
1440 | float wrapAdvance = 0.0f; | 1435 | float wrapAdvance = 0.0f; |
1441 | /* First we need to figure out how much text fits on the current line. */ | 1436 | /* First we need to figure out how much text fits on the current line. */ |
1442 | if (args->wrap && args->wrap->maxWidth > 0) { | 1437 | if (args->wrap && args->wrap->maxWidth > 0) { |
@@ -1701,7 +1696,6 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) { | |||
1701 | wrapRuns.end = runCount; | 1696 | wrapRuns.end = runCount; |
1702 | wrapPosRange.start = wrapResumePos; | 1697 | wrapPosRange.start = wrapResumePos; |
1703 | wrapPosRange.end = textLen; | 1698 | wrapPosRange.end = textLen; |
1704 | yCursor += d->height; | ||
1705 | } | 1699 | } |
1706 | if (args->cursorAdvance_out) { | 1700 | if (args->cursorAdvance_out) { |
1707 | *args->cursorAdvance_out = init_I2(xCursor, yCursor); | 1701 | *args->cursorAdvance_out = init_I2(xCursor, yCursor); |
@@ -1962,8 +1956,9 @@ iTextMetrics measure_WrapText(iWrapText *d, int fontId) { | |||
1962 | return tm; | 1956 | return tm; |
1963 | } | 1957 | } |
1964 | 1958 | ||
1965 | void draw_WrapText(iWrapText *d, int fontId, iInt2 pos, int color) { | 1959 | iTextMetrics draw_WrapText(iWrapText *d, int fontId, iInt2 pos, int color) { |
1966 | run_Font_(font_Text_(fontId), | 1960 | iTextMetrics tm; |
1961 | tm.bounds = run_Font_(font_Text_(fontId), | ||
1967 | &(iRunArgs){ .mode = draw_RunMode | runFlagsFromId_(fontId) | | 1962 | &(iRunArgs){ .mode = draw_RunMode | runFlagsFromId_(fontId) | |
1968 | (color & permanent_ColorId ? permanentColorFlag_RunMode : 0) | | 1963 | (color & permanent_ColorId ? permanentColorFlag_RunMode : 0) | |
1969 | (color & fillBackground_ColorId ? fillBackground_RunMode : 0), | 1964 | (color & fillBackground_ColorId ? fillBackground_RunMode : 0), |
@@ -1971,7 +1966,9 @@ void draw_WrapText(iWrapText *d, int fontId, iInt2 pos, int color) { | |||
1971 | .pos = pos, | 1966 | .pos = pos, |
1972 | .wrap = d, | 1967 | .wrap = d, |
1973 | .color = color & mask_ColorId, | 1968 | .color = color & mask_ColorId, |
1969 | .cursorAdvance_out = &tm.advance, | ||
1974 | }); | 1970 | }); |
1971 | return tm; | ||
1975 | } | 1972 | } |
1976 | 1973 | ||
1977 | SDL_Texture *glyphCache_Text(void) { | 1974 | SDL_Texture *glyphCache_Text(void) { |