Program Listing for File fonts.cpp¶
↰ Return to documentation for file (blam\components\content\fonts\fonts.cpp
)
#include "fonts.h"
#include <fstream>
#include "components/rendering/rendering.h"
#include "components/rendering/directx11/direct2d/drawing.h"
#include "components/rendering/directx11/dw_font_loader/FontLoader.h"
#include "components/3rdparty/rapidxml/rapidxml.hpp"
#include "components/core/utils/converters/converters.h"
#include "components/core/utils/string/string.h"
#include "components/core/utils/io/io.h"
#include "components/core/logger/logger.h"
#include "components/core/error/error.h"
#include "components/core/cache/cache.h"
#include "components/core/config/config.h"
#include "res/mc/errors.h"
using namespace Blam::Content::Fonts;
using namespace rapidxml;
std::map<std::string, Font> font_list;
bool Blam::Content::Fonts::FontExists(std::string id)
{
std::map<std::string, Font>::iterator it;
for (it = font_list.begin(); it != font_list.end(); it++)
{
if (it->first == id)
{
return true;
}
}
return false;
}
HRESULT LoadGlyph(char character, int width, int height, std::string bitmap_path, std::string format, Font* font);
bool resolve_glyph_character(std::string xml_glyph, char* character);
HRESULT Blam::Content::Fonts::LoadFont(std::string path)
{
HRESULT hr = S_OK;
Font new_font;
new_font.path = path;
std::string xml_path = path + "/" + FONTINFO_FILENAME;
std::string bin_path = path + FONT_PACKAGE_EXTENSION;
if (Blam::Utils::IO::file_exists(xml_path))
{
new_font.is_font_package = false;
new_font.file_path = xml_path;
//load as XML unpackaged font
xml_document<> font_xml_file;
//read file into vector buffer
std::ifstream font_file(new_font.file_path);
std::vector<char> buffer((std::istreambuf_iterator<char>(font_file)), std::istreambuf_iterator<char>());
buffer.push_back('\0');
//load document
font_xml_file.parse<0>(&buffer[0]);
//get root node
xml_node<>* root_node = font_xml_file.first_node("fontinfo");
Blam::Logger::LogEvent("### begin dumping font XML file text to console ###");
Blam::Logger::LogEvent(std::string(buffer.begin(), buffer.end()));
Blam::Logger::LogEvent("### end dumping font XML file text to console ###");
bool valid_font = true;
xml_node<>* properties_node = root_node->first_node("properties");
//xml attributes
xml_node<>* id_element = properties_node->first_node("id");
xml_node<>* size_element = properties_node->first_node("size");
xml_node<>* charspacing_element = properties_node->first_node("charspacing");
xml_node<>* monospace_element = properties_node->first_node("monospace");
xml_node<>* monospace_width = properties_node->first_node("monowidth");
xml_node<>* space_width = properties_node->first_node("spacewidth");
xml_node<>* truetype = properties_node->first_node("truetype");
xml_node<>* ttf_path = properties_node->first_node("ttf_path");
xml_node<>* ttf_name = properties_node->first_node("ttf_name");
//id
if (id_element)
{
if (!FontExists(id_element->value()))
{
new_font.id = id_element->value();
}
else
{
valid_font = false;
Blam::Logger::LogEvent("### WARNING tried to load a font with duplicate id " + std::string(id_element->value()) + ". font will NOT be loaded!", true, WSV_ERROR);
}
}
else
{
valid_font = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' fontinfo is missing id element! font will NOT be loaded!", true, WSV_ERROR);
}
// truetype element
if (truetype)
{
new_font.is_truetype = Blam::Converters::StringToBool(truetype->value());
}
else
{
new_font.is_truetype = false;
}
// if truetype is enabled, ensure ttf file exists
if (new_font.is_truetype)
{
if (ttf_path)
{
new_font.ttf_path = path + "/" + ttf_path->value();
if (!Blam::Utils::IO::file_exists(new_font.ttf_path))
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' ttf_path element referenced an invalid file. font will NOT be loaded!", WSV_WARNING);
valid_font = false;
}
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' ttf_path element was not found, but truetype was set to true. font will NOT be loaded!", WSV_WARNING);
valid_font = false;
}
if (ttf_name)
{
new_font.ttf_name = ttf_name->value();
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' ttf_name element was not found, but truetype was set to true. substituting id for font name, this may cause the font to fail to display correctly", WSV_WARNING);
}
}
else
{
//get size value
if (size_element)
{
try
{
new_font.size = std::stoi(size_element->value());
}
catch (std::invalid_argument ex)
{
valid_font = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' size element (" + size_element->value() + ") was in a bad format (std::invalid_argument thrown). font will NOT be loaded!", true, WSV_ERROR);
}
catch (std::out_of_range ex)
{
valid_font = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' size element (" + size_element->value() + ") caused an overflow (std::out_of_range thrown). font will NOT be loaded!", true, WSV_ERROR);
}
}
else
{
valid_font = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' fontinfo is missing size element! font will NOT be loaded!", true, WSV_ERROR);
}
//get charspacing value
if (charspacing_element)
{
try
{
new_font.charspacing = std::stoi(charspacing_element->value());
}
catch (std::invalid_argument ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' charspacing element (" + charspacing_element->value() + ") was in a bad format (std::invalid_argument thrown). defaulting charspacing to 0, this may cause unexpected results.", true, WSV_WARNING);
new_font.charspacing = 0;
}
catch (std::out_of_range ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' charspacing element (" + charspacing_element->value() + ") caused an overflow (std::out_of_range thrown). defaulting charspacing to 0, this may cause unexpected results.", true, WSV_WARNING);
new_font.charspacing = 0;
}
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' fontinfo is missing charspacing element! defaulting to 0, this may cause unexpected results.", true, WSV_WARNING);
new_font.charspacing = 0;
}
//get monospaced value
if (monospace_element)
{
std::string monospace_str = Blam::Utils::String::to_lower(monospace_element->value());
if (monospace_str == "false" || monospace_str == "0" || monospace_str == "no")
{
new_font.monospaced = false;
}
else if (monospace_str == "true" || monospace_str == "1" || monospace_str == "yes")
{
new_font.monospaced = true;
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' fontinfo has invalid monospace element! defaulting to FALSE, this may cause unexpected results.", true, WSV_WARNING);
new_font.monospaced = false;
}
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' fontinfo is missing monospace element! defaulting to FALSE, this may cause unexpected results.", true, WSV_WARNING);
new_font.monospaced = false;
}
bool use_spacewidth_element = true;
//get monowidth value if monospaced
if (monospace_width)
{
try
{
new_font.mono_width = std::stoi(monospace_width->value());
new_font.space_width = new_font.mono_width;
use_spacewidth_element = false;
}
catch (std::invalid_argument ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' monowidth element (" + monospace_width->value() + ") was in a bad format (std::invalid_argument thrown). setting monospace to FALSE, this may cause unexpected results.", true, WSV_WARNING);
new_font.mono_width = 0;
new_font.monospaced = false;
}
catch (std::out_of_range ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' monowidth element (" + monospace_width->value() + ") caused an overflow (std::out_of_range thrown). setting monospace to FALSE, this may cause unexpected results.", true, WSV_WARNING);
new_font.mono_width = 0;
new_font.monospaced = false;
}
}
else
{
if (new_font.monospaced)
{
Blam::Logger::LogEvent("### ERROR unpackaged font at '" + path + "' fontinfo is missing monowidth element, but has monospace set to true. setting monospace to FALSE, this may cause unexpected results.", true, WSV_ERROR);
}
new_font.monospaced = false;
new_font.mono_width = 0;
}
if (use_spacewidth_element)
{
if (space_width)
{
try
{
new_font.space_width = std::stoi(space_width->value());
}
catch (std::invalid_argument ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' spacewidth element (" + space_width->value() + ") was in a bad format (std::invalid_argument thrown). setting space_width to 6, this may cause unexpected results.", true, WSV_WARNING);
new_font.space_width = 6;
}
catch (std::out_of_range ex)
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' spacewidth element (" + space_width->value() + ") caused an overflow (std::out_of_range thrown). setting space_width to 6, this may cause unexpected results.", true, WSV_WARNING);
new_font.space_width = 6;
}
}
else
{
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' spacewidth element was not found. setting space_width to 6, this may cause unexpected results.", true, WSV_ERROR);
new_font.space_width = 6;
}
}
else
{
new_font.space_width = 0;
}
}
if (valid_font)
{
if (new_font.is_truetype)
{
using namespace BlamRendering::DirectX::D2D::MF;
HRESULT hr = BlamRendering::DirectX::D2D::LoadFontFromFile(new_font.id, new_font.ttf_path);
}
else
{
xml_node<>* glyphs_node = root_node->first_node("glyphs");
for (xml_node<>* glyph_node = glyphs_node->first_node("glyph"); glyph_node; glyph_node = glyph_node->next_sibling())
{
//<glyph char="a" width="16" height="16" bitmap="./glyphs/a.png" format="PNG"></glyph>
xml_attribute<char>* character_attr = glyph_node->first_attribute("char");
xml_attribute<char>* width_attr = glyph_node->first_attribute("width");
xml_attribute<char>* height_attr = glyph_node->first_attribute("height");
xml_attribute<char>* bitmap_attr = glyph_node->first_attribute("bitmap");
xml_attribute<char>* format_attr = glyph_node->first_attribute("format");
char character = NULL;
int width = 0;
int height = 0;
std::string bitmap_path = "";
std::string format = "";
bool valid_glyph = true;
//get character attribute
if (character_attr)
{
char* e = character_attr->value();
bool resolve_result = resolve_glyph_character(e, &character);
if (!resolve_result)
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph an invalid character attribute (" + character_attr->value() + ")! glyph will NOT be loaded!", true, WSV_ERROR);
}
}
else
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph with no character attribute! glyph will NOT be loaded!", true, WSV_ERROR);
}
//get glyph width attribute
if (width_attr)
{
try
{
width = std::stoi(width_attr->value());
}
catch (std::invalid_argument ex)
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' glyph width (" + width_attr->value() + ") attribute was in a bad format (std::invalid_argument thrown). glyph will NOT be loaded!", true, WSV_ERROR);
}
catch (std::out_of_range ex)
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' glyph width (" + width_attr->value() + ") attribute caused an overflow (std::out_of_range thrown). glyph will NOT be loaded!", true, WSV_ERROR);
}
}
else
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph with no width attribute! glyph will NOT be loaded!", true, WSV_ERROR);
}
//get glyph height attribute
if (height_attr)
{
try
{
height = std::stoi(height_attr->value());
}
catch (std::invalid_argument ex)
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' glyph height attribute (" + height_attr->value() + ") was in a bad format (std::invalid_argument thrown). glyph will NOT be loaded!", true, WSV_ERROR);
}
catch (std::out_of_range ex)
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' glyph height attribute (" + height_attr->value() + ") caused an overflow (std::out_of_range thrown). glyph will NOT be loaded!", true, WSV_ERROR);
}
}
else
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph with no height attribute! glyph will NOT be loaded!", true, WSV_ERROR);
}
//get bitmap path attribute
if (bitmap_attr)
{
const char* what_the_fuck = bitmap_attr->value();
bitmap_path = std::string(what_the_fuck);
}
else
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph with no bitmap attribute! glyph will NOT be loaded!", true, WSV_ERROR);
}
//get file format attribute
if (format_attr)
{
format = *format_attr->value();
}
else
{
valid_glyph = false;
Blam::Logger::LogEvent("### WARNING unpackaged font at '" + path + "' contains a glyph with no format attribute! glyph will NOT be loaded!", true, WSV_ERROR);
}
//if the glyph is valid, try and load as bitmap
if (valid_glyph)
{
HRESULT glyph_hr = LoadGlyph(character, width, height, bitmap_path, format, &new_font);
if (SUCCEEDED(glyph_hr))
{
int e = 0;
}
else
{
int e = 0;
}
}
else
{
hr = BL_S_FONT_LOADED_OK_BAD_GLYPHS;
Blam::Logger::LogEvent("### ERROR one or more required glyph properties were invalid. check the <glpyhs> section of your fontinfo.xml at: '" + path + "'", true, WSV_ERROR);
}
}
}
}
else
{
hr = BL_E_FONT_INVALID_DATA;
Blam::Logger::LogEvent("### ERROR one or more required fontinfo properties were invalid. check your fontinfo.xml at: '" + path + "'", true, WSV_ERROR);
}
Blam::Logger::LogEvent("loaded uncompressed font '" + new_font.id + "' (" + path + "), contains " + std::to_string(new_font.glyph_list.size()) + " glyphs" , true, WSV_NONE);
font_list.insert(std::pair<std::string, Font>(new_font.id, new_font));
}
else if (Blam::Utils::IO::file_exists(bin_path))
{
new_font.is_font_package = true;
// Load as font package
std::ifstream font_package;
font_package.open(bin_path, std::ios::in | std::ios::binary);
char header[0x400];
font_package.read(header, 0x400);
// Ensure we're actually reading a blamite font package, and someone isnt trying to load a blam! package
if (memcmp(&header[0x0], "BFNT", 0x4) == 0)
{
// continue assuming the file is of a valid type
Blam::Logger::LogEvent("font package header seems valid - continuing");
// Header properties
char package_engine_version[0x20];
int ttf_file_length = 0;
int ttf_file_offset = 0;
memcpy(&new_font.package_version, &header[0x26], 0x2);
memcpy(&package_engine_version, &header[0x11C], 0x1F);
package_engine_version[0x1F] = NULL; //ensure string is null-terminated
if (new_font.package_version > FONT_PACKAGE_VERSION)
{
Blam::Logger::LogEvent("### WARNING font package at " + path + " has version newer than what the engine supports, this may cause unexpected results", WSV_WARNING);
}
// Load font properties after ensuring that package version is ok
{
memcpy(&ttf_file_length, &header[0x170], 0x4);
memcpy(&ttf_file_offset, &header[0x180], 0x4);
char font_id[0x20];
memcpy(&font_id, &header[0x17F], 0x1F);
font_id[0x1F] = NULL;
new_font.id = std::string(font_id);
memcpy(&new_font.is_truetype, &header[0x1A0], 0x1);
memcpy(&new_font.monospaced, &header[0x1A1], 0x1);
memcpy(&new_font.size, &header[0x1A2], 0x2);
memcpy(&new_font.mono_width, &header[0x1A4], 0x2);
memcpy(&new_font.charspacing, &header[0x1A6], 0x2);
memcpy(&new_font.space_width, &header[0x1A8], 0x2);
char ttf_display_name[0x20];
memcpy(&ttf_display_name, &header[0x1AA], 0x1F);
ttf_display_name[0x1F] = NULL;
new_font.ttf_name = std::string(ttf_display_name);
new_font.package_engine_version = std::string(package_engine_version);
}
if (new_font.is_truetype)
{
memcpy(&new_font.ttf_length, &header[0x170], 0x4);
memcpy(&new_font.ttf_offset, &header[0x174], 0x4);
void* font_data = malloc(new_font.ttf_length);
font_package.seekg(new_font.ttf_offset);
font_package.read((char*)font_data, new_font.ttf_length);
std::string cached_file_path = Blam::Cache::WriteFileToCache(font_data, new_font.ttf_length, new_font.id);
free(font_data);
BlamRendering::DirectX::D2D::LoadFontFromFile(new_font.id, cached_file_path);
}
else
{
std::vector<char> char_list;
// Read character list
{
char character_list[0x40000];
font_package.read(character_list, 0x40000);
// this is how wchar_t is stored in memory
// 65 00
for (int i = 0; i < 0x40000; i = i + 0x4)
{
char glyph[0x4];
memcpy(&glyph, &character_list[i], 0x4);
if (glyph[1] != 0x0 || glyph[2] == 0x0 || glyph[3] != 0x0)
{
Blam::Logger::LogEvent("### WARNING unicode and wide characters are not supported at this time", WSV_WARNING);
}
if (glyph[0] == 0x0 && i != 0x0)
{
//if we reach null and we aren't at the start of the list, we can assume that character list has ended
break;
}
char_list.push_back(glyph[0x0]);
}
}
// Read index table
{
const int index_size = 0x10;
for (int i = 0; i < char_list.size(); i++)
{
char index_entry[index_size];
byte format;
int pos = font_package.tellg();
font_package.read(index_entry, index_size);
FontGlyph glyph;
glyph.character = char_list.at(i);
memcpy(&glyph.width, &index_entry[0x0], 0x2);
memcpy(&glyph.height, &index_entry[0x2], 0x2);
memcpy(&glyph.data_length, &index_entry[0x4], 0x4);
memcpy(&format, &index_entry[0x9], 0x1);
if (format == 0x0)
{
glyph.format = FontGlyphFormat::PNG;
}
else
{
Blam::Logger::LogEvent("### ERROR unreciognized glyph format 0x" + std::to_string(format), WSV_ERROR);
}
memcpy(&glyph.data_offset, &index_entry[0xC], 0x4);
new_font.glyph_list.insert(std::pair<char, FontGlyph>(glyph.character, glyph));
}
}
// Read bitmap data
{
std::map<char, FontGlyph>::iterator it;
for (it = new_font.glyph_list.begin(); it != new_font.glyph_list.end(); it++)
{
FontGlyph glyph = it->second;
glyph.bitmap_data = malloc(glyph.data_length);
font_package.seekg(glyph.data_offset);
font_package.read((char*)glyph.bitmap_data, glyph.data_length);
BlamRendering::DirectX::WIC::CreateWICBitmapFromMemory(glyph.bitmap_data, glyph.data_length, &glyph.bitmap);
it->second = glyph;
}
}
}
Blam::Logger::LogEvent("loaded font package '" + new_font.id + "' (" + path + "), contains " + std::to_string(new_font.glyph_list.size()) + " glyphs", true, WSV_NONE);
font_list.insert(std::pair<std::string, Font>(new_font.id, new_font));
}
else
{
Blam::Logger::LogEvent("### ERROR font package header appears to be invalid - aborting font load", WSV_ERROR);
hr = E_FAIL;
}
font_package.close();
}
else
{
Blam::Logger::LogEvent("### ERROR tried to load font at '" + path + "', could not find file", true, WSV_ERROR);
}
return hr;
}
FontGlyphFormat GetGlyphFormatFromString(std::string format)
{
if (format == "PNG")
{
return FontGlyphFormat::PNG;
}
else
{
return FontGlyphFormat::PNG;
}
}
HRESULT LoadGlyph(char character, int width, int height, std::string bitmap_path, std::string format, Font* font)
{
ID2D1DeviceContext* target = BlamRendering::DirectX::D2D::GetD2DRenderTarget();
ID2D1Factory* factory = BlamRendering::DirectX::D2D::GetD2DFactory();
//create a new glyph
FontGlyph glyph;
glyph.width = width;
glyph.height = height;
//BlamRendering::DirectX::WIC::CreateD2DBitmapFromResource(IDB_THEME_DEFAULT_ICON, "PNG", width, height, &glyph.bitmap);
glyph.character = character;
glyph.format = GetGlyphFormatFromString(format);
glyph.path = bitmap_path;
glyph.file_path = font->path + "/" + bitmap_path;
bool file_exists = Blam::Utils::IO::file_exists(glyph.file_path);
if (file_exists)
{
HRESULT hr = BlamRendering::DirectX::WIC::CreateWICBitmapFromFile(Blam::Converters::ConvertStringToWstring(glyph.file_path), &glyph.bitmap);
if (SUCCEEDED(hr))
{
font->glyph_list.insert(std::pair<char, FontGlyph>(character, glyph));
return S_OK;
}
else
{
Blam::Logger::LogEvent("### ERROR unpackaged font at '" + font->path + "' glyph " + glyph.character + "' encountered an error while trying to load glyph image as ID2D1Bitmap:", true, WSV_ERROR);
Blam::Logger::LogEvent("" + std::string(Blam::Error::GetStringFromHResult(hr)), true, WSV_ERROR);
return hr;
}
}
else
{
Blam::Logger::LogEvent("### ERROR unpackaged font at '" + font->path + "' glyph " + glyph.character + "' points to a file image that does not exist! glyph will NOT be loaded!", true, WSV_ERROR);
return BL_W_GLYPH_FILE_NOT_FOUND;
}
}
bool resolve_glyph_character(std::string xml_glyph, char* character)
{
std::string glyph_str = "";
if (Blam::Utils::String::starts_with_ci(xml_glyph, "lower_"))
{
//handle as lowercase letter
std::string letter = Blam::Utils::String::split(xml_glyph, "_").at(1);
glyph_str = Blam::Utils::String::to_lower(letter);
}
else if (Blam::Utils::String::starts_with_ci(xml_glyph, "0x"))
{
//handle as special character defined by hex code
return Blam::Converters::HexStringToChar(xml_glyph, character);
}
else
{
glyph_str = xml_glyph;
}
//read string as a regular character
if (glyph_str.length() == 1)
{
//char c = glyph_str.c_str()[0];
memcpy(character, &glyph_str.at(0), 1);
//character = &glyph_str.at(0);
/*
#############################################
# maybe the string gets nuked and as such it fucks itself completely
# idk man you figure it out
#############################################
*/
//memcpy(character, glyph_str.at(0), 1);
//character = &c;
return true;
}
else
{
return false;
}
}
Font* Blam::Content::Fonts::GetFont(std::string id)
{
std::map<std::string, Font>::iterator iter = font_list.find(id);
if (iter != font_list.end())
{
return &iter->second;
}
else
{
return nullptr;
}
}
FontGlyph* Blam::Content::Fonts::GetFontGlyph(Font* font, char glyph)
{
std::map<char, FontGlyph>::iterator iter = font->glyph_list.find(glyph);
if (iter != font->glyph_list.end())
{
return &iter->second;
}
else
{
return nullptr;
}
}
std::map<std::string, Font>* Blam::Content::Fonts::GetFontList()
{
return &font_list;
}
void CleanupFontData(std::string id)
{
Font* font = Blam::Content::Fonts::GetFont(id);
if (font)
{
std::map<char, FontGlyph>::iterator it;
if (font->is_font_package)
{
for (it = font->glyph_list.begin(); it != font->glyph_list.end(); it++)
{
free(it->second.bitmap_data);
}
}
font->glyph_list.clear();
}
}
HRESULT Blam::Content::Fonts::ReloadFont(std::string id)
{
Font* font = Blam::Content::Fonts::GetFont(id);
if (font)
{
std::string path = font->path;
CleanupFontData(id);
font_list.erase(id);
return Blam::Content::Fonts::LoadFont(path);
}
else
{
return 0;
}
}
void Blam::Content::Fonts::Cleanup()
{
std::map<std::string, Font>::iterator it;
for (it = font_list.begin(); it != font_list.end(); it++)
{
CleanupFontData(it->first);
}
font_list.clear();
}
void Blam::Content::Fonts::LoadAllFonts()
{
std::string fonts_dir = Blam::Config::GetConfig()->GetString("fonts_dir");
Blam::Utils::IO::ValidatePath(fonts_dir);
if (Blam::Config::GetConfig()->GetBoolean("use_font_table"))
{
if (Blam::Utils::IO::file_exists(fonts_dir + "/font_table.txt"))
{
std::vector<std::string> fonts_to_load = Blam::Utils::IO::GetFileContentsAsLines(fonts_dir + "/font_table.txt");
for (int i = 0; i < fonts_to_load.size(); i++)
{
HRESULT hr = LoadFont(fonts_dir + "/" + fonts_to_load.at(i));
if (FAILED(hr))
{
Blam::Logger::LogEvent("### WARNING failed to load font in font table: " + fonts_to_load.at(i), WSV_WARNING);
}
}
}
else
{
Blam::Logger::LogEvent("### ERROR font_table.txt could not be found in '" + fonts_dir + "'! this will cause errors!", WSV_ERROR);
}
}
else
{
}
}