summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/about/version.gmi5
-rw-r--r--src/ui/documentwidget.c11
-rw-r--r--src/ui/text.c25
3 files changed, 32 insertions, 9 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index c281017f..f4842661 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -7,9 +7,10 @@
7# Release notes 7# Release notes
8 8
9## 1.3.1 9## 1.3.1
10* New UI languages: Serbian, Interlingue/Occidental. 10* Added UI languages: Serbian, Interlingue.
11* Fixed: Kerning was not applied correctly in the text renderer.
11* Fixed: Whitespace normalization in plain text files (tab characters). 12* Fixed: Whitespace normalization in plain text files (tab characters).
12* Fixed: Issues buffering window contents for reusing later. 13* Fixed: Issues buffering window contents, possibly causing missing font glyphs.
13 14
14## 1.3 15## 1.3
15 16
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 0c7ebd54..733ed543 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -2497,6 +2497,17 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
2497 break; 2497 break;
2498 } 2498 }
2499#endif 2499#endif
2500#if 0
2501 case '0': {
2502 extern int enableKerning_Text;
2503 enableKerning_Text = !enableKerning_Text;
2504 invalidate_DocumentWidget_(d);
2505 refresh_Widget(w);
2506 printf("kerning: %d\n", enableKerning_Text);
2507 fflush(stdout);
2508 break;
2509 }
2510#endif
2500 } 2511 }
2501 } 2512 }
2502 else if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { 2513 else if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) {
diff --git a/src/ui/text.c b/src/ui/text.c
index 6af7d6d1..83073d1f 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -72,7 +72,7 @@ struct Impl_Glyph {
72 iHashNode node; 72 iHashNode node;
73 int flags; 73 int flags;
74 uint32_t glyphIndex; 74 uint32_t glyphIndex;
75 const iFont *font; /* may come from symbols/emoji */ 75 iFont *font; /* may come from symbols/emoji */
76 iRect rect[2]; /* zero and half pixel offset */ 76 iRect rect[2]; /* zero and half pixel offset */
77 iInt2 d[2]; 77 iInt2 d[2];
78 float advance; /* scaled */ 78 float advance; /* scaled */
@@ -179,6 +179,7 @@ static void deinit_Font(iFont *d) {
179} 179}
180 180
181static uint32_t glyphIndex_Font_(iFont *d, iChar ch) { 181static uint32_t glyphIndex_Font_(iFont *d, iChar ch) {
182 /* TODO: Add a small cache of ~5 most recently found indices. */
182 const size_t entry = ch - 32; 183 const size_t entry = ch - 32;
183 if (entry < iElemCount(d->indexTable)) { 184 if (entry < iElemCount(d->indexTable)) {
184 if (d->indexTable[entry] == ~0u) { 185 if (d->indexTable[entry] == ~0u) {
@@ -1098,11 +1099,6 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1098 if (!isSpace_Char(ch)) { 1099 if (!isSpace_Char(ch)) {
1099 xposExtend += isEmoji ? glyph->advance : advance; 1100 xposExtend += isEmoji ? glyph->advance : advance;
1100 } 1101 }
1101 xposExtend = iMax(xposExtend, xpos);
1102 xposMax = iMax(xposMax, xposExtend);
1103 if (args->continueFrom_out && ((mode & noWrapFlag_RunMode) || isWrapBoundary_(prevCh, ch))) {
1104 lastWordEnd = currentPos; /* mark word wrap position */
1105 }
1106#if defined (LAGRANGE_ENABLE_KERNING) 1102#if defined (LAGRANGE_ENABLE_KERNING)
1107 /* Check the next character. */ 1103 /* Check the next character. */
1108 if (!isMonospaced && glyph->font == d) { 1104 if (!isMonospaced && glyph->font == d) {
@@ -1110,10 +1106,24 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1110 const char *peek = chPos; 1106 const char *peek = chPos;
1111 const iChar next = nextChar_(&peek, args->text.end); 1107 const iChar next = nextChar_(&peek, args->text.end);
1112 if (enableKerning_Text && !d->manualKernOnly && next) { 1108 if (enableKerning_Text && !d->manualKernOnly && next) {
1113 xpos += d->xScale * stbtt_GetGlyphKernAdvance(&d->font, glyph->glyphIndex, next); 1109 const uint32_t nextGlyphIndex = glyphIndex_Font_(glyph->font, next);
1110 const int kern = stbtt_GetGlyphKernAdvance(
1111 &glyph->font->font, glyph->glyphIndex, nextGlyphIndex);
1112 if (kern) {
1113// printf("%lc(%u) -> %lc(%u): kern %d (%f)\n", ch, glyph->glyphIndex, next,
1114// nextGlyphIndex,
1115// kern, d->xScale * kern);
1116 xpos += d->xScale * kern;
1117 xposExtend += d->xScale * kern;
1118 }
1114 } 1119 }
1115 } 1120 }
1116#endif 1121#endif
1122 xposExtend = iMax(xposExtend, xpos);
1123 xposMax = iMax(xposMax, xposExtend);
1124 if (args->continueFrom_out && ((mode & noWrapFlag_RunMode) || isWrapBoundary_(prevCh, ch))) {
1125 lastWordEnd = currentPos; /* mark word wrap position */
1126 }
1117 prevCh = ch; 1127 prevCh = ch;
1118 if (--maxLen == 0) { 1128 if (--maxLen == 0) {
1119 break; 1129 break;
@@ -1122,6 +1132,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1122 if (args->runAdvance_out) { 1132 if (args->runAdvance_out) {
1123 *args->runAdvance_out = xposMax - orig.x; 1133 *args->runAdvance_out = xposMax - orig.x;
1124 } 1134 }
1135 fflush(stdout);
1125 return bounds; 1136 return bounds;
1126} 1137}
1127 1138