From 9dfffb6697ddb9065c277b1d30a98a5339bcd0e3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Feb 2019 11:43:04 +0100 Subject: [PATCH] - moved font code into a subdirectory. --- src/CMakeLists.txt | 8 +- src/{ => gamedata/fonts}/v_font.cpp | 18 ++- src/{ => gamedata/fonts}/v_font.h | 1 + src/gamedata/fonts/v_text.cpp | 237 ++++++++++++++++++++++++++++ src/{ => gamedata/fonts}/v_text.h | 0 src/{v_text.cpp => v_drawtext.cpp} | 189 ---------------------- 6 files changed, 261 insertions(+), 192 deletions(-) rename src/{ => gamedata/fonts}/v_font.cpp (99%) rename src/{ => gamedata/fonts}/v_font.h (99%) create mode 100644 src/gamedata/fonts/v_text.cpp rename src/{ => gamedata/fonts}/v_text.h (100%) rename src/{v_text.cpp => v_drawtext.cpp} (66%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b0789d91e..a6b22efda 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -655,6 +655,7 @@ file( GLOB HEADER_FILES g_statusbar/*.h gamedata/*.h gamedata/resourcefiles/*.h + gamedata/fonts/*.h gamedata/textures/*.h gamedata/textures/hires/hqnx/*.h gamedata/textures/hires/hqnx_asm/*.h @@ -966,13 +967,12 @@ set (PCH_SOURCES statistics.cpp stats.cpp v_2ddrawer.cpp + v_drawtext.cpp v_blend.cpp v_draw.cpp - v_font.cpp v_framebuffer.cpp v_palette.cpp v_pfx.cpp - v_text.cpp v_video.cpp wi_stuff.cpp gamedata/a_keys.cpp @@ -1125,6 +1125,8 @@ set (PCH_SOURCES gamedata/textures/formats/tgatexture.cpp gamedata/textures/hires/hqresize.cpp gamedata/textures/hires/hirestex.cpp + gamedata/fonts/v_font.cpp + gamedata/fonts/v_text.cpp gamedata/p_xlat.cpp gamedata/xlat/parse_xlat.cpp gamedata/xlat/parsecontext.cpp @@ -1339,6 +1341,7 @@ include_directories( . g_shared gamedata gamedata/textures + gamedata/fonts rendering sound sound/oplsynth @@ -1457,6 +1460,7 @@ source_group("External\\SFMT" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/s source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+") source_group("Game Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/.+") source_group("Game Data\\Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/resourcefiles/.+") +source_group("Game Data\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/fonts/.+") source_group("Game Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/textures/.+") source_group("Game Data\\Textures\\Hires" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/textures/hires/.+") source_group("Game Data\\Textures\\Hires\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/textures/hires/hqnx/.+") diff --git a/src/v_font.cpp b/src/gamedata/fonts/v_font.cpp similarity index 99% rename from src/v_font.cpp rename to src/gamedata/fonts/v_font.cpp index 37a54d381..7caf60369 100644 --- a/src/v_font.cpp +++ b/src/gamedata/fonts/v_font.cpp @@ -1098,6 +1098,22 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla sc.MustGetValue(false); FontHeight = sc.Number; } + else if (sc.Compare("Translationtype")) + { + sc.MustGetToken(TK_Identifier); + if (sc.Compare("console")) + { + TranslationType = 1; + } + else if (sc.Compare("standard")) + { + TranslationType = 0; + } + else + { + sc.ScriptError("Unknown translation type %s", sc.String); + } + } } } } @@ -1701,7 +1717,7 @@ void FFont::LoadTranslations() static_cast(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, nullptr); + BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr); } //========================================================================== diff --git a/src/v_font.h b/src/gamedata/fonts/v_font.h similarity index 99% rename from src/v_font.h rename to src/gamedata/fonts/v_font.h index de2482d99..a4bf7c738 100644 --- a/src/v_font.h +++ b/src/gamedata/fonts/v_font.h @@ -118,6 +118,7 @@ protected: int SpaceWidth; int FontHeight; int GlobalKerning; + int TranslationType = 0; char Cursor; bool noTranslate; bool translateUntranslated; diff --git a/src/gamedata/fonts/v_text.cpp b/src/gamedata/fonts/v_text.cpp new file mode 100644 index 000000000..dc2729df1 --- /dev/null +++ b/src/gamedata/fonts/v_text.cpp @@ -0,0 +1,237 @@ +/* +** v_text.cpp +** Draws text to a canvas. Also has a text line-breaker thingy. +** +**--------------------------------------------------------------------------- +** Copyright 1998-2006 Randy Heit +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include +#include +#include +#include + +#include "v_text.h" + + +#include "v_video.h" +#include "w_wad.h" + +#include "gstrings.h" +#include "vm.h" +#include "serializer.h" + +//========================================================================== +// +// Break long lines of text into multiple lines no longer than maxwidth pixels +// +//========================================================================== + +static void breakit (FBrokenLines *line, FFont *font, const uint8_t *start, const uint8_t *stop, FString &linecolor) +{ + if (!linecolor.IsEmpty()) + { + line->Text = TEXTCOLOR_ESCAPE; + line->Text += linecolor; + } + line->Text.AppendCStrPart ((const char *)start, stop - start); + line->Width = font->StringWidth (line->Text); +} + +TArray V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor) +{ + TArray Lines(128); + + const uint8_t *space = NULL, *start = string; + int c, w, nw; + FString lastcolor, linecolor; + bool lastWasSpace = false; + int kerning = font->GetDefaultKerning (); + + w = 0; + + while ( (c = GetCharFromString(string)) ) + { + if (c == TEXTCOLOR_ESCAPE) + { + if (*string) + { + if (*string == '[') + { + const uint8_t *start = string; + while (*string != ']' && *string != '\0') + { + string++; + } + if (*string != '\0') + { + string++; + } + lastcolor = FString((const char *)start, string - start); + } + else + { + lastcolor = *string++; + } + } + continue; + } + + if (iswspace(c)) + { + if (!lastWasSpace) + { + space = string - 1; + lastWasSpace = true; + } + } + else + { + lastWasSpace = false; + } + + nw = font->GetCharWidth (c); + + if ((w > 0 && w + nw > maxwidth) || c == '\n') + { // Time to break the line + if (!space) + space = string - 1; + + auto index = Lines.Reserve(1); + breakit (&Lines[index], font, start, space, linecolor); + if (c == '\n' && !preservecolor) + { + lastcolor = ""; // Why, oh why, did I do it like this? + } + linecolor = lastcolor; + + w = 0; + lastWasSpace = false; + start = space; + space = NULL; + + while (*start && iswspace (*start) && *start != '\n') + start++; + if (*start == '\n') + start++; + else + while (*start && iswspace (*start)) + start++; + string = start; + } + else + { + w += nw + kerning; + } + } + + // String here is pointing one character after the '\0' + if (--string - start >= 1) + { + const uint8_t *s = start; + + while (s < string) + { + // If there is any non-white space in the remainder of the string, add it. + if (!iswspace (*s++)) + { + auto i = Lines.Reserve(1); + breakit (&Lines[i], font, start, string, linecolor); + break; + } + } + } + return Lines; +} + +FSerializer &Serialize(FSerializer &arc, const char *key, FBrokenLines& g, FBrokenLines *def) +{ + if (arc.BeginObject(key)) + { + arc("text", g.Text) + ("width", g.Width) + .EndObject(); + } + return arc; +} + + + +class DBrokenLines : public DObject +{ + DECLARE_CLASS(DBrokenLines, DObject) + +public: + TArray mBroken; + + DBrokenLines() = default; + + DBrokenLines(TArray &broken) + { + mBroken = std::move(broken); + } + + void Serialize(FSerializer &arc) override + { + arc("lines", mBroken); + } +}; + +IMPLEMENT_CLASS(DBrokenLines, false, false); + +DEFINE_ACTION_FUNCTION(DBrokenLines, Count) +{ + PARAM_SELF_PROLOGUE(DBrokenLines); + ACTION_RETURN_INT(self->mBroken.Size()); +} + +DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth) +{ + PARAM_SELF_PROLOGUE(DBrokenLines); + PARAM_INT(index); + ACTION_RETURN_INT((unsigned)index >= self->mBroken.Size()? -1 : self->mBroken[index].Width); +} + +DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt) +{ + + PARAM_SELF_PROLOGUE(DBrokenLines); + PARAM_INT(index); + ACTION_RETURN_STRING((unsigned)index >= self->mBroken.Size() ? -1 : self->mBroken[index].Text); +} + +DEFINE_ACTION_FUNCTION(FFont, BreakLines) +{ + PARAM_SELF_STRUCT_PROLOGUE(FFont); + PARAM_STRING(text); + PARAM_INT(maxwidth); + + auto broken = V_BreakLines(self, maxwidth, text, true); + ACTION_RETURN_OBJECT(Create(broken)); +} diff --git a/src/v_text.h b/src/gamedata/fonts/v_text.h similarity index 100% rename from src/v_text.h rename to src/gamedata/fonts/v_text.h diff --git a/src/v_text.cpp b/src/v_drawtext.cpp similarity index 66% rename from src/v_text.cpp rename to src/v_drawtext.cpp index e7634fa5e..1ab1e7c64 100644 --- a/src/v_text.cpp +++ b/src/v_drawtext.cpp @@ -263,192 +263,3 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText) return 0; } - -//========================================================================== -// -// Break long lines of text into multiple lines no longer than maxwidth pixels -// -//========================================================================== - -static void breakit (FBrokenLines *line, FFont *font, const uint8_t *start, const uint8_t *stop, FString &linecolor) -{ - if (!linecolor.IsEmpty()) - { - line->Text = TEXTCOLOR_ESCAPE; - line->Text += linecolor; - } - line->Text.AppendCStrPart ((const char *)start, stop - start); - line->Width = font->StringWidth (line->Text); -} - -TArray V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor) -{ - TArray Lines(128); - - const uint8_t *space = NULL, *start = string; - int c, w, nw; - FString lastcolor, linecolor; - bool lastWasSpace = false; - int kerning = font->GetDefaultKerning (); - - w = 0; - - while ( (c = GetCharFromString(string)) ) - { - if (c == TEXTCOLOR_ESCAPE) - { - if (*string) - { - if (*string == '[') - { - const uint8_t *start = string; - while (*string != ']' && *string != '\0') - { - string++; - } - if (*string != '\0') - { - string++; - } - lastcolor = FString((const char *)start, string - start); - } - else - { - lastcolor = *string++; - } - } - continue; - } - - if (iswspace(c)) - { - if (!lastWasSpace) - { - space = string - 1; - lastWasSpace = true; - } - } - else - { - lastWasSpace = false; - } - - nw = font->GetCharWidth (c); - - if ((w > 0 && w + nw > maxwidth) || c == '\n') - { // Time to break the line - if (!space) - space = string - 1; - - auto index = Lines.Reserve(1); - breakit (&Lines[index], font, start, space, linecolor); - if (c == '\n' && !preservecolor) - { - lastcolor = ""; // Why, oh why, did I do it like this? - } - linecolor = lastcolor; - - w = 0; - lastWasSpace = false; - start = space; - space = NULL; - - while (*start && iswspace (*start) && *start != '\n') - start++; - if (*start == '\n') - start++; - else - while (*start && iswspace (*start)) - start++; - string = start; - } - else - { - w += nw + kerning; - } - } - - // String here is pointing one character after the '\0' - if (--string - start >= 1) - { - const uint8_t *s = start; - - while (s < string) - { - // If there is any non-white space in the remainder of the string, add it. - if (!iswspace (*s++)) - { - auto i = Lines.Reserve(1); - breakit (&Lines[i], font, start, string, linecolor); - break; - } - } - } - return Lines; -} - -FSerializer &Serialize(FSerializer &arc, const char *key, FBrokenLines& g, FBrokenLines *def) -{ - if (arc.BeginObject(key)) - { - arc("text", g.Text) - ("width", g.Width) - .EndObject(); - } - return arc; -} - - - -class DBrokenLines : public DObject -{ - DECLARE_CLASS(DBrokenLines, DObject) - -public: - TArray mBroken; - - DBrokenLines() = default; - - DBrokenLines(TArray &broken) - { - mBroken = std::move(broken); - } - - void Serialize(FSerializer &arc) override - { - arc("lines", mBroken); - } -}; - -IMPLEMENT_CLASS(DBrokenLines, false, false); - -DEFINE_ACTION_FUNCTION(DBrokenLines, Count) -{ - PARAM_SELF_PROLOGUE(DBrokenLines); - ACTION_RETURN_INT(self->mBroken.Size()); -} - -DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth) -{ - PARAM_SELF_PROLOGUE(DBrokenLines); - PARAM_INT(index); - ACTION_RETURN_INT((unsigned)index >= self->mBroken.Size()? -1 : self->mBroken[index].Width); -} - -DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt) -{ - - PARAM_SELF_PROLOGUE(DBrokenLines); - PARAM_INT(index); - ACTION_RETURN_STRING((unsigned)index >= self->mBroken.Size() ? -1 : self->mBroken[index].Text); -} - -DEFINE_ACTION_FUNCTION(FFont, BreakLines) -{ - PARAM_SELF_STRUCT_PROLOGUE(FFont); - PARAM_STRING(text); - PARAM_INT(maxwidth); - - auto broken = V_BreakLines(self, maxwidth, text, true); - ACTION_RETURN_OBJECT(Create(broken)); -}