/*
CGUITTFont FreeType class for Irrlicht
Copyright (c) 2009-2010 John Norman
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
The original version of this class can be located at:
http://irrlicht.suckerfreegames.com/
John Norman
john@suckerfreegames.com
*/
#include <irrlicht.h>
#include "CGUITTFont.h"
namespace irr
{
namespace gui
{
// Manages the FT_Face cache.
struct SGUITTFace : public virtual irr::IReferenceCounted
{
SGUITTFace() : face_buffer(0), face_buffer_size(0)
{
memset((void*)&face, 0, sizeof(FT_Face));
}
~SGUITTFace()
{
FT_Done_Face(face);
delete[] face_buffer;
}
FT_Face face;
FT_Byte* face_buffer;
FT_Long face_buffer_size;
};
// Static variables.
FT_Library CGUITTFont::c_library;
core::map<io::path, SGUITTFace*> CGUITTFont::c_faces;
bool CGUITTFont::c_libraryLoaded = false;
scene::IMesh* CGUITTFont::shared_plane_ptr_ = 0;
scene::SMesh CGUITTFont::shared_plane_;
//
video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const
{
// Determine what our texture size should be.
// Add 1 because textures are inclusive-exclusive.
core::dimension2du d(bits.width + 1, bits.rows + 1);
core::dimension2du texture_size;
//core::dimension2du texture_size(bits.width + 1, bits.rows + 1);
// Create and load our image now.
video::IImage* image = 0;
switch (bits.pixel_mode)
{
case FT_PIXEL_MODE_MONO:
{
// Create a blank image and fill it with transparent pixels.
texture_size = d.getOptimalSize(true, true);
image = driver->createImage(video::ECF_A1R5G5B5, texture_size);
image->fill(video::SColor(0, 255, 255, 255));
// Load the monochrome data in.
const u32 image_pitch = image->getPitch() / sizeof(u16);
u16* image_data = (u16*)image->lock();
u8* glyph_data = bits.buffer;
for (s32 y = 0; y < bits.rows; ++y)
{
u16* row = image_data;
for (s32 x = 0; x < bits.width; ++x)
{
// Monochrome bitmaps store 8 pixels per byte. The left-most pixel is the bit 0x80.
// So, we go through the data each bit at a time.
if ((glyph_data[y * bits.pitch + (x / 8)] & (0x80 >> (x % 8))) != 0)
*row = 0xFFFF;
++row;
}
image_data += image_pitch;
}
image->unlock();
break;
}
case FT_PIXEL_MODE_GRAY:
{
// Create our blank image.
texture_size = d.getOptimalSize(!driver->queryFeature(video::EVDF_TEXTURE_NPOT), !driver->queryFeature(video::EVDF_TEXTURE_NSQUARE), true, 0);
image = driver->createImage(video::ECF_A8R8G8B8, texture_size);
image->fill(video::SColor(0, 255, 255, 255));
|