/*
* Copyright 2010 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenXcom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenXcom. If not, see .
*/
#include "Font.h"
#include
#include "Exception.h"
#include "Surface.h"
#include "Language.h"
namespace OpenXcom
{
std::wstring Font::_index = L"";
/**
* Initializes the font with a blank surface sized big enough to
* contain all the characters.
* @param width Width in pixels of each character.
* @param height Height in pixels of each character.
* @param spacing Horizontal spacing between each character.
*/
Font::Font(int width, int height, int spacing) : _width(width), _height(height), _chars(), _spacing(spacing)
{
_surface = new Surface(width, height * _index.length());
}
/**
* Deletes the font's surface.
*/
Font::~Font()
{
delete _surface;
}
/**
* Calculates the real size and position of each character in
* the surface and stores them in SDL_Rect's for future use
* by other classes.
*/
void Font::load()
{
_surface->lock();
for (unsigned int i = 0; i < _index.length(); ++i)
{
SDL_Rect rect;
int left = -1, right = -1;
for (int x = 0; x < _width; ++x)
{
for (unsigned int y = i * _height; y < (i + 1) * _height && left == -1; ++y)
{
Uint8 pixel = _surface->getPixel(x, y);
if (pixel != 0)
{
left = x;
}
}
}
for (int x = _width - 1; x >= 0; --x)
{
for (unsigned int y = (i + 1) * _height - 1; y >= i * _height && right == -1; --y)
{
Uint8 pixel = _surface->getPixel(x, y);
if (pixel != 0)
{
right = x;
}
}
}
rect.x = left;
rect.y = i * _height;
rect.w = right - left + 1;
rect.h = _height;
_chars[_index[i]] = rect;
}
_surface->unlock();
}
/**
* Loads the characters contained in each font
* from a UTF-8 file to use as the index.
* @param filename Filename of the index file.
*/
void Font::loadIndex(const std::string &filename)
{
_index = L"";
std::ifstream txtFile (filename.c_str(), std::ios::in | std::ios::binary);
if (!txtFile)
{
throw Exception("Failed to load index");
}
char value;
std::string buffer;
while (txtFile.read(&value, 1))
{
buffer += value;
}
if (!txtFile.eof())
{
throw Exception("Invalid data from file");
}
_index = Language::utf8ToWstr(buffer);
txtFile.close();
}
/**
* Returns a particular character from the set stored in the font.
* @param c Character to use for size/position.
* @return Pointer to the font's surface with the respective
* cropping rectangle set up.
*/
Surface *const Font::getChar(wchar_t c)
{
if (_chars.find(c) == _chars.end())
{
c = '?';
}
_surface->getCrop()->x = _chars[c].x;
_surface->getCrop()->y = _chars[c].y;
_surface->getCrop()->w = _chars[c].w;
_surface->getCrop()->h = _chars[c].h;
return _surface;
}
/**
* Returns the maximum width for any character in the font.
* @return Width in pixels.
*/
int Font::getWidth() const
{
return _width;
}
/**
* Returns the maximum height for any character in the font.
* @return Height in pixels.
*/
int Font::getHeight() const
{
return _height;
}
/**
* Returns the horizontal spacing for any character in the font.
* @return Spacing in pixels.
* @note This does not refer to character spacing within the surface,
* but to the spacing used when drawing a series of characters.
*/
int Font::getSpacing() const
{
return _spacing;
}
/**
* Returns the surface stored within the font. Used for loading the
* actual graphic into the font.
* @return Pointer to the internal surface.
*/
Surface *const Font::getSurface() const
{
return _surface;
}
}