Implement line breaking in DS Map Title.

This commit is contained in:
Mari the Deer 2023-10-29 21:24:06 +01:00
commit f452d1cbac
2 changed files with 96 additions and 9 deletions

View file

@ -598,11 +598,17 @@ Class DSMapTitle : HUDMessageBase
int fheight, fheight_sub;
String txt, txtsub;
bool hasnewline;
int tics, holdtics, fadeintics, fadeouttics;
int ultics;
transient bool bDontDeleteMe; // safeguard for savegames
bool bTxtIsSplit;
Array<String> txt_split;
Array<int> txtwidth_split;
int txtmaxwidth_split;
// all the actual hard code
int MyStringWidth( String str )
{
@ -625,6 +631,66 @@ Class DSMapTitle : HUDMessageBase
w = max(w,lw);
return w;
}
void MyStringBreak( String str, int maxw )
{
bTxtIsSplit = true;
txt_split.Clear();
txtwidth_split.Clear();
txtmaxwidth_split = 0;
int cur = 0;
int w = 0;
int len = str.CodePointCount();
bool wasspace = false;
bool leftspace = false;
int lastspace = 0, pastspace = 0;
for ( int i=0, pos=0; i<len; i++ )
{
int oldpos = pos;
int ch;
[ch, pos] = str.GetNextCodePoint(pos);
if ( (ch == 0x09) || (ch == 0x0A) || (ch == 0x0D) || (ch == 0x20) )
{
if ( leftspace )
{
if ( ch == 0x0A )
{
txt_split.Push("");
txtwidth_split.Push(0);
}
continue;
}
if ( !wasspace )
{
lastspace = oldpos;
wasspace = true;
}
pastspace = pos;
}
else
{
wasspace = false;
leftspace = false;
}
int cw = (ch>255)?0:glyphs[ch].advance;
bool endof = ((i+1)>=len);
if ( (ch != 0x0A) && !endof && ((w <= 0) || (w+cw <= maxw)) )
{
w += cw;
continue;
}
String sstr = str.Mid(cur,endof?int.max:(lastspace-cur));
int lw = MyStringWidth(sstr);
txt_split.Push(sstr);
txtwidth_split.Push(lw);
if ( lw > txtmaxwidth_split ) txtmaxwidth_split = lw;
w = 0;
wasspace = false;
cur = pastspace;
lastspace = 0;
pastspace = 0;
leftspace = true;
}
}
int MySubStringWidth( String str )
{
int w = 0;
@ -756,6 +822,8 @@ Class DSMapTitle : HUDMessageBase
txtsub = txt.Mid(sep+3);
txt.Truncate(sep);
}
hasnewline = (txt.IndexOf("\n") != -1);
bTxtIsSplit = false;
tics = -10;
holdtics = 140;
fadeintics = 20;
@ -833,6 +901,12 @@ Class DSMapTitle : HUDMessageBase
return self;
}
override void ScreenSizeChanged()
{
// force line re-break
bTxtIsSplit = false;
}
override bool Tick()
{
if ( !bDontDeleteMe ) return true;
@ -846,10 +920,6 @@ Class DSMapTitle : HUDMessageBase
{
if ( tics <= 0 ) return;
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/360.)),1.);
int w = MyStringWidth(txt);
int w2 = MySubStringWidth(txtsub);
if ( w > 800 ) hs = max(hs-2.,1.);
else if ( w > 400 ) hs = max(hs-1.,1.);
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
double fractic = System.GetTimeFrac();
double ftics = tics+fractic;
@ -857,9 +927,26 @@ Class DSMapTitle : HUDMessageBase
double xx = int(ss.x/2.);
double yy = int(ss.y/2.)-64.;
double wfact = clamp(ftics/double(ultics),0.,1.);
DrawUnderline(xx,yy+1,ss,(w+32)*wfact,alpha);
MyDrawText(txt,xx-w/2,yy,ss,alpha);
MySubDrawText(txtsub,xx-w2/2,yy+fheight_sub+12,ss,alpha);
int wsub = MySubStringWidth(txtsub);
int w = MyStringWidth(txt);
int capw = int(ss.x-250);
if ( (w < capw) && !hasnewline )
{
DrawUnderline(xx,yy+1,ss,(w+32)*wfact,alpha);
MyDrawText(txt,xx-w/2,yy,ss,alpha);
MySubDrawText(txtsub,xx-wsub/2,yy+fheight_sub+12,ss,alpha);
return;
}
if ( !bTxtIsSplit ) MyStringBreak(txt,capw);
yy += (fheight/2)*(txt_split.Size()-1);
DrawUnderline(xx,yy+1,ss,(txtmaxwidth_split+32)*wfact,alpha);
yy -= fheight*txt_split.Size();
for ( int i=0; i<txt_split.Size(); i++ )
{
yy += fheight;
MyDrawText(txt_split[i],xx-txtwidth_split[i]/2,yy,ss,alpha);
}
MySubDrawText(txtsub,xx-wsub/2,yy+fheight_sub+12,ss,alpha);
}
}