summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-17 21:31:48 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-17 21:31:48 +0200
commit3c95b7e2aed7a405e71d954082ba7d1223a676bf (patch)
treea42bac2459825ea5c536385f2544e1376ed7a9a2
parent3cb3af524117fc91afd5f0f878d9978d27048344 (diff)
TextBuf: Support for color
Fill glyph backgrounds individually based on current color.
-rw-r--r--src/ui/color.h3
-rw-r--r--src/ui/text.c33
-rw-r--r--src/ui/text.h2
3 files changed, 29 insertions, 9 deletions
diff --git a/src/ui/color.h b/src/ui/color.h
index a4a7b93e..057ca42d 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -179,7 +179,8 @@ iLocalDef iBool isRegularText_ColorId(enum iColorId d) {
179} 179}
180 180
181#define mask_ColorId 0x7f 181#define mask_ColorId 0x7f
182#define permanent_ColorId 0x80 /* cannot be changed via escapes */ 182#define permanent_ColorId 0x80 /* cannot be changed via escapes */
183#define fillBackground_ColorId 0x100 /* fill background with same color, but alpha 0 */
183 184
184#define asciiBase_ColorEscape 33 185#define asciiBase_ColorEscape 33
185#define asciiExtended_ColorEscape (128 - asciiBase_ColorEscape) 186#define asciiExtended_ColorEscape (128 - asciiBase_ColorEscape)
diff --git a/src/ui/text.c b/src/ui/text.c
index 6642b9ef..5163d14a 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -829,6 +829,7 @@ enum iRunMode {
829 e.g., for icons */ 829 e.g., for icons */
830 permanentColorFlag_RunMode = iBit(11), 830 permanentColorFlag_RunMode = iBit(11),
831 alwaysVariableWidthFlag_RunMode = iBit(12), 831 alwaysVariableWidthFlag_RunMode = iBit(12),
832 fillBackground_RunMode = iBit(13),
832}; 833};
833 834
834static enum iFontId fontId_Text_(const iFont *font) { 835static enum iFontId fontId_Text_(const iFont *font) {
@@ -894,6 +895,10 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
894 if (isMonospaced) { 895 if (isMonospaced) {
895 monoAdvance = glyph_Font_(d, 'M')->advance; 896 monoAdvance = glyph_Font_(d, 'M')->advance;
896 } 897 }
898 if (args->mode & fillBackground_RunMode) {
899 const iColor initial = get_Color(args->color);
900 SDL_SetRenderDrawColor(text_.render, initial.r, initial.g, initial.b, 0);
901 }
897 /* Text rendering is not very straightforward! Let's dive in... */ 902 /* Text rendering is not very straightforward! Let's dive in... */
898 for (const char *chPos = args->text.start; chPos != args->text.end; ) { 903 for (const char *chPos = args->text.start; chPos != args->text.end; ) {
899 iAssert(chPos < args->text.end); 904 iAssert(chPos < args->text.end);
@@ -908,6 +913,9 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
908 const iColor clr = 913 const iColor clr =
909 ansiForeground_Color(capturedRange_RegExpMatch(&m, 1), tmParagraph_ColorId); 914 ansiForeground_Color(capturedRange_RegExpMatch(&m, 1), tmParagraph_ColorId);
910 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b); 915 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b);
916 if (args->mode & fillBackground_RunMode) {
917 SDL_SetRenderDrawColor(text_.render, clr.r, clr.g, clr.b, 0);
918 }
911 } 919 }
912 chPos = end_RegExpMatch(&m); 920 chPos = end_RegExpMatch(&m);
913 continue; 921 continue;
@@ -972,7 +980,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
972 prevCh = 0; 980 prevCh = 0;
973 continue; 981 continue;
974 } 982 }
975 if (ch == '\r') { 983 if (ch == '\r') { /* color change */
976 iChar esc = nextChar_(&chPos, args->text.end); 984 iChar esc = nextChar_(&chPos, args->text.end);
977 int colorNum = args->color; 985 int colorNum = args->color;
978 if (esc != 0x24) { /* ASCII Cancel */ 986 if (esc != 0x24) { /* ASCII Cancel */
@@ -985,6 +993,10 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
985 if (mode & draw_RunMode && ~mode & permanentColorFlag_RunMode) { 993 if (mode & draw_RunMode && ~mode & permanentColorFlag_RunMode) {
986 const iColor clr = get_Color(colorNum); 994 const iColor clr = get_Color(colorNum);
987 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b); 995 SDL_SetTextureColorMod(text_.cache, clr.r, clr.g, clr.b);
996 if (args->mode & fillBackground_RunMode) {
997 printf("draw color: [%d] %d,%d,%d\n", colorNum, clr.r, clr.g, clr.b);
998 SDL_SetRenderDrawColor(text_.render, clr.r, clr.g, clr.b, 0);
999 }
988 } 1000 }
989 prevCh = 0; 1001 prevCh = 0;
990 continue; 1002 continue;
@@ -995,6 +1007,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
995 } 1007 }
996 const iGlyph *glyph = glyph_Font_(d, ch); 1008 const iGlyph *glyph = glyph_Font_(d, ch);
997 int x1 = iMax(xpos, xposExtend); 1009 int x1 = iMax(xpos, xposExtend);
1010 /* Which half of the pixel the glyph falls on? */
998 const int hoff = enableHalfPixelGlyphs_Text ? (xpos - x1 > 0.5f ? 1 : 0) : 0; 1011 const int hoff = enableHalfPixelGlyphs_Text ? (xpos - x1 > 0.5f ? 1 : 0) : 0;
999 if (!isRasterized_Glyph_(glyph, hoff)) { 1012 if (!isRasterized_Glyph_(glyph, hoff)) {
1000 /* Need to pause here and make sure all glyphs have been cached in the text. */ 1013 /* Need to pause here and make sure all glyphs have been cached in the text. */
@@ -1002,7 +1015,7 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1002 glyph = glyph_Font_(d, ch); /* cache may have been reset */ 1015 glyph = glyph_Font_(d, ch); /* cache may have been reset */
1003 } 1016 }
1004 int x2 = x1 + glyph->rect[hoff].size.x; 1017 int x2 = x1 + glyph->rect[hoff].size.x;
1005 /* Out of the allotted space? */ 1018 /* Out of the allotted space on the line? */
1006 if (args->xposLimit > 0 && x2 > args->xposLimit) { 1019 if (args->xposLimit > 0 && x2 > args->xposLimit) {
1007 if (args->continueFrom_out) { 1020 if (args->continueFrom_out) {
1008 if (lastWordEnd != args->text.start) { 1021 if (lastWordEnd != args->text.start) {
@@ -1064,6 +1077,11 @@ static iRect run_Font_(iFont *d, const iRunArgs *args) {
1064 src.y += over; 1077 src.y += over;
1065 src.h -= over; 1078 src.h -= over;
1066 } 1079 }
1080 if (args->mode & fillBackground_RunMode) {
1081 /* Alpha blending looks much better if the RGB components don't change in
1082 the partially transparent pixels. */
1083 SDL_RenderFillRect(text_.render, &dst);
1084 }
1067 SDL_RenderCopy(text_.render, text_.cache, &src, &dst); 1085 SDL_RenderCopy(text_.render, text_.cache, &src, &dst);
1068 } 1086 }
1069 xpos += advance; 1087 xpos += advance;
@@ -1192,11 +1210,12 @@ static void drawBounded_Text_(int fontId, iInt2 pos, int xposBound, int color, i
1192 run_Font_(font, 1210 run_Font_(font,
1193 &(iRunArgs){ .mode = draw_RunMode | 1211 &(iRunArgs){ .mode = draw_RunMode |
1194 (color & permanent_ColorId ? permanentColorFlag_RunMode : 0) | 1212 (color & permanent_ColorId ? permanentColorFlag_RunMode : 0) |
1213 (color & fillBackground_ColorId ? fillBackground_RunMode : 0) |
1195 runFlagsFromId_(fontId), 1214 runFlagsFromId_(fontId),
1196 .text = text, 1215 .text = text,
1197 .pos = pos, 1216 .pos = pos,
1198 .xposLayoutBound = xposBound, 1217 .xposLayoutBound = xposBound,
1199 .color = color }); 1218 .color = color & mask_ColorId });
1200} 1219}
1201 1220
1202static void draw_Text_(int fontId, iInt2 pos, int color, iRangecc text) { 1221static void draw_Text_(int fontId, iInt2 pos, int color, iRangecc text) {
@@ -1398,9 +1417,9 @@ iString *renderBlockChars_Text(const iBlock *fontData, int height, enum iTextBlo
1398 1417
1399/*-----------------------------------------------------------------------------------------------*/ 1418/*-----------------------------------------------------------------------------------------------*/
1400 1419
1401iDefineTypeConstructionArgs(TextBuf, (int font, const char *text), font, text) 1420iDefineTypeConstructionArgs(TextBuf, (int font, int color, const char *text), font, color, text)
1402 1421
1403void init_TextBuf(iTextBuf *d, int font, const char *text) { 1422void init_TextBuf(iTextBuf *d, int font, int color, const char *text) {
1404 SDL_Renderer *render = text_.render; 1423 SDL_Renderer *render = text_.render;
1405 d->size = advance_Text(font, text); 1424 d->size = advance_Text(font, text);
1406 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); 1425 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
@@ -1412,9 +1431,9 @@ void init_TextBuf(iTextBuf *d, int font, const char *text) {
1412 SDL_Texture *oldTarget = SDL_GetRenderTarget(render); 1431 SDL_Texture *oldTarget = SDL_GetRenderTarget(render);
1413 SDL_SetRenderTarget(render, d->texture); 1432 SDL_SetRenderTarget(render, d->texture);
1414 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_NONE); /* blended when TextBuf is drawn */ 1433 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_NONE); /* blended when TextBuf is drawn */
1415 SDL_SetRenderDrawColor(text_.render, 255, 255, 255, 0); 1434 SDL_SetRenderDrawColor(text_.render, 0, 0, 0, 0);
1416 SDL_RenderClear(text_.render); 1435 SDL_RenderClear(text_.render);
1417 draw_Text_(font, zero_I2(), white_ColorId, range_CStr(text)); 1436 draw_Text_(font, zero_I2(), color | fillBackground_ColorId, range_CStr(text));
1418 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_BLEND); 1437 SDL_SetTextureBlendMode(text_.cache, SDL_BLENDMODE_BLEND);
1419 SDL_SetRenderTarget(render, oldTarget); 1438 SDL_SetRenderTarget(render, oldTarget);
1420 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND); 1439 SDL_SetTextureBlendMode(d->texture, SDL_BLENDMODE_BLEND);
diff --git a/src/ui/text.h b/src/ui/text.h
index 606096b6..136e14e9 100644
--- a/src/ui/text.h
+++ b/src/ui/text.h
@@ -212,7 +212,7 @@ iString * renderBlockChars_Text (const iBlock *fontData, int height, enum iT
212/*-----------------------------------------------------------------------------------------------*/ 212/*-----------------------------------------------------------------------------------------------*/
213 213
214iDeclareType(TextBuf) 214iDeclareType(TextBuf)
215iDeclareTypeConstructionArgs(TextBuf, int font, const char *text) 215iDeclareTypeConstructionArgs(TextBuf, int font, int color, const char *text)
216 216
217struct Impl_TextBuf { 217struct Impl_TextBuf {
218 SDL_Texture *texture; 218 SDL_Texture *texture;