diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-17 21:31:48 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-03-17 21:31:48 +0200 |
commit | 3c95b7e2aed7a405e71d954082ba7d1223a676bf (patch) | |
tree | a42bac2459825ea5c536385f2544e1376ed7a9a2 /src | |
parent | 3cb3af524117fc91afd5f0f878d9978d27048344 (diff) |
TextBuf: Support for color
Fill glyph backgrounds individually based on current color.
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/color.h | 3 | ||||
-rw-r--r-- | src/ui/text.c | 33 | ||||
-rw-r--r-- | src/ui/text.h | 2 |
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 | ||
834 | static enum iFontId fontId_Text_(const iFont *font) { | 835 | static 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 | ||
1202 | static void draw_Text_(int fontId, iInt2 pos, int color, iRangecc text) { | 1221 | static 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 | ||
1401 | iDefineTypeConstructionArgs(TextBuf, (int font, const char *text), font, text) | 1420 | iDefineTypeConstructionArgs(TextBuf, (int font, int color, const char *text), font, color, text) |
1402 | 1421 | ||
1403 | void init_TextBuf(iTextBuf *d, int font, const char *text) { | 1422 | void 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 | ||
214 | iDeclareType(TextBuf) | 214 | iDeclareType(TextBuf) |
215 | iDeclareTypeConstructionArgs(TextBuf, int font, const char *text) | 215 | iDeclareTypeConstructionArgs(TextBuf, int font, int color, const char *text) |
216 | 216 | ||
217 | struct Impl_TextBuf { | 217 | struct Impl_TextBuf { |
218 | SDL_Texture *texture; | 218 | SDL_Texture *texture; |