Skip to content

Commit

Permalink
revert f08a398 [skip ci]
Browse files Browse the repository at this point in the history
Оказалось, есть софтина для создания шрифтов, которым этот код в движке нужен https://drive.google.com/file/d/1IXFTr0Wn6eUeyuiLt1GKyyEBFOtVfrma/view?usp=sharing
  • Loading branch information
xrSimpodin committed Jan 31, 2023
1 parent fa8d885 commit b63c07e
Show file tree
Hide file tree
Showing 9 changed files with 475 additions and 10 deletions.
22 changes: 16 additions & 6 deletions ogsr_engine/Layers/xrRender/dxFontRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ void dxFontRender::OnRender(CGameFont& owner)
// calculate first-fit
int count = 1;

int length = xr_strlen(owner.strings[i].string);
int length = owner.smart_strlen(owner.strings[i].string);

while ((i + count) < owner.strings.size())
{
int L = xr_strlen(owner.strings[i + count].string);
int L = owner.smart_strlen(owner.strings[i + count].string);

if ((L + length) < 4096) // MAX_MB_CHARS ??
if ((L + length) < MAX_MB_CHARS)
{
count++;
length += L;
Expand All @@ -67,8 +67,11 @@ void dxFontRender::OnRender(CGameFont& owner)
for (; i < last; i++)
{
CGameFont::String& PS = owner.strings[i];
wide_char wsStr[MAX_MB_CHARS];

int len = xr_strlen(PS.string);
int len = owner.IsMultibyte() ? mbhMulti2Wide(wsStr, NULL, MAX_MB_CHARS, PS.string) :

xr_strlen(PS.string);

if (len)
{
Expand All @@ -81,7 +84,7 @@ void dxFontRender::OnRender(CGameFont& owner)
float fSize = 0;

if (PS.align)
fSize = owner.SizeOf_(PS.string); // уже с * owner.GetWidthScale()
fSize = owner.IsMultibyte() ? owner.SizeOf_(wsStr) : owner.SizeOf_(PS.string);

switch (PS.align)
{
Expand Down Expand Up @@ -115,7 +118,7 @@ void dxFontRender::OnRender(CGameFont& owner)
{
Fvector l;

l = owner.GetCharTC((u16)(u8)PS.string[j]);
l = owner.IsMultibyte() ? owner.GetCharTC(wsStr[1 + j]) : owner.GetCharTC((u16)(u8)PS.string[j]);

float scw = l.z * g_current_font_scale.x * owner.GetWidthScale();

Expand Down Expand Up @@ -144,6 +147,13 @@ void dxFontRender::OnRender(CGameFont& owner)
}

X += scw * owner.vInterval.x;

if (owner.IsMultibyte())
{
X -= 2;
if (IsNeedSpaceCharacter(wsStr[1 + j]))
X += owner.fXStep;
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions ogsr_engine/xrGame/ui/UIEditKeyBind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ CUIEditKeyBind::~CUIEditKeyBind() { delete_data(m_pAnimation); }

u32 cut_string_by_length(CGameFont* pFont, LPCSTR src, LPSTR dst, u32 dst_size, float length)
{
if (pFont->IsMultibyte())
{
u16 nPos = pFont->GetCutLengthPos(length, src);
VERIFY(nPos < dst_size);
strncpy(dst, src, nPos);
dst[nPos] = '\0';
return nPos;
}
else
{
float text_len = pFont->SizeOf_(src);
UI()->ClientToScreenScaledWidth(text_len);
Expand Down
87 changes: 85 additions & 2 deletions ogsr_engine/xrGame/ui/UILines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,92 @@ void CUILines::ParseText()
line->AddSubLine(&subline);
}

BOOL bNewLines = FALSE;

if (uFlags.test(flRecognizeNewLine))
if (m_pFont->IsMultibyte())
{
CUILine* ptmp_line = xr_new<CUILine>();
int vsz = line->m_subLines.size();
VERIFY(vsz);
for (int i = 0; i < vsz; i++)
{
char* pszTemp = NULL;
const u32 tcolor = line->m_subLines[i].m_color;
char szTempLine[MAX_MB_CHARS], *pszSearch = NULL;
VERIFY(strlen(line->m_subLines[i].m_text.c_str()) < MAX_MB_CHARS);
strcpy_s(szTempLine, line->m_subLines[i].m_text.c_str());
pszSearch = szTempLine;
while ((pszTemp = strstr(pszSearch, "\\n")) != NULL)
{
bNewLines = TRUE;
*pszTemp = '\0';
ptmp_line->AddSubLine(pszSearch, tcolor);
pszSearch = pszTemp + 2;
}
ptmp_line->AddSubLine(pszSearch, tcolor);
}
line->Clear();
xr_free(line);
line = ptmp_line;
}
else
line->ProcessNewLines(); // process "\n"

if (m_pFont->IsMultibyte())
{
line->ProcessNewLines(); // process "\n"
#define UBUFFER_SIZE 100
u16 aMarkers[UBUFFER_SIZE];
CUILine tmp_line;
char szTempLine[MAX_MB_CHARS];
float fTargetWidth = 1.0f;
UI()->ClientToScreenScaledWidth(fTargetWidth);
VERIFY((m_wndSize.x > 0) && (fTargetWidth > 0));
fTargetWidth = m_wndSize.x / fTargetWidth;
int vsz = line->m_subLines.size();
VERIFY(vsz);
if ((vsz > 1) && (!bNewLines))
{ // only colored line, pizdets
for (int i = 0; i < vsz; i++)
{
const char* pszText = line->m_subLines[i].m_text.c_str();
const u32 tcolor = line->m_subLines[i].m_color;
VERIFY(pszText);
tmp_line.AddSubLine(pszText, tcolor);
}
m_lines.push_back(tmp_line);
tmp_line.Clear();
}
else
{
for (int i = 0; i < vsz; i++)
{
const char* pszText = line->m_subLines[i].m_text.c_str();
const u32 tcolor = line->m_subLines[i].m_color;
u16 uFrom = 0, uPartLen = 0;
VERIFY(pszText);
u16 nMarkers = m_pFont->SplitByWidth(aMarkers, UBUFFER_SIZE, fTargetWidth, pszText);
for (u16 j = 0; j < nMarkers; j++)
{
uPartLen = aMarkers[j] - uFrom;
VERIFY((uPartLen > 0) && (uPartLen < MAX_MB_CHARS));
strncpy_s(szTempLine, pszText + uFrom, uPartLen);
szTempLine[uPartLen] = '\0';
tmp_line.AddSubLine(szTempLine, tcolor);
m_lines.push_back(tmp_line);
tmp_line.Clear();
uFrom += uPartLen;
}
strncpy_s(szTempLine, pszText + uFrom, MAX_MB_CHARS);
tmp_line.AddSubLine(szTempLine, tcolor);
m_lines.push_back(tmp_line);
tmp_line.Clear();
}
}
}

else
{

float max_width = m_wndSize.x;

CUILine tmp_line;
Expand Down Expand Up @@ -228,6 +309,8 @@ void CUILines::ParseText()
}
}

}

xr_delete(line);
uFlags.set(flNeedReparse, FALSE);
}
Expand Down
146 changes: 144 additions & 2 deletions ogsr_engine/xr_3da/GameFont.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,56 @@ void CGameFont::Initialize(LPCSTR cShader, LPCSTR cTextureName)
nNumChars = 0x100;
TCMap = (Fvector*)xr_realloc((void*)TCMap, nNumChars * sizeof(Fvector));

if (ini->section_exist("symbol_coords"))
if (ini->section_exist("mb_symbol_coords"))
{
nNumChars = 0x10000;
TCMap = (Fvector*)xr_realloc((void*)TCMap, nNumChars * sizeof(Fvector));
uFlags |= fsMultibyte;
fHeight = ini->r_float("mb_symbol_coords", "height");

fXStep = ceil(fHeight / 2.0f);

// Searching for the first valid character

Fvector vFirstValid = {0, 0, 0};

if (ini->line_exist("mb_symbol_coords", "09608"))
{
Fvector v = ini->r_fvector3("mb_symbol_coords", "09608");
vFirstValid.set(v.x, v.y, 1 + v[2] - v[0]);
}
else
for (u32 i = 0; i < nNumChars; i++)
{
xr_sprintf(buf, sizeof(buf), "%05d", i);
if (ini->line_exist("mb_symbol_coords", buf))
{
Fvector v = ini->r_fvector3("mb_symbol_coords", buf);
vFirstValid.set(v.x, v.y, 1 + v[2] - v[0]);
break;
}
}

// Filling entire character table

for (u32 i = 0; i < nNumChars; i++)
{
xr_sprintf(buf, sizeof(buf), "%05d", i);
if (ini->line_exist("mb_symbol_coords", buf))
{
Fvector v = ini->r_fvector3("mb_symbol_coords", buf);
TCMap[i].set(v.x, v.y, 1 + v[2] - v[0]);
}
else
TCMap[i] = vFirstValid; // "unassigned" unprintable characters
}

// Special case for space
TCMap[0x0020].set(0, 0, 0);
// Special case for ideographic space
TCMap[0x3000].set(0, 0, 0);
}
else if (ini->section_exist("symbol_coords"))
{
//float d = READ_IF_EXISTS(ini, r_float, "width_correction", "value", 0.0f); // Это раньше не работало, теперь работает, и чтоб старые кривые конфиги не работали криво, имя параметра переименовано.
float d = READ_IF_EXISTS(ini, r_float, "font_width_correction", "value", 0.0f);
Expand Down Expand Up @@ -156,12 +205,76 @@ void CGameFont::OutSet(float x, float y)

void CGameFont::OutSetI(float x, float y) { OutSet(DI2PX(x), DI2PY(y)); }

u32 CGameFont::smart_strlen(const char* S) { return (IsMultibyte() ? mbhMulti2Wide(NULL, NULL, 0, S) : xr_strlen(S)); }

void CGameFont::OnRender()
{
pFontRender->OnRender(*this);
strings.clear();
}

u16 CGameFont::GetCutLengthPos(float fTargetWidth, const char* pszText)
{
VERIFY(pszText);

wide_char wsStr[MAX_MB_CHARS], wsPos[MAX_MB_CHARS];
float fCurWidth = 0.0f, fDelta = 0.0f;

u16 len = mbhMulti2Wide(wsStr, wsPos, MAX_MB_CHARS, pszText);
u16 i = 1;

for (; i <= len; i++)
{
fDelta = GetCharTC(wsStr[i]).z - 2;

if (IsNeedSpaceCharacter(wsStr[i]))
fDelta += fXStep;

if ((fCurWidth + fDelta) > fTargetWidth)
break;
else
fCurWidth += fDelta;
}

return wsPos[i - 1];
}

u16 CGameFont::SplitByWidth(u16* puBuffer, u16 uBufferSize, float fTargetWidth, const char* pszText)
{
VERIFY(puBuffer && uBufferSize && pszText);

wide_char wsStr[MAX_MB_CHARS], wsPos[MAX_MB_CHARS];
float fCurWidth = 0.0f, fDelta = 0.0f;
u16 nLines = 0;

u16 len = mbhMulti2Wide(wsStr, wsPos, MAX_MB_CHARS, pszText);

for (u16 i = 1; i <= len; i++)
{
fDelta = (GetCharTC(wsStr[i]).z * GetWidthScale()) - 2;

if (IsNeedSpaceCharacter(wsStr[i]))
fDelta += fXStep;

if (((fCurWidth + fDelta) > fTargetWidth) && // overlength
(!IsBadStartCharacter(wsStr[i])) && // can start with this character
(i < len) && // is not the last character
((i > 1) && (!IsBadEndCharacter(wsStr[i - 1]))) // && // do not stop the string on a "bad" character
)
{
fCurWidth = fDelta;

VERIFY(nLines < uBufferSize);

puBuffer[nLines++] = wsPos[i - 1];
}
else
fCurWidth += fDelta;
}

return nLines;
}

void CGameFont::MasterOut(BOOL bCheckDevice, BOOL bUseCoords, BOOL bScaleCoords, BOOL bUseSkip, float _x, float _y, float _skip, LPCSTR fmt, va_list p)
{
if (bCheckDevice && (!RDEVICE.b_is_Active))
Expand Down Expand Up @@ -207,13 +320,22 @@ void __cdecl CGameFont::OutNext(LPCSTR fmt, ...) { MASTER_OUT(TRUE, FALSE, FALSE

void CGameFont::OutSkip(float val) { fCurrentY += val * CurrentHeight_(); }

float CGameFont::SizeOf_(const char cChar) { return (GetCharTC((u16)(u8)(cChar)).z * vInterval.x * GetWidthScale()); }
float CGameFont::SizeOf_(const char cChar) { return (GetCharTC((u16)(u8)(((IsMultibyte() && cChar == ' ')) ? 0 : cChar)).z * vInterval.x * GetWidthScale()); }

float CGameFont::SizeOf_(LPCSTR s)
{
if (!(s && s[0]))
return 0;

if (IsMultibyte())
{
wide_char wsStr[MAX_MB_CHARS];

mbhMulti2Wide(wsStr, NULL, MAX_MB_CHARS, s);

return SizeOf_(wsStr);
}

int len = xr_strlen(s);
float X = 0;
if (len)
Expand All @@ -223,6 +345,26 @@ float CGameFont::SizeOf_(LPCSTR s)
return (X * vInterval.x) * GetWidthScale();
}

float CGameFont::SizeOf_(const wide_char* wsStr)
{
if (!(wsStr && wsStr[0]))
return 0;

unsigned int len = wsStr[0];
float X = 0.0f, fDelta = 0.0f;

if (len)
for (unsigned int j = 1; j <= len; j++)
{
fDelta = GetCharTC(wsStr[j]).z - 2;
if (IsNeedSpaceCharacter(wsStr[j]))
fDelta += fXStep;
X += fDelta;
}

return (X * vInterval.x);
}

float CGameFont::CurrentHeight_() { return fCurrentHeight * vInterval.y * GetHeightScale(); }

void CGameFont::SetHeightI(float S)
Expand Down
Loading

0 comments on commit b63c07e

Please sign in to comment.