- exported BrokenLines to scripting as a new class.

- removed the hard limit of 128 lines for V_BreakLines.
This commit is contained in:
Christoph Oelckers 2017-02-05 16:18:41 +01:00
parent d8a1ce88b0
commit 52bec33c0d
3 changed files with 92 additions and 18 deletions

View file

@ -47,11 +47,14 @@
#include "doomstat.h"
#include "templates.h"
//==========================================================================
//
// DrawChar
//
// Write a single character using the given font
//
//==========================================================================
void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...)
{
if (font == NULL)
@ -79,11 +82,14 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch
}
}
//==========================================================================
//
// DrawText
//
// Write a string using the given font
//
//==========================================================================
void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...)
{
int w;
@ -167,9 +173,12 @@ void DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *s
}
//==========================================================================
//
// Break long lines of text into multiple lines no longer than maxwidth pixels
//
//==========================================================================
static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const BYTE *stop, FString &linecolor)
{
if (!linecolor.IsEmpty())
@ -181,20 +190,19 @@ static void breakit (FBrokenLines *line, FFont *font, const BYTE *start, const B
line->Width = font->StringWidth (line->Text);
}
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor)
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool preservecolor, unsigned int *count)
{
FBrokenLines lines[128]; // Support up to 128 lines (should be plenty)
TArray<FBrokenLines> Lines(128);
const BYTE *space = NULL, *start = string;
size_t i, ii;
int c, w, nw;
FString lastcolor, linecolor;
bool lastWasSpace = false;
int kerning = font->GetDefaultKerning ();
i = w = 0;
w = 0;
while ( (c = *string++) && i < countof(lines) )
while ( (c = *string++) )
{
if (c == TEXTCOLOR_ESCAPE)
{
@ -241,14 +249,14 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
if (!space)
space = string - 1;
breakit (&lines[i], font, start, space, linecolor);
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;
i++;
w = 0;
lastWasSpace = false;
start = space;
@ -270,7 +278,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
}
// String here is pointing one character after the '\0'
if (i < countof(lines) && --string - start >= 1)
if (--string - start >= 1)
{
const BYTE *s = start;
@ -279,20 +287,25 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *string, bool
// If there is any non-white space in the remainder of the string, add it.
if (!isspace (*s++))
{
breakit (&lines[i++], font, start, string, linecolor);
auto i = Lines.Reserve(1);
breakit (&Lines[i], font, start, string, linecolor);
break;
}
}
}
// Make a copy of the broken lines and return them
FBrokenLines *broken = new FBrokenLines[i+1];
FBrokenLines *broken = new FBrokenLines[Lines.Size() + 1];
for (ii = 0; ii < i; ++ii)
for (unsigned ii = 0; ii < Lines.Size(); ++ii)
{
broken[ii] = lines[ii];
broken[ii] = Lines[ii];
}
broken[Lines.Size()].Width = -1;
if (count != nullptr)
{
*count = Lines.Size();
}
broken[ii].Width = -1;
return broken;
}
@ -304,3 +317,56 @@ void V_FreeBrokenLines (FBrokenLines *lines)
delete[] lines;
}
}
class DBrokenLines : public DObject
{
DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject)
public:
FBrokenLines *mBroken;
unsigned int mCount;
DBrokenLines(FBrokenLines *broken, unsigned int count)
{
mBroken = broken;
mCount = count;
}
void OnDestroy() override
{
V_FreeBrokenLines(mBroken);
}
};
IMPLEMENT_CLASS(DBrokenLines, true, false);
DEFINE_ACTION_FUNCTION(DBrokenLines, Count)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
ACTION_RETURN_INT(self->mCount);
}
DEFINE_ACTION_FUNCTION(DBrokenLines, StringWidth)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
PARAM_INT(index);
ACTION_RETURN_INT((unsigned)index >= self->mCount? -1 : self->mBroken[index].Width);
}
DEFINE_ACTION_FUNCTION(DBrokenLines, StringAt)
{
PARAM_SELF_PROLOGUE(DBrokenLines);
PARAM_INT(index);
ACTION_RETURN_STRING((unsigned)index >= self->mCount? -1 : self->mBroken[index].Text);
}
DEFINE_ACTION_FUNCTION(FFont, BreakLines)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
PARAM_STRING(text);
PARAM_INT(maxwidth);
unsigned int count;
FBrokenLines *broken = V_BreakLines(self, maxwidth, text, true, &count);
ACTION_RETURN_OBJECT(new DBrokenLines(broken, count));
}

View file

@ -75,11 +75,11 @@ struct FBrokenLines
#define TEXTCOLOR_CHAT "\034*"
#define TEXTCOLOR_TEAMCHAT "\034!"
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false);
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str, bool preservecolor = false, unsigned int *count = nullptr);
void V_FreeBrokenLines (FBrokenLines *lines);
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor); }
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor); }
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false, unsigned int *count = nullptr)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str, preservecolor, count); }
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false, unsigned int *count = nullptr)
{ return V_BreakLines (font, maxwidth, (const BYTE *)str.GetChars(), preservecolor, count); }
#endif //__V_TEXT_H__

View file

@ -68,6 +68,13 @@ struct Screen native
native static void DrawHUDTexture(TextureID tex, double x, double y);
}
class BrokenLines : Object native
{
native int Count();
native int StringWidth(int line);
native String StringAt(int line);
}
struct Font native
{
native int GetCharWidth(int code);
@ -75,6 +82,7 @@ struct Font native
native static int FindFontColor(Name color);
native static Font FindFont(Name fontname);
native static Font GetFont(Name fontname);
native static BrokenLines BreakLines(String text, int maxlen);
}
struct Console native