metaforce/Runtime/GuiSys/CRasterFont.cpp

211 lines
6.2 KiB
C++
Raw Normal View History

2016-03-11 22:52:55 +00:00
#include "GuiSys/CRasterFont.hpp"
2016-03-19 00:07:31 +00:00
#include "CDrawStringOptions.hpp"
#include "CTextRenderBuffer.hpp"
2016-03-22 18:35:52 +00:00
#include "Graphics/CTexture.hpp"
2016-12-23 06:41:39 +00:00
#include "CSimplePool.hpp"
2016-03-11 22:52:55 +00:00
namespace urde
{
CRasterFont::CRasterFont(urde::CInputStream& in, urde::IObjectStore& store)
{
2016-03-18 02:22:19 +00:00
u32 magic;
in.readBytesToBuf(&magic, 4);
if (magic != SBIG('FONT'))
return;
u32 version = in.readUint32Big();
x4_monoWidth = in.readUint32Big();
x8_monoHeight = in.readUint32Big();
if (version >= 1)
x8c_baseline = in.readUint32Big();
else
x8c_baseline = x8_monoHeight;
if (version >= 2)
2016-03-17 20:21:08 +00:00
x90_lineMargin = in.readUint32Big();
bool tmp1 = in.readBool();
bool tmp2 = in.readBool();
u32 tmp3 = in.readUint32Big();
u32 tmp4 = in.readUint32Big();
std::string name= in.readString();
u32 txtrId = in.readUint32Big();
x30_fontInfo = CFontInfo(tmp1, tmp2, tmp3, tmp4, name.c_str());
2016-08-17 05:40:25 +00:00
x80_texture = store.GetObj({FOURCC('TXTR'), txtrId});
2016-03-23 20:38:01 +00:00
x2c_mode = EColorType(in.readUint32Big());
u32 glyphCount = in.readUint32Big();
xc_glyphs.reserve(glyphCount);
for (u32 i = 0 ; i < glyphCount ; ++i)
{
2017-01-24 07:41:33 +00:00
char16_t chr = in.readUint16Big();
float startU = in.readFloatBig();
float startV = in.readFloatBig();
float endU = in.readFloatBig();
float endV = in.readFloatBig();
s32 a = in.readInt32Big();
s32 b = in.readInt32Big();
s32 c = in.readInt32Big();
s32 cellWidth = in.readInt32Big();
s32 cellHeight = in.readInt32Big();
s32 baseline = in.readInt32Big();
2016-03-18 02:22:19 +00:00
s32 kernStart = in.readInt32Big();
2017-01-22 09:06:03 +00:00
xc_glyphs.push_back(std::make_pair(chr, CGlyph(a, b, c, startU, startV, endU, endV,
cellWidth, cellHeight, baseline, kernStart)));
}
std::sort(xc_glyphs.begin(), xc_glyphs.end(), [=](auto& a, auto& b) -> bool{
return a.first < b.first;
});
u32 kernCount = in.readUint32Big();
x1c_kerning.reserve(kernCount);
for (u32 i = 0 ; i < kernCount ; ++i)
{
2017-01-24 07:41:33 +00:00
char16_t first = in.readUint16Big();
char16_t second = in.readUint16Big();
2017-02-01 07:20:18 +00:00
s32 howMuch = in.readInt32Big();
2017-01-22 09:06:03 +00:00
x1c_kerning.emplace_back(first, second, howMuch);
}
2016-03-23 20:38:01 +00:00
if (magic == SBIG('FONT') && version <= 2)
x0_initialized = true;
2016-03-11 22:52:55 +00:00
}
2016-03-16 19:53:06 +00:00
void CRasterFont::SinglePassDrawString(const CDrawStringOptions& opts, int x, int y, int& xout, int& yout,
2017-02-01 07:20:18 +00:00
CTextRenderBuffer* renderBuf, const char16_t* str, s32 length) const
2016-03-16 19:53:06 +00:00
{
2016-03-23 20:38:01 +00:00
if (!x0_initialized)
2016-03-16 19:53:06 +00:00
return;
2017-01-24 07:41:33 +00:00
const char16_t* chr = str;
2016-03-16 20:53:38 +00:00
const CGlyph* prevGlyph = nullptr;
2017-01-24 07:41:33 +00:00
while (*chr != u'\0')
2016-03-16 19:53:06 +00:00
{
2016-03-16 20:53:38 +00:00
const CGlyph* glyph = GetGlyph(*chr);
2016-03-16 19:53:06 +00:00
if (glyph)
{
2016-03-20 06:37:08 +00:00
if (opts.x0_direction == ETextDirection::Horizontal)
2016-03-16 19:53:06 +00:00
{
2017-01-29 03:58:16 +00:00
x += glyph->GetLeftPadding();
2016-03-16 19:53:06 +00:00
if (prevGlyph != 0)
x += KernLookup(x1c_kerning, prevGlyph->GetKernStart(), *chr);
int left = 0;
int top = 0;
if (renderBuf)
{
left += x;
2017-01-29 03:58:16 +00:00
top += y - glyph->GetBaseline();
2017-01-30 04:16:20 +00:00
renderBuf->AddCharacter(zeus::CVector2i(left, top), *chr, opts.x4_colors[2]);
2016-03-16 19:53:06 +00:00
}
2017-01-29 03:58:16 +00:00
x += glyph->GetRightPadding() + glyph->GetAdvance();
2016-03-16 19:53:06 +00:00
}
}
prevGlyph = glyph;
chr++;
if (length == -1)
continue;
2017-01-29 03:58:16 +00:00
if ((chr - str) >= length)
2016-03-16 19:53:06 +00:00
break;
}
xout = x;
yout = y;
}
void CRasterFont::DrawSpace(const CDrawStringOptions& opts, int x, int y, int& xout, int& yout, int len) const
{
2016-03-20 06:37:08 +00:00
if (opts.x0_direction != ETextDirection::Horizontal)
2016-03-16 19:53:06 +00:00
return;
xout = x + len;
yout = y;
}
2017-01-24 07:41:33 +00:00
void CRasterFont::DrawString(const CDrawStringOptions& opts, int x, int y, int& xout, int& yout,
CTextRenderBuffer* renderBuf, const char16_t* str, int len) const
2016-03-16 19:53:06 +00:00
{
2016-03-23 20:38:01 +00:00
if (!x0_initialized)
2016-03-16 19:53:06 +00:00
return;
if (renderBuf)
{
/* CGraphicsPalette pal = CGraphicsPalette::CGraphcisPalette(2, 4); */
/* zeus::CColor color = zeus::CColor(0.f, 0.f, 0.f, 0.f) */
/* tmp = color.ToRGB5A3(); */
/* tmp2 = opts.x8_.ToRGB5A3(); */
/* tmp3 = opts.xc_.ToRGB5A3(); */
/* tmp4 = zeus::CColor(0.f, 0.f, 0.f, 0.f); */
/* tmp5 = tmp4.ToRGBA5A3(); */
/* pal.UnLock(); */
/* renderBuf->AddPaletteChange(pal); */
2017-01-30 04:16:20 +00:00
renderBuf->AddPaletteChange(opts.x4_colors[0], opts.x4_colors[1]);
2016-03-16 19:53:06 +00:00
}
SinglePassDrawString(opts, x, y, xout, yout, renderBuf, str, len);
}
2017-01-24 07:41:33 +00:00
void CRasterFont::GetSize(const CDrawStringOptions& opts, int& width, int& height, const char16_t* str, int len) const
2016-03-16 19:53:06 +00:00
{
width = 0;
height = 0;
2017-01-24 07:41:33 +00:00
const char16_t* chr = str;
2016-03-16 20:53:38 +00:00
const CGlyph* prevGlyph = nullptr;
2016-03-16 19:53:06 +00:00
int prevWidth = 0;
2017-01-24 07:41:33 +00:00
while (*chr != u'\0')
2016-03-16 19:53:06 +00:00
{
2016-03-16 20:53:38 +00:00
const CGlyph* glyph = GetGlyph(*chr);
2016-03-16 19:53:06 +00:00
if (glyph)
{
2016-03-20 06:37:08 +00:00
if (opts.x0_direction == ETextDirection::Horizontal)
2016-03-16 19:53:06 +00:00
{
int advance = 0;
if (prevGlyph)
advance = KernLookup(x1c_kerning, prevGlyph->GetKernStart(), *chr);
2017-01-29 03:58:16 +00:00
int curWidth = prevWidth + (glyph->GetLeftPadding() + glyph->GetAdvance() + glyph->GetRightPadding() + advance);
int curHeight = glyph->GetBaseline() - (x8_monoHeight + glyph->GetCellHeight());
2016-03-16 19:53:06 +00:00
width = curWidth;
prevWidth = curWidth;
if (curHeight > height)
height = curHeight;
}
}
prevGlyph = glyph;
chr++;
2016-03-16 20:39:07 +00:00
if (len == -1)
2016-03-16 19:53:06 +00:00
continue;
2017-01-29 03:58:16 +00:00
if ((chr - str) >= len)
2016-03-16 19:53:06 +00:00
break;
}
}
2017-01-30 04:16:20 +00:00
bool CRasterFont::IsFinishedLoading() const
{
if (!x80_texture || !x80_texture.IsLoaded())
return false;
return true;
}
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef)
2016-03-12 05:10:14 +00:00
{
2016-12-23 06:41:39 +00:00
CSimplePool* sp = vparms.GetOwnedObj<CSimplePool*>();
return TToken<CRasterFont>::GetIObjObjectFor(std::make_unique<CRasterFont>(in, *sp));
2016-03-12 05:10:14 +00:00
}
2016-03-11 22:52:55 +00:00
}