- moved font code into a subdirectory.

This commit is contained in:
Christoph Oelckers 2019-02-17 11:43:04 +01:00
parent d5977e1802
commit 9dfffb6697
6 changed files with 261 additions and 192 deletions

View file

@ -655,6 +655,7 @@ file( GLOB HEADER_FILES
g_statusbar/*.h g_statusbar/*.h
gamedata/*.h gamedata/*.h
gamedata/resourcefiles/*.h gamedata/resourcefiles/*.h
gamedata/fonts/*.h
gamedata/textures/*.h gamedata/textures/*.h
gamedata/textures/hires/hqnx/*.h gamedata/textures/hires/hqnx/*.h
gamedata/textures/hires/hqnx_asm/*.h gamedata/textures/hires/hqnx_asm/*.h
@ -966,13 +967,12 @@ set (PCH_SOURCES
statistics.cpp statistics.cpp
stats.cpp stats.cpp
v_2ddrawer.cpp v_2ddrawer.cpp
v_drawtext.cpp
v_blend.cpp v_blend.cpp
v_draw.cpp v_draw.cpp
v_font.cpp
v_framebuffer.cpp v_framebuffer.cpp
v_palette.cpp v_palette.cpp
v_pfx.cpp v_pfx.cpp
v_text.cpp
v_video.cpp v_video.cpp
wi_stuff.cpp wi_stuff.cpp
gamedata/a_keys.cpp gamedata/a_keys.cpp
@ -1125,6 +1125,8 @@ set (PCH_SOURCES
gamedata/textures/formats/tgatexture.cpp gamedata/textures/formats/tgatexture.cpp
gamedata/textures/hires/hqresize.cpp gamedata/textures/hires/hqresize.cpp
gamedata/textures/hires/hirestex.cpp gamedata/textures/hires/hirestex.cpp
gamedata/fonts/v_font.cpp
gamedata/fonts/v_text.cpp
gamedata/p_xlat.cpp gamedata/p_xlat.cpp
gamedata/xlat/parse_xlat.cpp gamedata/xlat/parse_xlat.cpp
gamedata/xlat/parsecontext.cpp gamedata/xlat/parsecontext.cpp
@ -1339,6 +1341,7 @@ include_directories( .
g_shared g_shared
gamedata gamedata
gamedata/textures gamedata/textures
gamedata/fonts
rendering rendering
sound sound
sound/oplsynth 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("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fragglescript/.+")
source_group("Game Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/.+") 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\\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" 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" 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/.+") source_group("Game Data\\Textures\\Hires\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gamedata/textures/hires/hqnx/.+")

View file

@ -1098,6 +1098,22 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
sc.MustGetValue(false); sc.MustGetValue(false);
FontHeight = sc.Number; 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<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
} }
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, nullptr); BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr);
} }
//========================================================================== //==========================================================================

View file

@ -118,6 +118,7 @@ protected:
int SpaceWidth; int SpaceWidth;
int FontHeight; int FontHeight;
int GlobalKerning; int GlobalKerning;
int TranslationType = 0;
char Cursor; char Cursor;
bool noTranslate; bool noTranslate;
bool translateUntranslated; bool translateUntranslated;

View file

@ -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 <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <wctype.h>
#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<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor)
{
TArray<FBrokenLines> 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<FBrokenLines> mBroken;
DBrokenLines() = default;
DBrokenLines(TArray<FBrokenLines> &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<DBrokenLines>(broken));
}

View file

@ -263,192 +263,3 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText)
return 0; 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<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bool preservecolor)
{
TArray<FBrokenLines> 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<FBrokenLines> mBroken;
DBrokenLines() = default;
DBrokenLines(TArray<FBrokenLines> &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<DBrokenLines>(broken));
}