summaryrefslogtreecommitdiff
path: root/src/ui/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/text.c')
-rw-r--r--src/ui/text.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/src/ui/text.c b/src/ui/text.c
index e1638368..03ce46c7 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -792,7 +792,8 @@ struct Impl_AttributedRun {
792}; 792};
793 793
794iDeclareType(AttributedText) 794iDeclareType(AttributedText)
795iDeclareTypeConstructionArgs(AttributedText, iRangecc text, size_t maxLen, iFont *font, iColor fgColor) 795iDeclareTypeConstructionArgs(AttributedText, iRangecc text, size_t maxLen, iFont *font,
796 iColor fgColor, int baseDir)
796 797
797struct Impl_AttributedText { 798struct Impl_AttributedText {
798 iRangecc source; /* original source text */ 799 iRangecc source; /* original source text */
@@ -809,8 +810,9 @@ struct Impl_AttributedText {
809 iBool isBaseRTL; 810 iBool isBaseRTL;
810}; 811};
811 812
812iDefineTypeConstructionArgs(AttributedText, (iRangecc text, size_t maxLen, iFont *font, iColor fgColor), 813iDefineTypeConstructionArgs(AttributedText,
813 text, maxLen, font, fgColor) 814 (iRangecc text, size_t maxLen, iFont *font, iColor fgColor, int baseDir),
815 text, maxLen, font, fgColor, baseDir)
814 816
815static const char *sourcePtr_AttributedText_(const iAttributedText *d, int logicalPos) { 817static const char *sourcePtr_AttributedText_(const iAttributedText *d, int logicalPos) {
816 const int *logToSource = constData_Array(&d->logicalToSourceOffset); 818 const int *logToSource = constData_Array(&d->logicalToSourceOffset);
@@ -867,7 +869,7 @@ static enum iFontId fontId_Text_(const iFont *font) {
867 return (enum iFontId) (font - text_.fonts); 869 return (enum iFontId) (font - text_.fonts);
868} 870}
869 871
870static void prepare_AttributedText_(iAttributedText *d) { 872static void prepare_AttributedText_(iAttributedText *d, int overrideBaseDir) {
871 iAssert(isEmpty_Array(&d->runs)); 873 iAssert(isEmpty_Array(&d->runs));
872 size_t length = 0; 874 size_t length = 0;
873 /* Prepare the UTF-32 logical string. */ { 875 /* Prepare the UTF-32 logical string. */ {
@@ -896,7 +898,7 @@ static void prepare_AttributedText_(iAttributedText *d) {
896 data_Array(&d->logicalToVisual), 898 data_Array(&d->logicalToVisual),
897 data_Array(&d->visualToLogical), 899 data_Array(&d->visualToLogical),
898 (FriBidiLevel *) d->bidiLevels); 900 (FriBidiLevel *) d->bidiLevels);
899 d->isBaseRTL = FRIBIDI_IS_RTL(baseDir); 901 d->isBaseRTL = (overrideBaseDir == 0 ? FRIBIDI_IS_RTL(baseDir) : (overrideBaseDir < 0));
900#endif 902#endif
901 } 903 }
902 /* The mapping needs to include the terminating NULL position. */ { 904 /* The mapping needs to include the terminating NULL position. */ {
@@ -1017,7 +1019,8 @@ static void prepare_AttributedText_(iAttributedText *d) {
1017#endif 1019#endif
1018} 1020}
1019 1021
1020void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont *font, iColor fgColor) { 1022void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont *font, iColor fgColor,
1023 int baseDir) {
1021 d->source = text; 1024 d->source = text;
1022 d->maxLen = maxLen ? maxLen : iInvalidSize; 1025 d->maxLen = maxLen ? maxLen : iInvalidSize;
1023 d->font = font; 1026 d->font = font;
@@ -1030,7 +1033,7 @@ void init_AttributedText(iAttributedText *d, iRangecc text, size_t maxLen, iFont
1030 init_Array(&d->logicalToSourceOffset, sizeof(int)); 1033 init_Array(&d->logicalToSourceOffset, sizeof(int));
1031 d->bidiLevels = NULL; 1034 d->bidiLevels = NULL;
1032 d->isBaseRTL = iFalse; 1035 d->isBaseRTL = iFalse;
1033 prepare_AttributedText_(d); 1036 prepare_AttributedText_(d, baseDir);
1034} 1037}
1035 1038
1036void deinit_AttributedText(iAttributedText *d) { 1039void deinit_AttributedText(iAttributedText *d) {
@@ -1181,7 +1184,7 @@ static void cacheTextGlyphs_Font_(iFont *d, const iRangecc text) {
1181 iArray glyphIndices; 1184 iArray glyphIndices;
1182 init_Array(&glyphIndices, sizeof(uint32_t)); 1185 init_Array(&glyphIndices, sizeof(uint32_t));
1183 iAttributedText attrText; 1186 iAttributedText attrText;
1184 init_AttributedText(&attrText, text, 0, d, (iColor){}); 1187 init_AttributedText(&attrText, text, 0, d, (iColor){}, 0);
1185 /* We use AttributedText here so the font lookup matches the behavior during text drawing -- 1188 /* We use AttributedText here so the font lookup matches the behavior during text drawing --
1186 glyphs may be selected from a font that's different than `d`. */ 1189 glyphs may be selected from a font that's different than `d`. */
1187 const iChar *logicalText = constData_Array(&attrText.logical); 1190 const iChar *logicalText = constData_Array(&attrText.logical);
@@ -1229,9 +1232,10 @@ struct Impl_RunArgs {
1229 size_t maxLen; /* max characters to process */ 1232 size_t maxLen; /* max characters to process */
1230 iInt2 pos; 1233 iInt2 pos;
1231 iWrapText * wrap; 1234 iWrapText * wrap;
1232 int xposLimit; /* hard limit for wrapping */ 1235 int xposLimit; /* hard limit for wrapping */
1233 int xposLayoutBound; /* visible bound for layout purposes; does not affect wrapping */ 1236 int xposLayoutBound; /* visible bound for layout purposes; does not affect wrapping */
1234 int color; 1237 int color;
1238 int baseDir;
1235 /* TODO: Cleanup using TextMetrics 1239 /* TODO: Cleanup using TextMetrics
1236 Use TextMetrics output pointer instead of return value & cursorAdvance_out. */ 1240 Use TextMetrics output pointer instead of return value & cursorAdvance_out. */
1237 iInt2 * cursorAdvance_out; 1241 iInt2 * cursorAdvance_out;
@@ -1239,13 +1243,13 @@ struct Impl_RunArgs {
1239 int * runAdvance_out; 1243 int * runAdvance_out;
1240}; 1244};
1241 1245
1242static iBool notify_WrapText_(iWrapText *d, const char *ending, int origin, int advance) { 1246static iBool notify_WrapText_(iWrapText *d, const char *ending, int origin, int advance, iBool isBaseRTL) {
1243 if (d && d->wrapFunc && d->wrapRange_.start) { 1247 if (d && d->wrapFunc && d->wrapRange_.start) {
1244 /* `wrapRange_` uses logical indices. */ 1248 /* `wrapRange_` uses logical indices. */
1245 const char *end = ending ? ending : d->wrapRange_.end; 1249 const char *end = ending ? ending : d->wrapRange_.end;
1246 iRangecc range = { d->wrapRange_.start, end }; 1250 iRangecc range = { d->wrapRange_.start, end };
1247 iAssert(range.start <= range.end); 1251 iAssert(range.start <= range.end);
1248 const iBool result = d->wrapFunc(d, range, origin, advance); 1252 const iBool result = d->wrapFunc(d, range, origin, advance, isBaseRTL);
1249 if (result) { 1253 if (result) {
1250 d->wrapRange_.start = end; 1254 d->wrapRange_.start = end;
1251 } 1255 }
@@ -1380,7 +1384,8 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1380 font is used and other attributes such as color. (HarfBuzz shaping is done 1384 font is used and other attributes such as color. (HarfBuzz shaping is done
1381 with one specific font.) */ 1385 with one specific font.) */
1382 iAttributedText attrText; 1386 iAttributedText attrText;
1383 init_AttributedText(&attrText, args->text, args->maxLen, d, get_Color(args->color)); 1387 init_AttributedText(&attrText, args->text, args->maxLen, d, get_Color(args->color),
1388 args->baseDir);
1384 if (args->wrap) { 1389 if (args->wrap) {
1385 /* TODO: Duplicated args? */ 1390 /* TODO: Duplicated args? */
1386 iAssert(equalRange_Rangecc(args->wrap->text, args->text)); 1391 iAssert(equalRange_Rangecc(args->wrap->text, args->text));
@@ -1390,7 +1395,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1390 const iChar *logicalText = constData_Array(&attrText.logical); 1395 const iChar *logicalText = constData_Array(&attrText.logical);
1391 const iChar *visualText = constData_Array(&attrText.visual); 1396 const iChar *visualText = constData_Array(&attrText.visual);
1392 const int * logToVis = constData_Array(&attrText.logicalToVisual); 1397 const int * logToVis = constData_Array(&attrText.logicalToVisual);
1393 const int * visToLog = constData_Array(&attrText.visualToLogical); 1398// const int * visToLog = constData_Array(&attrText.visualToLogical);
1394 const size_t runCount = size_Array(&attrText.runs); 1399 const size_t runCount = size_Array(&attrText.runs);
1395 iArray buffers; 1400 iArray buffers;
1396 init_Array(&buffers, sizeof(iGlyphBuffer)); 1401 init_Array(&buffers, sizeof(iGlyphBuffer));
@@ -1580,7 +1585,8 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1580 if (!notify_WrapText_(args->wrap, 1585 if (!notify_WrapText_(args->wrap,
1581 sourcePtr_AttributedText_(&attrText, wrapResumePos), 1586 sourcePtr_AttributedText_(&attrText, wrapResumePos),
1582 origin, 1587 origin,
1583 iRound(wrapAdvance))) { 1588 iRound(wrapAdvance),
1589 attrText.isBaseRTL)) {
1584 willAbortDueToWrap = iTrue; 1590 willAbortDueToWrap = iTrue;
1585 } 1591 }
1586 xCursor = origin; 1592 xCursor = origin;
@@ -1743,8 +1749,9 @@ static int runFlagsFromId_(enum iFontId fontId) {
1743 return runFlags; 1749 return runFlags;
1744} 1750}
1745 1751
1746static iBool cbAdvanceOneLine_(iWrapText *d, iRangecc range, int origin, int advance) { 1752static iBool cbAdvanceOneLine_(iWrapText *d, iRangecc range, int origin, int advance,
1747 iUnused(origin, advance); 1753 iBool isBaseRTL) {
1754 iUnused(origin, advance, isBaseRTL);
1748 *((const char **) d->context) = range.end; 1755 *((const char **) d->context) = range.end;
1749 return iFalse; /* just one line */ 1756 return iFalse; /* just one line */
1750} 1757}
@@ -1785,9 +1792,9 @@ iTextMetrics measureN_Text(int fontId, const char *text, size_t n) {
1785} 1792}
1786 1793
1787static void drawBoundedN_Text_(int fontId, iInt2 pos, int xposBound, int color, iRangecc text, size_t maxLen) { 1794static void drawBoundedN_Text_(int fontId, iInt2 pos, int xposBound, int color, iRangecc text, size_t maxLen) {
1788 iText *d = &text_; 1795 iText * d = &text_;
1789 iFont *font = font_Text_(fontId); 1796 iFont * font = font_Text_(fontId);
1790 const iColor clr = get_Color(color & mask_ColorId); 1797 const iColor clr = get_Color(color & mask_ColorId);
1791 SDL_SetTextureColorMod(d->cache, clr.r, clr.g, clr.b); 1798 SDL_SetTextureColorMod(d->cache, clr.r, clr.g, clr.b);
1792 run_Font_(font, 1799 run_Font_(font,
1793 &(iRunArgs){ .mode = draw_RunMode | 1800 &(iRunArgs){ .mode = draw_RunMode |
@@ -1798,7 +1805,8 @@ static void drawBoundedN_Text_(int fontId, iInt2 pos, int xposBound, int color,
1798 .maxLen = maxLen, 1805 .maxLen = maxLen,
1799 .pos = pos, 1806 .pos = pos,
1800 .xposLayoutBound = xposBound, 1807 .xposLayoutBound = xposBound,
1801 .color = color & mask_ColorId }); 1808 .color = color & mask_ColorId,
1809 .baseDir = xposBound ? iSign(xposBound - pos.x) : 0 });
1802} 1810}
1803 1811
1804static void drawBounded_Text_(int fontId, iInt2 pos, int xposBound, int color, iRangecc text) { 1812static void drawBounded_Text_(int fontId, iInt2 pos, int xposBound, int color, iRangecc text) {