commit x64 compilation from lulu cause the other branch dont seems to compile properly at home
This commit is contained in:
193
include/engine/core/raster_font.cpp
Normal file
193
include/engine/core/raster_font.cpp
Normal file
@ -0,0 +1,193 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "core/raster_font.h"
|
||||
#include "core/render_resource_factory.h"
|
||||
#include "metafile/nml.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace GS;
|
||||
using namespace GS::Render;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
float RasterFont::GetHeight(bool normalized) const
|
||||
{
|
||||
if (normalized)
|
||||
return height;
|
||||
return GetPage(0) ? height * GetPage(0)->GetWidth() : -1;
|
||||
}
|
||||
float RasterFont::GetBaseline(bool normalized) const
|
||||
{
|
||||
if (normalized)
|
||||
return baseline;
|
||||
return GetPage(0) ? baseline * GetPage(0)->GetWidth() : -1;
|
||||
}
|
||||
Vector2 RasterFont::ComputeLineRect(const char *s, bool normalized) const
|
||||
{
|
||||
Vector2 r(0, height);
|
||||
for ( ; s[0] && s[0] != '\n'; ++s)
|
||||
if (const Glyph *c = GetGlyphInfos(s[0]))
|
||||
r.x += c->step;
|
||||
|
||||
if (!normalized)
|
||||
{
|
||||
if (GetPage(0))
|
||||
{
|
||||
r.x *= GetPage(0)->GetWidth();
|
||||
r.y *= GetPage(0)->GetHeight();
|
||||
}
|
||||
else
|
||||
r.Set(-1, -1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
Vector2 RasterFont::ComputeStringRect(const char *s, bool normalized) const
|
||||
{
|
||||
Vector2 r(0, 0);
|
||||
|
||||
forever
|
||||
{
|
||||
float w = 0; // Line width.
|
||||
for ( ; s[0] && s[0] != '\n'; ++s)
|
||||
if (const Glyph *c = GetGlyphInfos(s[0]))
|
||||
w += c->step;
|
||||
|
||||
if (w > r.x) // Largest width.
|
||||
r.x = w;
|
||||
r.y += height; // Line height.
|
||||
|
||||
if (!s[0])
|
||||
break;
|
||||
++s; // Jump over the line feed.
|
||||
}
|
||||
|
||||
if (!normalized)
|
||||
{
|
||||
if (GetPage(0))
|
||||
{
|
||||
r.x *= GetPage(0)->GetWidth();
|
||||
r.y *= GetPage(0)->GetHeight();
|
||||
}
|
||||
else
|
||||
r.Set(-1, -1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Texture *RasterFont::GetPage(uint page) const
|
||||
{ return (page < pages.GetCount()) ? pages.ObjectAt(page) : NULL; }
|
||||
const RasterFont::Glyph *RasterFont::GetGlyphInfos(uchar index) const
|
||||
{ return glyph[index].available ? &glyph[index] : NULL; }
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool RasterFont::Load(ResourceFactory &rf, const char *nml, const char *base)
|
||||
{
|
||||
Unload();
|
||||
|
||||
//-----------------------------------------------------------
|
||||
#define RFL_ERROR(l) { (l); Unload(); return false; }
|
||||
//-----------------------------------------------------------
|
||||
|
||||
using namespace GS::NML;
|
||||
|
||||
File file;
|
||||
if (!Parser::Load(nml, file))
|
||||
RFL_ERROR(__LOG_E__ << "Failed to load raster font description file '" << nml << "'.\n")
|
||||
|
||||
// Load font settings.
|
||||
Tag *root = file.GetTag("Font:Common;");
|
||||
if (!root)
|
||||
RFL_ERROR(__LOG_E__ << "Missing base tag in font description ('" << nml << "').\n")
|
||||
|
||||
uint page_count = 1;
|
||||
|
||||
NMLTagForeach(tag, *root)
|
||||
{
|
||||
if (tag->name == "Height")
|
||||
height = tag->GetReal();
|
||||
else if (tag->name == "BaseLine")
|
||||
baseline = tag->GetReal();
|
||||
else if (tag->name == "PageCount")
|
||||
page_count = tag->GetInteger();
|
||||
else __LOG_W__ << "Unexpected tag in font description header ('" << tag->name << "').\n";
|
||||
}
|
||||
|
||||
// Parse glyphs...
|
||||
root = file.GetTag("Font;");
|
||||
|
||||
NMLTagForeach(tag, *root)
|
||||
if (tag->name == "Char")
|
||||
{
|
||||
Tag *wrk = tag->GetTag("Id;");
|
||||
if (!wrk || (wrk->GetType() != Variant::VariantInteger))
|
||||
{
|
||||
__LOG_W__ << "Glyph with no or invalid ID in font '" << nml << "', skipping.\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
int glyphidx = wrk->GetInteger();
|
||||
if (glyphidx > 255)
|
||||
continue;
|
||||
|
||||
Glyph *pglyph = &glyph[glyphidx];
|
||||
pglyph->page = 0;
|
||||
pglyph->available = true;
|
||||
|
||||
NMLTagForeach(wrk, *tag)
|
||||
{
|
||||
if (wrk->name == "U")
|
||||
pglyph->u = wrk->GetReal();
|
||||
else if (wrk->name == "V")
|
||||
pglyph->v = wrk->GetReal();
|
||||
else if (wrk->name == "W")
|
||||
pglyph->w = wrk->GetReal();
|
||||
else if (wrk->name == "H")
|
||||
pglyph->h = wrk->GetReal();
|
||||
else if (wrk->name == "OffsetU")
|
||||
pglyph->offx = wrk->GetReal();
|
||||
else if (wrk->name == "OffsetV")
|
||||
pglyph->offy = wrk->GetReal();
|
||||
else if (wrk->name == "Step")
|
||||
pglyph->step = wrk->GetReal();
|
||||
else if (wrk->name == "Page")
|
||||
{
|
||||
if ((wrk->GetType() == Variant::VariantInteger) && ((uint)wrk->GetInteger() < page_count))
|
||||
pglyph->page = wrk->GetInteger();
|
||||
|
||||
else
|
||||
{
|
||||
__LOG_W__ << "Invalid glyph page in font '" << nml << "' (Glyph #" << glyphidx << "), skipping.\n";
|
||||
pglyph->available = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check...
|
||||
if (!glyph[' '].available)
|
||||
__LOG_W__ << "No space character in font '" << nml << "'.\n";
|
||||
|
||||
// Load font pages.
|
||||
for (uint n = 0; n < page_count; n++)
|
||||
if (Texture *t = rf.LoadTexture(String::Format("%s_%02d.tga", base, n)))
|
||||
pages.Add(t);
|
||||
|
||||
name = nml;
|
||||
return true;
|
||||
}
|
||||
void RasterFont::Unload()
|
||||
{
|
||||
pages.Clear();
|
||||
for (uint n = 0; n < 256; n++)
|
||||
glyph[n].Reset();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user