Added support for multiple graphics contexts, submission from Max Rhiener.

Alas changed the indenting to use 4 spaces instead of tabs, this irons out
differences when working under Windows and Unix, keeping the identing
consistent.
This commit is contained in:
Robert Osfield
2002-01-18 22:25:51 +00:00
parent 58ead9aead
commit 4fbf4db42e
39 changed files with 2579 additions and 2443 deletions

View File

@@ -21,6 +21,7 @@
#define OSGTEXT_FONT 1
#include <osg/Object>
#include <osg/State>
#include <osgText/Export>
@@ -41,11 +42,12 @@ public:
Font();
virtual bool open(const std::string& font);
bool open(const char* font);
bool open(const std::string& font);
virtual bool create(int pointSize, const unsigned int res = 72 );
virtual bool create();
virtual void output(const char* text);
virtual bool create(osg::State& state,int pointSize, const unsigned int res = 72 );
virtual bool create(osg::State& state);
virtual void output(osg::State& state,const char* text);
virtual bool isOk(void) const { return _init; }
virtual bool isCreated(void) const { return isOk() && _created; }
@@ -219,6 +221,10 @@ public:
int point_size,
double precision);
PolygonFont(const char* font,
int point_size,
double precision);
META_Object(PolygonFont);
protected:

View File

@@ -4,7 +4,7 @@
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*

View File

@@ -1,32 +1,32 @@
#include "FTBitmapGlyph.h"
#include "FTBitmapGlyph.h"
FTBitmapGlyph::FTBitmapGlyph( FT_Glyph glyph)
: FTGlyph(),
destWidth(0),
destHeight(0),
data(0)
: FTGlyph(),
destWidth(0),
destHeight(0),
data(0)
{
// This function will always fail if the glyph's format isn't scalable????
FT_Error err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_mono, 0, 1);
if( err || ft_glyph_format_bitmap != glyph->format)
{return;}
// This function will always fail if the glyph's format isn't scalable????
FT_Error err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_mono, 0, 1);
if( err || ft_glyph_format_bitmap != glyph->format)
{return;}
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
advance = glyph->advance.x >> 16;
advance = glyph->advance.x >> 16;
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
// FIXME What about dest alignment?
destWidth = srcWidth;
destHeight = srcHeight;
@@ -35,39 +35,39 @@ FTBitmapGlyph::FTBitmapGlyph( FT_Glyph glyph)
for(int y = 0; y < srcHeight; ++y)
{
--destHeight;
for(int x = 0; x < srcPitch; ++x)
{
*( data + ( destHeight * srcPitch + x)) = *( source->buffer + ( y * srcPitch) + x);
}
--destHeight;
for(int x = 0; x < srcPitch; ++x)
{
*( data + ( destHeight * srcPitch + x)) = *( source->buffer + ( y * srcPitch) + x);
}
}
destHeight = srcHeight;
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
}
FTBitmapGlyph::~FTBitmapGlyph()
{
delete[] data;
delete[] data;
}
float FTBitmapGlyph::Render( const FT_Vector& pen)
{
if( data != 0 )
{
// Move the glyph origin
glBitmap( 0, 0, 0.0, 0.0, pen.x + pos.x, pen.y - pos.y, (const GLubyte *)0 );
if( data != 0 )
{
// Move the glyph origin
glBitmap( 0, 0, 0.0, 0.0, pen.x + pos.x, pen.y - pos.y, (const GLubyte *)0 );
glBitmap( destWidth, destHeight, 0.0f, 0.0, 0.0, 0.0, (const GLubyte *)data);
glBitmap( destWidth, destHeight, 0.0f, 0.0, 0.0, 0.0, (const GLubyte *)data);
// Restore the glyph origin
glBitmap( 0, 0, 0.0, 0.0, -pen.x - pos.x, -pen.y + pos.y, (const GLubyte *)0 );
}
return advance;
// Restore the glyph origin
glBitmap( 0, 0, 0.0, 0.0, -pen.x - pos.x, -pen.y + pos.y, (const GLubyte *)0 );
}
return advance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTBitmapGlyph__
#define __FTBitmapGlyph__
#ifndef __FTBitmapGlyph__
#define __FTBitmapGlyph__
#include "FTGL.h"
@@ -7,7 +7,7 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
#include "FTGlyph.h"
/**
@@ -22,45 +22,45 @@
*/
class FTGL_EXPORT FTBitmapGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTBitmapGlyph( FT_Glyph glyph);
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTBitmapGlyph( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTBitmapGlyph();
/**
* Destructor
*/
virtual ~FTBitmapGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
};
#endif // __FTBitmapGlyph__
#endif // __FTBitmapGlyph__

View File

@@ -1,97 +1,97 @@
#include "FTCharmap.h"
#include "FTCharmap.h"
FTCharmap::FTCharmap( FT_Face face)
: ftFace( face),
err(0)
: ftFace( face),
err(0)
{
// Check that the default is valid
if( !face->charmap)
{
FT_Set_Charmap( ftFace, ftFace->charmaps[0]);
}
ftEncoding = face->charmap->encoding;
// Check that the default is valid
if( !face->charmap)
{
FT_Set_Charmap( ftFace, ftFace->charmaps[0]);
}
ftEncoding = face->charmap->encoding;
}
FTCharmap::~FTCharmap()
{
charMap.clear();
charMap.clear();
}
bool FTCharmap::CharMap( FT_Encoding encoding)
{
if( ftEncoding == encoding)
{
return true;
}
err = FT_Select_Charmap( ftFace, encoding );
if( !err)
{
ftEncoding = encoding;
charMap.clear();
}
return !err;
if( ftEncoding == encoding)
{
return true;
}
err = FT_Select_Charmap( ftFace, encoding );
if( !err)
{
ftEncoding = encoding;
charMap.clear();
}
return !err;
}
bool FTCharmap::CharMap( FT_UShort platform, FT_UShort encoding)
{
FT_CharMap found = 0;
FT_CharMap charmap;
FT_CharMap found = 0;
FT_CharMap charmap;
for( int n = 0; n < ftFace->num_charmaps; n++ )
{
charmap = ftFace->charmaps[n];
for( int n = 0; n < ftFace->num_charmaps; n++ )
{
charmap = ftFace->charmaps[n];
if( charmap->platform_id == platform && charmap->encoding_id == encoding)
{
found = charmap;
break;
}
}
if( charmap->platform_id == platform && charmap->encoding_id == encoding)
{
found = charmap;
break;
}
}
if( !found )
{
return false;
}
if( !found )
{
return false;
}
if( ftEncoding == found->encoding)
{
return true;
}
/* now, select the charmap for the face object */
err = FT_Set_Charmap( ftFace, found );
if( !err)
{
ftEncoding = found->encoding;
charMap.clear();
}
return !err;
if( ftEncoding == found->encoding)
{
return true;
}
/* now, select the charmap for the face object */
err = FT_Set_Charmap( ftFace, found );
if( !err)
{
ftEncoding = found->encoding;
charMap.clear();
}
return !err;
}
unsigned int FTCharmap::CharIndex( unsigned int index )
{
CharacterMap::const_iterator result = charMap.find( index);
if( result == charMap.end())
{
unsigned int glyph = FT_Get_Char_Index( ftFace, index);
charMap.insert( CharacterMap::value_type( index, glyph));
return glyph;
}
else
{
return result->second;
}
CharacterMap::const_iterator result = charMap.find( index);
if( result == charMap.end())
{
unsigned int glyph = FT_Get_Char_Index( ftFace, index);
charMap.insert( CharacterMap::value_type( index, glyph));
return glyph;
}
else
{
return result->second;
}
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTCharmap__
#define __FTCharmap__
#ifndef __FTCharmap__
#define __FTCharmap__
#include "FTGL.h"
@@ -26,99 +26,99 @@ using namespace std;
*/
class FTGL_EXPORT FTCharmap
{
public:
/**
* Constructor
*/
FTCharmap( FT_Face ftFace);
public:
/**
* Constructor
*/
FTCharmap( FT_Face ftFace);
/**
* Destructor
*/
virtual ~FTCharmap();
/**
* Destructor
*/
virtual ~FTCharmap();
/**
* Queries for the current character map code.
*
* @return The current character map code.
*/
FT_Encoding Encoding() const { return ftEncoding;}
/**
* Sets the character map for the face.
* Valid encodings as at Freetype 2.0.4
* ft_encoding_none
* ft_encoding_symbol
* ft_encoding_unicode
* ft_encoding_latin_2
* ft_encoding_sjis
* ft_encoding_gb2312
* ft_encoding_big5
* ft_encoding_wansung
* ft_encoding_johab
* ft_encoding_adobe_standard
* ft_encoding_adobe_expert
* ft_encoding_adobe_custom
* ft_encoding_apple_roman
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_Encoding encoding);
/**
* Queries for the current character map code.
*
* @return The current character map code.
*/
FT_Encoding Encoding() const { return ftEncoding;}
/**
* Sets the character map for the face.
* Valid encodings as at Freetype 2.0.4
* ft_encoding_none
* ft_encoding_symbol
* ft_encoding_unicode
* ft_encoding_latin_2
* ft_encoding_sjis
* ft_encoding_gb2312
* ft_encoding_big5
* ft_encoding_wansung
* ft_encoding_johab
* ft_encoding_adobe_standard
* ft_encoding_adobe_expert
* ft_encoding_adobe_custom
* ft_encoding_apple_roman
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_Encoding encoding);
/**
* Sets the character map for the face.
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_UShort platform, FT_UShort encoding);
/**
* Sets the character map for the face.
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_UShort platform, FT_UShort encoding);
/**
* Get the glyph index of the input character.
*
* @param index The character code of the requested glyph in the
* current encoding eg apple roman.
* @return The glyph index for the character.
*/
unsigned int CharIndex( unsigned int index );
/**
* Get the glyph index of the input character.
*
* @param index The character code of the requested glyph in the
* current encoding eg apple roman.
* @return The glyph index for the character.
*/
unsigned int CharIndex( unsigned int index );
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err;}
protected:
/**
* Current character map code.
*/
FT_Encoding ftEncoding;
/**
* The current Freetype face.
*/
FT_Face ftFace;
/**
* A structure that maps glyph indices to character codes
*
* < character code, face glyph index>
*/
typedef map< unsigned long, unsigned long> CharacterMap;
CharacterMap charMap;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
private:
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err;}
protected:
/**
* Current character map code.
*/
FT_Encoding ftEncoding;
/**
* The current Freetype face.
*/
FT_Face ftFace;
/**
* A structure that maps glyph indices to character codes
*
* < character code, face glyph index>
*/
typedef map< unsigned long, unsigned long> CharacterMap;
CharacterMap charMap;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
private:
};
#endif // __FTCharmap__
#endif // __FTCharmap__

View File

@@ -1,109 +1,109 @@
#include "FTFace.h"
#include "FTLibrary.h"
#include "FTCharmap.h"
#include "FTGL.h"
#include "FTFace.h"
#include "FTLibrary.h"
#include "FTCharmap.h"
#include "FTGL.h"
FTFace::FTFace()
: charMap(0),
ftFace(0),
numCharMaps(0),
numGlyphs(0),
err(0)
: charMap(0),
ftFace(0),
numCharMaps(0),
numGlyphs(0),
err(0)
{}
FTFace::~FTFace()
{
delete charMap;
charMap = 0;
Close();
delete charMap;
charMap = 0;
Close();
}
bool FTFace::Open( const char* filename)
{
ftFace = new FT_Face;
err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), filename, 0, ftFace);
ftFace = new FT_Face;
err = FT_New_Face( *FTLibrary::Instance().GetLibrary(), filename, 0, ftFace);
if( err)
if( err)
{
delete ftFace;
ftFace = 0;
return false;
delete ftFace;
ftFace = 0;
return false;
}
else
{
charMap = new FTCharmap( *ftFace);
return true;
}
charMap = new FTCharmap( *ftFace);
return true;
}
}
void FTFace::Close()
{
if( ftFace)
{
FT_Done_Face( *ftFace);
delete ftFace;
ftFace = 0;
}
if( ftFace)
{
FT_Done_Face( *ftFace);
delete ftFace;
ftFace = 0;
}
}
FTSize& FTFace::Size( const unsigned int size, const unsigned int res)
{
if( !charSize.CharSize( ftFace, size, res, res))
{
err = charSize.Error();
}
return charSize;
if( !charSize.CharSize( ftFace, size, res, res))
{
err = charSize.Error();
}
return charSize;
}
bool FTFace::CharMap( FT_Encoding encoding)
{
return charMap->CharMap( encoding);
return charMap->CharMap( encoding);
}
unsigned int FTFace::CharIndex( unsigned int index) const
{
return charMap->CharIndex( index);
return charMap->CharIndex( index);
}
FT_Vector& FTFace::KernAdvance( unsigned int index1, unsigned int index2)
{
kernAdvance.x = 0; kernAdvance.y = 0;
if( FT_HAS_KERNING((*ftFace)) && index1 && index2)
{
err = FT_Get_Kerning( *ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance);
if( !err)
{
kernAdvance.x /= 64; kernAdvance.y /= 64;
}
}
return kernAdvance;
kernAdvance.x = 0; kernAdvance.y = 0;
if( FT_HAS_KERNING((*ftFace)) && index1 && index2)
{
err = FT_Get_Kerning( *ftFace, index1, index2, ft_kerning_unfitted, &kernAdvance);
if( !err)
{
kernAdvance.x /= 64; kernAdvance.y /= 64;
}
}
return kernAdvance;
}
FT_Glyph* FTFace::Glyph( unsigned int index, FT_Int load_flags)
{
err = FT_Load_Glyph( *ftFace, index, load_flags);
err = FT_Get_Glyph( (*ftFace)->glyph, &ftGlyph);
if( !err)
{
return &ftGlyph;
}
else
{
return NULL;
}
err = FT_Load_Glyph( *ftFace, index, load_flags);
err = FT_Get_Glyph( (*ftFace)->glyph, &ftGlyph);
if( !err)
{
return &ftGlyph;
}
else
{
return NULL;
}
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTFace__
#define __FTFace__
#ifndef __FTFace__
#define __FTFace__
#include "FTGL.h"
@@ -14,134 +14,134 @@ class FTCharmap;
/**
* FTFace class provides an abstraction layer for the Freetype Face.
*
* @see "Freetype 2 Documentation - 2.0.4"
* @see "Freetype 2 Documentation - 2.0.4"
*
*/
class FTGL_EXPORT FTFace
{
public:
/**
* Default Constructor
*/
FTFace();
public:
/**
* Default Constructor
*/
FTFace();
/**
* Destructor
*
* Disposes of the current Freetype Face.
*/
virtual ~FTFace();
/**
* Destructor
*
* Disposes of the current Freetype Face.
*/
virtual ~FTFace();
/**
* Opens and reads a face file.
*
* @param fontname font file name.
* @return <code>true</code> if file has opened
* successfully.
*/
bool Open( const char* filename);
/**
* Opens and reads a face file.
*
* @param fontname font file name.
* @return <code>true</code> if file has opened
* successfully.
*/
bool Open( const char* filename);
/**
* Disposes of the face
*/
void Close();
/**
* Sets the char size for the current face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param size the face size in points (1/72 inch)
* @param res the resolution of the target device.
* @return <code>FTSize</code> object
*/
FTSize& Size( const unsigned int size, const unsigned int res);
/**
* Disposes of the face
*/
void Close();
/**
* Sets the char size for the current face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param size the face size in points (1/72 inch)
* @param res the resolution of the target device.
* @return <code>FTSize</code> object
*/
FTSize& Size( const unsigned int size, const unsigned int res);
/**
* Sets the character map for the face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_Encoding encoding);
/**
* Sets the character map for the face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param encoding the Freetype encoding symbol. See above.
* @return <code>true</code> if charmap was valid
* and set correctly
*/
bool CharMap( FT_Encoding encoding);
/**
* Get the glyph index of the input character.
*
* @param index The character code of the requested glyph in the
* current encoding eg apple roman.
* @return The glyph index for the character.
*/
unsigned int CharIndex( unsigned int index ) const;
/**
* Get the glyph index of the input character.
*
* @param index The character code of the requested glyph in the
* current encoding eg apple roman.
* @return The glyph index for the character.
*/
unsigned int CharIndex( unsigned int index ) const;
/**
* Gets the kerning vector between two glyphs
*/
FT_Vector& KernAdvance( unsigned int index1, unsigned int index2);
/**
* Gets the kerning vector between two glyphs
*/
FT_Vector& KernAdvance( unsigned int index1, unsigned int index2);
/**
* Loads and creates a Freetype glyph.
*/
FT_Glyph* Glyph( unsigned int index, FT_Int load_flags);
/**
* Loads and creates a Freetype glyph.
*/
FT_Glyph* Glyph( unsigned int index, FT_Int load_flags);
/**
* Gets the current Freetype face.
*/
FT_Face* Face() const { return ftFace;}
/**
* Gets the current Freetype face.
*/
FT_Face* Face() const { return ftFace;}
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err; }
private:
/**
* The size object associated with this face
*/
FTSize charSize;
/**
* The Character Map object associated with this face
*/
FTCharmap* charMap;
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err; }
private:
/**
* The size object associated with this face
*/
FTSize charSize;
/**
* The Character Map object associated with this face
*/
FTCharmap* charMap;
/**
* The Freetype face
*/
FT_Face* ftFace;
/**
* The Freetype face
*/
FT_Face* ftFace;
/**
* Temporary variable to hold a glyph
*/
FT_Glyph ftGlyph;
/**
* Temporary variable to hold a glyph
*/
FT_Glyph ftGlyph;
/**
* The number of character maps in this face.
*/
int numCharMaps;
/**
* The number of character maps in this face.
*/
int numCharMaps;
/**
* The number of glyphs in this face
*/
int numGlyphs;
/**
* The number of glyphs in this face
*/
int numGlyphs;
/**
* Temporary variable to holding a kerning vector.
*/
FT_Vector kernAdvance;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
/**
* Temporary variable to holding a kerning vector.
*/
FT_Vector kernAdvance;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
};
#endif // __FTFace__
#endif // __FTFace__

View File

@@ -1,148 +1,179 @@
#include "FTFace.h"
#include "FTFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTFace.h"
#include "FTFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
// mrn@changes
FTFont::FTFont()
: numFaces(0),
glyphList(0),
err(0)
: numFaces(0),
err(0)
{
pen.x = 0;
pen.y = 0;
pen.x = 0;
pen.y = 0;
}
FTFont::~FTFont()
{
Close();
Close();
}
bool FTFont::Open( const char* fontname )
{
if( face.Open( fontname))
{
FT_Face* ftFace = face.Face();
numGlyphs = (*ftFace)->num_glyphs;
return true;
}
else
{
err = face.Error();
return false;
}
if( face.Open( fontname))
{
FT_Face* ftFace = face.Face();
numGlyphs = (*ftFace)->num_glyphs;
return true;
}
else
{
err = face.Error();
return false;
}
}
// mrn@changes
void FTFont::Close()
{
delete glyphList;
GlyphContextContainer::iterator itr;
for(itr=_contextGlyphList.begin();itr<_contextGlyphList.begin();itr++)
delete *itr;
_contextGlyphList.clear();
}
bool FTFont::FaceSize( const unsigned int size, const unsigned int res )
// mrn@changes
bool FTFont::FaceSize( const unsigned int size, const unsigned int res , unsigned int renderContext)
{
charSize = face.Size( size, res);
charSize = face.Size( size, res);
if( glyphList)
delete glyphList;
glyphList = new FTGlyphContainer( &face, numGlyphs);
if( MakeGlyphList())
{
return true;
}
else
{
return false;
}
// check the context
while (_contextGlyphList.size() <= renderContext)
_contextGlyphList.push_back(NULL);
FTGlyphContainer*& glyphList=_contextGlyphList[renderContext];
if( glyphList)
delete glyphList;
glyphList = new FTGlyphContainer( &face, numGlyphs);
if( MakeGlyphList(renderContext))
{
return true;
}
else
{
return false;
}
}
bool FTFont::Created(unsigned int renderContext)
{
if(renderContext < _contextGlyphList.size())
return (_contextGlyphList[renderContext] != NULL);
else
return false;
}
bool FTFont::CharMap( FT_Encoding encoding)
{
err = face.CharMap( encoding);
return !err;
err = face.CharMap( encoding);
return !err;
}
int FTFont::Ascender() const
int FTFont::Ascender() const
{
return charSize.Ascender();
return charSize.Ascender();
}
int FTFont::Descender() const
int FTFont::Descender() const
{
return charSize.Descender();
return charSize.Descender();
}
// mrn@changes
float FTFont::Advance( const wchar_t* string)
{
const wchar_t* c = string; // wchar_t IS unsigned?
float width = 0;
// all are the same, a bit a hack
FTGlyphContainer* glyphList=_contextGlyphList[0];
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
const wchar_t* c = string; // wchar_t IS unsigned?
float width = 0;
return width;
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
return width;
}
// mrn@changes
float FTFont::Advance( const char* string)
{
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
float width = 0;
// all are the same, a bit a hack
FTGlyphContainer* glyphList=_contextGlyphList[0];
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
float width = 0;
return width;
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
return width;
}
void FTFont::render( const char* string )
// mrn@changes
void FTFont::render( const char* string , unsigned int renderContext)
{
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
++c;
}
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
++c;
}
}
void FTFont::render( const wchar_t* string )
// mrn@changes
void FTFont::render( const wchar_t* string , unsigned int renderContext)
{
const wchar_t* c = string; // wchar_t IS unsigned?
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
++c;
}
const wchar_t* c = string; // wchar_t IS unsigned?
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
++c;
}
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTFont__
#define __FTFont__
#ifndef __FTFont__
#define __FTFont__
#include <string>
@@ -11,6 +11,9 @@
#include "FTFace.h"
#include "FTGL.h"
// mrn@changes
#include <vector>
class FTGlyphContainer;
@@ -27,156 +30,170 @@ using namespace std;
* <code>MakeGlyphList</code> function to build a glyphList with the
* appropriate glyph type.
*
* @see FTFace
* @see FTSize
* @see FTGlyphContainer
* @see FTGlyph
* @see FTFace
* @see FTSize
* @see FTGlyphContainer
* @see FTGlyph
*/
class FTGL_EXPORT FTFont
{
public:
/**
* Default Constructor
*/
FTFont();
/**
* Destructor
*/
virtual ~FTFont();
/**
* Opens and reads a font file.
*
* @param fontname font file name.
* @return <code>true</code> if file has opened
* successfully.
*/
virtual bool Open( const char* fontname );
/**
* Disposes of the font
*/
virtual void Close();
/**
* Sets the char size for the current face.
*
* @param size the face size in points (1/72 inch)
* @param res the resolution of the target device.
* @return <code>true</code> if size was set correctly
*/
virtual bool FaceSize( const unsigned int size, const unsigned int res = 72 );
/**
* Sets the character map for the face.
*
* @param encoding Freetype enumerate for char map code.
* @return <code>true</code> if charmap was valid and
* set correctly
*/
virtual bool CharMap( FT_Encoding encoding );
/**
* Gets the global ascender height for the face.
*
* @return Ascender height
*/
virtual int Ascender() const;
/**
* Gets the global descender height for the face.
*
* @return Descender height
*/
virtual int Descender() const;
/**
* Gets the advance width for a string.
*
* param string a wchar_t string
* @return advance width
*/
float Advance( const wchar_t* string);
public:
/**
* Default Constructor
*/
FTFont();
/**
* Destructor
*/
virtual ~FTFont();
/**
* Opens and reads a font file.
*
* @param fontname font file name.
* @return <code>true</code> if file has opened
* successfully.
*/
virtual bool Open( const char* fontname);
/**
* Disposes of the font
*/
virtual void Close();
/**
* Sets the char size for the current face.
*
* @param size the face size in points (1/72 inch)
* @param res the resolution of the target device.
* @return <code>true</code> if size was set correctly
*/
// mrn@changes
virtual bool FaceSize( const unsigned int size, const unsigned int res = 72 , unsigned int renderContext=0);
virtual bool Created(unsigned int renderContext=0);
/**
* Gets the advance width for a string.
*
* param string a char string
* @return advance width
*/
float Advance( const char* string);
/**
* Sets the character map for the face.
*
* @param encoding Freetype enumerate for char map code.
* @return <code>true</code> if charmap was valid and
* set correctly
*/
virtual bool CharMap( FT_Encoding encoding );
/**
* Gets the global ascender height for the face.
*
* @return Ascender height
*/
virtual int Ascender() const;
/**
* Gets the global descender height for the face.
*
* @return Descender height
*/
virtual int Descender() const;
/**
* Gets the advance width for a string.
*
* param string a wchar_t string
* @return advance width
*/
float Advance( const wchar_t* string);
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
virtual void render( const char* string );
/**
* Gets the advance width for a string.
*
* param string a char string
* @return advance width
*/
float Advance( const char* string);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
virtual void render( const wchar_t* string );
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
// mrn@changes
virtual void render( const char* string , unsigned int renderContext=0);
/**
* Queries the Font for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
// mrn@changes
virtual void render( const wchar_t* string , unsigned int renderContext=0);
/**
* Queries the Font for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
protected:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
virtual bool MakeGlyphList() = 0;
/**
* Current face object
*/
FTFace face;
/**
* Number of faces in this font
*/
unsigned int numFaces;
/**
* Current size object
*/
FTSize charSize;
protected:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
virtual bool MakeGlyphList( unsigned int renderContext=0) = 0;
/**
* Current face object
*/
FTFace face;
/**
* Number of faces in this font
*/
unsigned int numFaces;
/**
* Current size object
*/
FTSize charSize;
/**
* An object that holds a list of glyphs
*/
FTGlyphContainer* glyphList;
/**
* The number of glyphs in this font
*/
unsigned int numGlyphs;
/**
* Current pen or cursor position;
*/
FT_Vector pen;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
private:
/**
* An object that holds a list of glyphs
*/
// mrn@changes
// FTGlyphContainer* glyphList;
/**
* The number of glyphs in this font
*/
unsigned int numGlyphs;
/**
* Current pen or cursor position;
*/
FT_Vector pen;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
/**
* renderContext list
*/
// mrn@changes
typedef std::vector<FTGlyphContainer*> GlyphContextContainer;
GlyphContextContainer _contextGlyphList;
private:
};
#endif // __FTFont__
#endif // __FTFont__

View File

@@ -87,16 +87,16 @@
#endif
#if defined(_MSC_VER)
# ifdef FTGL_LIBRARY_STATIC // staticLib
# define FTGL_EXPORT
# elif FTGL_LIBRARY // dynamicLib
# define FTGL_EXPORT __declspec(dllexport)
# else
# define FTGL_EXPORT __declspec(dllimport)
# endif /* FTGL_LIBRARY */
# ifdef FTGL_LIBRARY_STATIC // staticLib
# define FTGL_EXPORT
# elif FTGL_LIBRARY // dynamicLib
# define FTGL_EXPORT __declspec(dllexport)
# else
# define FTGL_EXPORT __declspec(dllimport)
# endif /* FTGL_LIBRARY */
#else
# define FTGL_EXPORT
# define FTGL_EXPORT
#endif
#endif // __FTGL__
#endif // __FTGL__

View File

@@ -1,6 +1,6 @@
#include "FTGLBitmapFont.h"
#include "FTGlyphContainer.h"
#include "FTBitmapGlyph.h"
#include "FTGLBitmapFont.h"
#include "FTGlyphContainer.h"
#include "FTBitmapGlyph.h"
FTGLBitmapFont::FTGLBitmapFont()
@@ -12,54 +12,59 @@ FTGLBitmapFont::~FTGLBitmapFont()
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
bool FTGLBitmapFont::MakeGlyphList()
// mrn@changes
bool FTGLBitmapFont::MakeGlyphList(unsigned int renderContext)
{
// if( preCache)
for( unsigned int c = 0; c < numGlyphs; ++c)
{
FT_Glyph* ftGlyph = face.Glyph( c, FT_LOAD_DEFAULT);
// FT_HAS_VERTICAL(face)
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
if( ftGlyph)
{
FTBitmapGlyph* tempGlyph = new FTBitmapGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
// if( preCache)
for( unsigned int c = 0; c < numGlyphs; ++c)
{
FT_Glyph* ftGlyph = face.Glyph( c, FT_LOAD_DEFAULT);
// FT_HAS_VERTICAL(face)
if( ftGlyph)
{
FTBitmapGlyph* tempGlyph = new FTBitmapGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
}
void FTGLBitmapFont::render( const char* string)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
// mrn@changes
void FTGLBitmapFont::render( const char* string,unsigned int renderContext)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
FTFont::render( string);
FTFont::render( string,renderContext);
glPopClientAttrib();
glPopClientAttrib();
}
void FTGLBitmapFont::render( const wchar_t* string)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
// mrn@changes
void FTGLBitmapFont::render( const wchar_t* string,unsigned int renderContext)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
FTFont::render( string);
FTFont::render( string,renderContext);
glPopClientAttrib();
glPopClientAttrib();
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTGLBitmapFont__
#define __FTGLBitmapFont__
#ifndef __FTGLBitmapFont__
#define __FTGLBitmapFont__
#include "FTGL.h"
@@ -12,45 +12,48 @@ class FTBitmapGlyph;
* FTGLBitmapFont is a specialisation of the FTFont class for handling
* Bitmap fonts
*
* @see FTFont
* @see FTFont
*/
class FTGL_EXPORT FTGLBitmapFont : public FTFont
{
public:
/**
* Constructor
*/
FTGLBitmapFont();
public:
/**
* Constructor
*/
FTGLBitmapFont();
/**
* Destructor
*/
~FTGLBitmapFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
void render( const char* string);
/**
* Destructor
*/
~FTGLBitmapFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
// mrn@changes
void render( const char* string, unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string 'C' style wide string to be output.
*/
void render( const wchar_t* string);
/**
* Renders a string of characters
*
* @param string 'C' style wide string to be output.
*/
// mrn@changes
void render( const wchar_t* string, unsigned int renderContext=0);
// attributes
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
bool MakeGlyphList();
// attributes
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
virtual bool MakeGlyphList(unsigned int renderContext=0);
};
#endif // __FTGLBitmapFont__
#endif // __FTGLBitmapFont__

View File

@@ -1,7 +1,7 @@
#include "FTGLOutlineFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTOutlineGlyph.h"
#include "FTGLOutlineFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTOutlineGlyph.h"
FTGLOutlineFont::FTGLOutlineFont()
@@ -12,54 +12,59 @@ FTGLOutlineFont::~FTGLOutlineFont()
{}
bool FTGLOutlineFont::MakeGlyphList()
// mrn@changes
bool FTGLOutlineFont::MakeGlyphList( unsigned int renderContext)
{
for( unsigned int n = 0; n < numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
if( ftGlyph)
{
FTOutlineGlyph* tempGlyph = new FTOutlineGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
for( unsigned int n = 0; n < numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
if( ftGlyph)
{
FTOutlineGlyph* tempGlyph = new FTOutlineGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
}
void FTGLOutlineFont::render( const char* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable( GL_LINE_SMOOTH);
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
// mrn@changes
void FTGLOutlineFont::render( const char* string, unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable( GL_LINE_SMOOTH);
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string);
FTFont::render( string,renderContext);
glPopAttrib();
glPopAttrib();
}
void FTGLOutlineFont::render( const wchar_t* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable( GL_LINE_SMOOTH);
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
// mrn@changes
void FTGLOutlineFont::render( const wchar_t* string, unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable( GL_LINE_SMOOTH);
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string);
FTFont::render( string,renderContext);
glPopAttrib();
glPopAttrib();
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTGLOutlineFont__
#define __FTGLOutlineFont__
#ifndef __FTGLOutlineFont__
#define __FTGLOutlineFont__
#include "FTGL.h"
@@ -12,45 +12,48 @@ class FTOutlineGlyph;
* FTGLOutlineFont is a specialisation of the FTFont class for handling
* Vector Outline fonts
*
* @see FTFont
* @see FTFont
*/
class FTGL_EXPORT FTGLOutlineFont : public FTFont
{
public:
/**
* Default Constructor
*/
FTGLOutlineFont();
/**
* Destructor
*/
~FTGLOutlineFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
void render( const char* string);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
void render( const wchar_t* string);
public:
/**
* Default Constructor
*/
FTGLOutlineFont();
/**
* Destructor
*/
~FTGLOutlineFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
// mrn@changes
virtual void render( const char* string, unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
// mrn@changes
virtual void render( const wchar_t* string, unsigned int renderContext=0);
// attributes
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
bool MakeGlyphList();
// attributes
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
virtual bool MakeGlyphList( unsigned int renderContext=0);
};
#endif // __FTGLOutlineFont__

View File

@@ -1,6 +1,6 @@
#include "FTGLPixmapFont.h"
#include "FTGlyphContainer.h"
#include "FTPixmapGlyph.h"
#include "FTGLPixmapFont.h"
#include "FTGlyphContainer.h"
#include "FTPixmapGlyph.h"
FTGLPixmapFont::FTGLPixmapFont()
@@ -12,53 +12,56 @@ FTGLPixmapFont::~FTGLPixmapFont()
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
bool FTGLPixmapFont::MakeGlyphList()
// mrn@changes
bool FTGLPixmapFont::MakeGlyphList(unsigned int renderContext)
{
// if( preCache)
for( unsigned int c = 0; c < numGlyphs; ++c)
{
FT_Glyph* ftGlyph = face.Glyph( c, FT_LOAD_DEFAULT);
// FT_HAS_VERTICAL(face)
if( ftGlyph)
{
FTPixmapGlyph* tempGlyph = new FTPixmapGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
// if( preCache)
for( unsigned int c = 0; c < numGlyphs; ++c)
{
FT_Glyph* ftGlyph = face.Glyph( c, FT_LOAD_DEFAULT);
// FT_HAS_VERTICAL(face)
if( ftGlyph)
{
FTPixmapGlyph* tempGlyph = new FTPixmapGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
}
void FTGLPixmapFont::render( const char* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
void FTGLPixmapFont::render( const char* string,unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FTFont::render( string);
FTFont::render( string,renderContext);
glPopAttrib();
glPopAttrib();
}
void FTGLPixmapFont::render( const wchar_t* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
void FTGLPixmapFont::render( const wchar_t* string,unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FTFont::render( string);
FTFont::render( string,renderContext);
glPopAttrib();
glPopAttrib();
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTGLPixmapFont__
#define __FTGLPixmapFont__
#ifndef __FTGLPixmapFont__
#define __FTGLPixmapFont__
#include "FTGL.h"
@@ -12,47 +12,50 @@ class FTPixmapGlyph;
* FTGLPixmapFont is a specialisation of the FTFont class for handling
* Pixmap (Grey Scale) fonts
*
* @see FTFont
* @see FTFont
*/
class FTGL_EXPORT FTGLPixmapFont : public FTFont
{
public:
/**
* Default Constructor
*/
FTGLPixmapFont();
/**
* Destructor
*/
~FTGLPixmapFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
void render( const char* string);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
void render( const wchar_t* string);
public:
/**
* Default Constructor
*/
FTGLPixmapFont();
/**
* Destructor
*/
~FTGLPixmapFont();
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
// mrn@changes
virtual void render( const char* string, unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
// mrn@changes
virtual void render( const wchar_t* string, unsigned int renderContext=0);
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
bool MakeGlyphList();
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
virtual bool MakeGlyphList(unsigned int renderContext=0);
};
#endif // __FTGLPixmapFont__
#endif // __FTGLPixmapFont__

View File

@@ -1,7 +1,7 @@
#include "FTGLPolygonFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTPolyGlyph.h"
#include "FTGLPolygonFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTPolyGlyph.h"
@@ -13,22 +13,25 @@ FTGLPolygonFont::~FTGLPolygonFont()
{}
bool FTGLPolygonFont::MakeGlyphList()
// mrn@changes
bool FTGLPolygonFont::MakeGlyphList( unsigned int renderContext)
{
for( unsigned int n = 0; n < numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
if( ftGlyph)
{
FTPolyGlyph* tempGlyph = new FTPolyGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
for( unsigned int n = 0; n < numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
if( ftGlyph)
{
FTPolyGlyph* tempGlyph = new FTPolyGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
}

View File

@@ -1,9 +1,9 @@
#ifndef __FTGLPolygonFont__
#define __FTGLPolygonFont__
#ifndef __FTGLPolygonFont__
#define __FTGLPolygonFont__
#include "FTGL.h"
#include "FTFont.h"
#include "FTFont.h"
class FTPolyGlyph;
@@ -12,32 +12,33 @@ class FTPolyGlyph;
* FTGLPolygonFont is a specialisation of the FTFont class for handling
* tesselated Polygon Mesh fonts
*
* @see FTFont
* @see FTFont
*/
class FTGL_EXPORT FTGLPolygonFont : public FTFont
{
public:
/**
* Default Constructor
*/
FTGLPolygonFont();
/**
* Destructor
*/
~FTGLPolygonFont();
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
bool MakeGlyphList();
public:
/**
* Default Constructor
*/
FTGLPolygonFont();
/**
* Destructor
*/
~FTGLPolygonFont();
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
virtual bool MakeGlyphList( unsigned int renderContext=0);
};
#endif // __FTGLPolygonFont__
#endif // __FTGLPolygonFont__

View File

@@ -1,6 +1,6 @@
#include "FTGLTextureFont.h"
#include "FTGlyphContainer.h"
#include "FTTextureGlyph.h"
#include "FTGLTextureFont.h"
#include "FTGlyphContainer.h"
#include "FTTextureGlyph.h"
inline GLuint NextPowerOf2( GLuint in)
{
@@ -17,188 +17,215 @@ inline GLuint NextPowerOf2( GLuint in)
FTGLTextureFont::FTGLTextureFont()
: maxTextSize(0),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
: maxTextSize(0),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
{}
FTGLTextureFont::FTGLTextureFont(int textureSize)
: maxTextSize(textureSize),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
: maxTextSize(textureSize),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
{}
FTGLTextureFont::~FTGLTextureFont()
{
glDeleteTextures( numTextures, (const GLuint*)glTextureID);
ContextTextureId::iterator itr;
for(itr=glContextTextureID.begin();itr != glContextTextureID.end(); itr++)
{
glDeleteTextures( numTextures, (const GLuint*)*itr);
delete *itr;
}
}
bool FTGLTextureFont::MakeGlyphList()
// mrn@changes
bool FTGLTextureFont::MakeGlyphList(unsigned int renderContext)
{
if( !maxTextSize)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
glyphHeight = ( charSize.Height()) + padding;
glyphWidth = ( charSize.Width()) + padding;
GetSize();
GLuint totalMem;
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
if( textureHeight > (maxTextSize-padding*2))
{
numTextures = static_cast<int>( textureHeight / (maxTextSize-padding*2)) + 1;
if( numTextures > 15) // FIXME
numTextures = 15;
GLsizei heightRemain = NextPowerOf2( textureHeight % (maxTextSize-padding*2));
totalMem = ((maxTextSize * ( numTextures - 1)) + heightRemain) * textureWidth;
// check the context
while (glContextTextureID.size() <= renderContext)
glContextTextureID.push_back(NULL);
unsigned long* glTextureID=glContextTextureID[renderContext];
if(glTextureID)
return true;
else
{
glTextureID=new unsigned long[16];
glContextTextureID[renderContext]=glTextureID;
}
glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
memset( textMem, 0, totalMem);
unsigned int glyphNum = 0;
unsigned char* currTextPtr = textMem;
for( int x = 0; x < numTextures - 1; ++x)
{
glyphNum = FillGlyphs( glyphNum, glTextureID[x], textureWidth, maxTextSize, currTextPtr);
CreateTexture( x, textureWidth, maxTextSize, currTextPtr);
currTextPtr += ( textureWidth * maxTextSize);
++glyphNum;
}
glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
CreateTexture( numTextures - 1, textureWidth, heightRemain, currTextPtr);
}
else
{
textureHeight = NextPowerOf2( textureHeight+padding*2);
totalMem = textureWidth * textureHeight;
glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
memset( textMem, 0, totalMem);
FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem);
CreateTexture( 0, textureWidth, textureHeight, textMem);
}
delete [] textMem;
return !err;
}
unsigned int FTGLTextureFont::FillGlyphs( unsigned int glyphStart, GLuint id, GLsizei width, GLsizei height, unsigned char* textdata)
{
int currentTextX = padding;
int currentTextY = padding;// + padding;
float currTextU = (float)padding / (float)width;
float currTextV = (float)padding / (float)height;
unsigned int n;
if( !maxTextSize)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
for( n = glyphStart; n <= numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING);
if( ftGlyph)
{
unsigned char* data = textdata + (( currentTextY * width) + currentTextX);
currTextU = (float)currentTextX / (float)width;
FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, id, data, width, height, currTextU, currTextV);
glyphList->Add( tempGlyph);
glyphHeight = ( charSize.Height()) + padding;
glyphWidth = ( charSize.Width()) + padding;
GetSize();
GLuint totalMem;
currentTextX += glyphWidth;
if( currentTextX > ( width - glyphWidth))
{
currentTextY += glyphHeight;
if( currentTextY > ( height - glyphHeight))
return n;
currentTextX = padding;
currTextV = (float)currentTextY / (float)height;
}
}
else
{
err = face.Error();
}
}
if( textureHeight > (maxTextSize-padding*2))
{
numTextures = static_cast<int>( textureHeight / (maxTextSize-padding*2)) + 1;
if( numTextures > 15) // FIXME
numTextures = 15;
GLsizei heightRemain = NextPowerOf2( textureHeight % (maxTextSize-padding*2));
totalMem = ((maxTextSize * ( numTextures - 1)) + heightRemain) * textureWidth;
glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
memset( textMem, 0, totalMem);
unsigned int glyphNum = 0;
unsigned char* currTextPtr = textMem;
for( int x = 0; x < numTextures - 1; ++x)
{
glyphNum = FillGlyphs( glyphNum, glTextureID[x], textureWidth, maxTextSize, currTextPtr,renderContext);
CreateTexture( glTextureID[x], textureWidth, maxTextSize, currTextPtr);
currTextPtr += ( textureWidth * maxTextSize);
++glyphNum;
}
glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr,renderContext);
CreateTexture( glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
}
else
{
textureHeight = NextPowerOf2( textureHeight+padding*2);
totalMem = textureWidth * textureHeight;
glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
memset( textMem, 0, totalMem);
FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem,renderContext);
CreateTexture( glTextureID[0], textureWidth, textureHeight, textMem);
}
delete [] textMem;
return !err;
}
// mrn@changes
unsigned int FTGLTextureFont::FillGlyphs( unsigned int glyphStart, GLuint id, GLsizei width, GLsizei height, unsigned char* textdata, unsigned int renderContext)
{
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
int currentTextX = padding;
int currentTextY = padding;// + padding;
float currTextU = (float)padding / (float)width;
float currTextV = (float)padding / (float)height;
unsigned int n;
for( n = glyphStart; n <= numGlyphs; ++n)
{
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING);
if( ftGlyph)
{
unsigned char* data = textdata + (( currentTextY * width) + currentTextX);
currTextU = (float)currentTextX / (float)width;
FTTextureGlyph* tempGlyph = new FTTextureGlyph( *ftGlyph, id, data, width, height, currTextU, currTextV);
glyphList->Add( tempGlyph);
currentTextX += glyphWidth;
if( currentTextX > ( width - glyphWidth))
{
currentTextY += glyphHeight;
if( currentTextY > ( height - glyphHeight))
return n;
currentTextX = padding;
currTextV = (float)currentTextY / (float)height;
}
}
else
{
err = face.Error();
}
}
return n;
return n;
}
void FTGLTextureFont::GetSize()
{
//work out the max width. Most likely maxTextSize
textureWidth = NextPowerOf2( (numGlyphs * glyphWidth) + padding*2);
if( textureWidth > maxTextSize)
{
textureWidth = maxTextSize;
}
int h = static_cast<int>( (textureWidth-padding*2) / glyphWidth);
//work out the max width. Most likely maxTextSize
textureWidth = NextPowerOf2( (numGlyphs * glyphWidth) + padding*2);
if( textureWidth > maxTextSize)
{
textureWidth = maxTextSize;
}
int h = static_cast<int>( (textureWidth-padding*2) / glyphWidth);
textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
}
// mrn@changes
void FTGLTextureFont::CreateTexture( GLuint id, GLsizei width, GLsizei height, unsigned char* data)
{
glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
glBindTexture( GL_TEXTURE_2D, glTextureID[id]);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
glBindTexture( GL_TEXTURE_2D, id);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
}
void FTGLTextureFont::render( const char* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string);
// mrn@changes
void FTGLTextureFont::render( const char* string, unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string,renderContext);
glPopAttrib();
glPopAttrib();
}
void FTGLTextureFont::render( const wchar_t* string)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string);
glPopAttrib();
// mrn@changes
void FTGLTextureFont::render( const wchar_t* string, unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
FTFont::render( string,renderContext);
glPopAttrib();
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTGLTextureFont__
#define __FTGLTextureFont__
#ifndef __FTGLTextureFont__
#define __FTGLTextureFont__
#include "FTGL.h"
#include "FTFont.h"
@@ -10,142 +10,151 @@ class FTTextureGlyph;
* FTGLTextureFont is a specialisation of the FTFont class for handling
* Texture mapped fonts
*
* @see FTFont
* @see FTFont
*/
class FTGL_EXPORT FTGLTextureFont : public FTFont
{
public:
/**
* Default Constructor
*/
FTGLTextureFont();
FTGLTextureFont(int textureSize);
/**
* Destructor
*/
virtual ~FTGLTextureFont();
/**
* Get the total width of the texture that holds this font
*/
virtual GLsizei TextureWidth() const { return textureWidth;}
/**
* Get the total height of the texture that holds this font
*/
virtual GLsizei TextureHeight() const { return textureHeight;}
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
virtual void render( const char* string);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
virtual void render( const wchar_t* string);
public:
/**
* Default Constructor
*/
FTGLTextureFont();
FTGLTextureFont(int textureSize);
/**
* Destructor
*/
virtual ~FTGLTextureFont();
/**
* Get the total width of the texture that holds this font
*/
virtual GLsizei TextureWidth() const { return textureWidth;}
/**
* Get the total height of the texture that holds this font
*/
virtual GLsizei TextureHeight() const { return textureHeight;}
/**
* Renders a string of characters
*
* @param string 'C' style string to be output.
*/
// mrn@changes
virtual void render( const char* string, unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string wchar_t string to be output.
*/
// mrn@changes
virtual void render( const wchar_t* string, unsigned int renderContext=0);
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
bool MakeGlyphList();
/**
* Draw a series of glyphs into texture memory
*
* This function will start with glyph index glyphStart and draw each
* glyph into the texture until it runs out of space in the current
* texture. It will return the index of the last glyph it drew so
* that if more textures are required, we know where to start from.
*
* @param glyphStart The index of the first glyph to be drawn
* @param textID The index of the openGLtexture to draw glyphs into
* @param textureWidth The texture width
* @param textureHeight The texture height
* @param textMem A pointer to the texture memory.
*/
unsigned int FillGlyphs( unsigned int glyphStart, GLuint textID, GLsizei textureWidth, GLsizei textureHeight, unsigned char* textMem);
private:
/**
* Constructs the internal glyph cache.
*
* This a list of glyphs processed for openGL rendering NOT
* freetype glyphs
*/
// mrn@changes
bool MakeGlyphList( unsigned int renderContext=0);
/**
* Draw a series of glyphs into texture memory
*
* This function will start with glyph index glyphStart and draw each
* glyph into the texture until it runs out of space in the current
* texture. It will return the index of the last glyph it drew so
* that if more textures are required, we know where to start from.
*
* @param glyphStart The index of the first glyph to be drawn
* @param textID The index of the openGLtexture to draw glyphs into
* @param textureWidth The texture width
* @param textureHeight The texture height
* @param textMem A pointer to the texture memory.
*/
// mrn@changes
unsigned int FillGlyphs( unsigned int glyphStart, GLuint textID, GLsizei textureWidth, GLsizei textureHeight, unsigned char* textMem, unsigned int renderContext=0);
/**
* Get the size of a block of memory required to layout the glyphs
*
* Calculates a width and height based on the glyph sizes and the
* number of glyphs.
*/
void GetSize();
/**
* Get the size of a block of memory required to layout the glyphs
*
* Calculates a width and height based on the glyph sizes and the
* number of glyphs.
*/
void GetSize();
/**
* Creates an OpenGL texture object.
*
* The format is GL_ALPHA and the params are
* GL_TEXTURE_WRAP_S = GL_CLAMP
* GL_TEXTURE_WRAP_T = GL_CLAMP
* GL_TEXTURE_MAG_FILTER = GL_LINEAR
* GL_TEXTURE_MIN_FILTER = GL_LINEAR
* Note that mipmapping is NOT used
* @param id The index into an array of glTextureIDs.
* @param width The width of the texture in bytes
* @param height The number of rows of bytes.
* @param data A pointer to the texture data
*/
void CreateTexture( GLuint id, GLsizei width, GLsizei height, unsigned char* data);
/**
* The maximum texture dimension on this OpenGL implemetation
*/
GLsizei maxTextSize;
/**
* The minimum texture width required to hold the glyphs
*/
GLsizei textureWidth;
/**
* The minimum texture height required to hold the glyphs
*/
GLsizei textureHeight;
/**
* An array of texture ids
*/
unsigned long glTextureID[16];
/**
* The number of textures required to hold the glyphs
*/
int numTextures;
/**
* Creates an OpenGL texture object.
*
* The format is GL_ALPHA and the params are
* GL_TEXTURE_WRAP_S = GL_CLAMP
* GL_TEXTURE_WRAP_T = GL_CLAMP
* GL_TEXTURE_MAG_FILTER = GL_LINEAR
* GL_TEXTURE_MIN_FILTER = GL_LINEAR
* Note that mipmapping is NOT used
// mrn@changes
// the glTexture id
* @param id The index into an array of glTextureIDs.
* @param width The width of the texture in bytes
* @param height The number of rows of bytes.
* @param data A pointer to the texture data
*/
void CreateTexture( GLuint id, GLsizei width, GLsizei height, unsigned char* data);
/**
* The maximum texture dimension on this OpenGL implemetation
*/
GLsizei maxTextSize;
/**
* The minimum texture width required to hold the glyphs
*/
GLsizei textureWidth;
/**
* The minimum texture height required to hold the glyphs
*/
GLsizei textureHeight;
/**
* An array of texture ids
*/
// mrn@changes
// unsigned long glTextureID[16];
typedef std::vector< unsigned long* > ContextTextureId;
ContextTextureId glContextTextureID;
/**
* The number of textures required to hold the glyphs
*/
int numTextures;
/**
* The memeory where the textures are built before beiing transferred
* to OpenGL
*/
unsigned char* textMem;
/**
* The max height for glyphs in the current font
*/
int glyphHeight;
/**
* The memeory where the textures are built before beiing transferred
* to OpenGL
*/
unsigned char* textMem;
/**
* The max height for glyphs in the current font
*/
int glyphHeight;
/**
* The max width for glyphs in the current font
*/
int glyphWidth;
/**
* The max width for glyphs in the current font
*/
int glyphWidth;
/**
* A value to be added to the height and width to ensure that
* glyphs don't overlap in the texture
*/
int padding;
/**
* A value to be added to the height and width to ensure that
* glyphs don't overlap in the texture
*/
int padding;
};

View File

@@ -1,5 +1,5 @@
#ifndef __FTGlyph__
#define __FTGlyph__
#ifndef __FTGlyph__
#define __FTGlyph__
#include "FTGL.h"
@@ -21,59 +21,59 @@
*/
class FTGL_EXPORT FTGlyph
{
public:
/**
* Constructor
*/
FTGlyph();
public:
/**
* Constructor
*/
FTGlyph();
/**
* Destructor
*/
virtual ~FTGlyph();
/**
* Destructor
*/
virtual ~FTGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen) = 0;
/**
* Return the advance width for this glyph.
*
* @return advance width.
*/
float Advance() const { return advance;}
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err;}
protected:
/**
* The advance distance for this glyph
*/
float advance;
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen) = 0;
/**
* Return the advance width for this glyph.
*
* @return advance width.
*/
float Advance() const { return advance;}
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err;}
protected:
/**
* The advance distance for this glyph
*/
float advance;
/**
* Vector from the pen position to the topleft corner of the glyph
*/
FT_Vector pos;
/**
* Vector from the pen position to the topleft corner of the glyph
*/
FT_Vector pos;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
private:
/**
* Current error code. Zero means no error.
*/
FT_Error err;
private:
};
#endif // __FTGlyph__
#endif // __FTGlyph__

View File

@@ -1,67 +1,67 @@
#include "FTGlyphContainer.h"
#include "FTGlyph.h"
#include "FTFace.h"
#include "FTGlyphContainer.h"
#include "FTGlyph.h"
#include "FTFace.h"
FTGlyphContainer::FTGlyphContainer( FTFace* f, unsigned int g, bool p)
: preCache( p),
numGlyphs( g),
face( f),
err( 0)
: preCache( p),
numGlyphs( g),
face( f),
err( 0)
{
glyphs.reserve( g);
glyphs.reserve( g);
}
FTGlyphContainer::~FTGlyphContainer()
{
vector<FTGlyph*>::iterator iter;
for( iter = glyphs.begin(); iter != glyphs.end(); ++iter)
{
delete *iter;
}
glyphs.clear();
vector<FTGlyph*>::iterator iter;
for( iter = glyphs.begin(); iter != glyphs.end(); ++iter)
{
delete *iter;
}
glyphs.clear();
}
bool FTGlyphContainer::Add( FTGlyph* tempGlyph)
{
// At the moment we are using a vector. Vectors don't return bool.
glyphs.push_back( tempGlyph);
return true;
// At the moment we are using a vector. Vectors don't return bool.
glyphs.push_back( tempGlyph);
return true;
}
float FTGlyphContainer::Advance( unsigned int index, unsigned int next)
{
unsigned int left = face->CharIndex( index);
unsigned int right = face->CharIndex( next);
unsigned int left = face->CharIndex( index);
unsigned int right = face->CharIndex( next);
float width = face->KernAdvance( left, right).x;
if (left<glyphs.size()) width += glyphs[left]->Advance();
return width;
float width = face->KernAdvance( left, right).x;
if (left<glyphs.size()) width += glyphs[left]->Advance();
return width;
}
FT_Vector& FTGlyphContainer::render( unsigned int index, unsigned int next, FT_Vector pen)
{
kernAdvance.x = 0; kernAdvance.y = 0;
unsigned int left = face->CharIndex( index);
unsigned int right = face->CharIndex( next);
kernAdvance = face->KernAdvance( left, right);
if( !face->Error())
{
if (left<glyphs.size()) advance = glyphs[left]->Render( pen);
}
kernAdvance.x = advance + kernAdvance.x;
// kernAdvance.y = advance.y + kernAdvance.y;
return kernAdvance;
kernAdvance.x = 0; kernAdvance.y = 0;
unsigned int left = face->CharIndex( index);
unsigned int right = face->CharIndex( next);
kernAdvance = face->KernAdvance( left, right);
if( !face->Error())
{
if (left<glyphs.size()) advance = glyphs[left]->Render( pen);
}
kernAdvance.x = advance + kernAdvance.x;
// kernAdvance.y = advance.y + kernAdvance.y;
return kernAdvance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTGlyphContainer__
#define __FTGlyphContainer__
#ifndef __FTGlyphContainer__
#define __FTGlyphContainer__
#include "FTGL.h"
@@ -22,95 +22,95 @@ using namespace std;
*/
class FTGL_EXPORT FTGlyphContainer
{
public:
/**
* Constructor
*
* @param face The Freetype face
* @param numGlyphs the number of glyphs in this face
* @param p A flag to indicate preprocessing of glyphs.
* Not used.
*/
FTGlyphContainer( FTFace* face, unsigned int numGlyphs, bool p = false);
public:
/**
* Constructor
*
* @param face The Freetype face
* @param numGlyphs the number of glyphs in this face
* @param p A flag to indicate preprocessing of glyphs.
* Not used.
*/
FTGlyphContainer( FTFace* face, unsigned int numGlyphs, bool p = false);
/**
* Destructor
*/
virtual ~FTGlyphContainer();
/**
* Destructor
*/
virtual ~FTGlyphContainer();
/**
* Adds a glyph to this glyph list.
*
* @param glyph
* @return <code>true</code>
*/
bool Add( FTGlyph* glyph);
/**
* Adds a glyph to this glyph list.
*
* @param glyph
* @return <code>true</code>
*/
bool Add( FTGlyph* glyph);
/**
* Returns the kerned advance width for a glyph.
*
* @param index glyph index of the character
* @param next the next glyph in a string
* @return advance width
*/
float Advance( unsigned int index, unsigned int next);
/**
* renders a character
* @param index the glyph to be rendered
* @param next the next glyph in the string. Used for kerning.
* @param pen the position to render the glyph
* @return The distance to advance the pen position after rendering
*/
FT_Vector& render( unsigned int index, unsigned int next, FT_Vector pen);
/**
* Queries the Font for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
/**
* Returns the kerned advance width for a glyph.
*
* @param index glyph index of the character
* @param next the next glyph in a string
* @return advance width
*/
float Advance( unsigned int index, unsigned int next);
/**
* renders a character
* @param index the glyph to be rendered
* @param next the next glyph in the string. Used for kerning.
* @param pen the position to render the glyph
* @return The distance to advance the pen position after rendering
*/
FT_Vector& render( unsigned int index, unsigned int next, FT_Vector pen);
/**
* Queries the Font for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
private:
/**
* A flag to indicate preprocessing of glyphs. Not used.
*/
bool preCache;
private:
/**
* A flag to indicate preprocessing of glyphs. Not used.
*/
bool preCache;
/**
* How meny glyphs are stored in this container
*/
int numGlyphs;
/**
* How meny glyphs are stored in this container
*/
int numGlyphs;
/**
* The current Freetype face
*/
FTFace* face;
/**
* The current Freetype face
*/
FTFace* face;
/**
* The kerning vector for the current pair of glyphs
*/
FT_Vector kernAdvance;
/**
* The kerning vector for the current pair of glyphs
*/
FT_Vector kernAdvance;
/**
* The advance for the glyph being rendered
*/
float advance;
/**
* The advance for the glyph being rendered
*/
float advance;
/**
* A structure to hold the glyphs
*/
vector<FTGlyph*> glyphs;
// typedef pair<int, FTGlyph*> CHARREF; // glyphIndex, glyph
// vector<CHARREF> glyphs;
// map< int, FTGlyph*> CHARREF; // charCode, glyph
/**
* A structure to hold the glyphs
*/
vector<FTGlyph*> glyphs;
// typedef pair<int, FTGlyph*> CHARREF; // glyphIndex, glyph
// vector<CHARREF> glyphs;
// map< int, FTGlyph*> CHARREF; // charCode, glyph
/**
* Current error code. Zero means no error.
*/
FT_Error err;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
};
#endif // __FTGlyphContainer__
#endif // __FTGlyphContainer__

View File

@@ -1,5 +1,5 @@
#ifndef __FTLibrary__
#define __FTLibrary__
#ifndef __FTLibrary__
#define __FTLibrary__
#include "FTGL.h"
@@ -23,73 +23,73 @@
* for errors using the following code...
* <code>err = FTLibrary::Instance().Error();</code>
*
* @see "Freetype 2 Documentation - 2.0.4"
* @see "Freetype 2 Documentation - 2.0.4"
*
*/
class FTGL_EXPORT FTLibrary
{
public:
/**
* Global acces point to the single FTLibrary object.
*
* @return The global <code>FTLibrary</code> object.
*/
static FTLibrary& Instance();
public:
/**
* Global acces point to the single FTLibrary object.
*
* @return The global <code>FTLibrary</code> object.
*/
static FTLibrary& Instance();
/**
* Gets a pointer to the native Freetype library.
*
* @return A handle to a FreeType library instance.
*/
FT_Library* GetLibrary() const { return lib;}
/**
* Queries the library for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
/**
* Destructor
*
* Disposes of the Freetype library
*/
virtual ~FTLibrary();
private:
/**
* Default constructors.
*
* Made private to stop clients creating there own FTLibrary
* objects.
*/
FTLibrary();
FTLibrary( const FT_Library&){}
FTLibrary& operator=( const FT_Library&) { return *this; }
/**
* Initialises the Freetype library
*
* Even though this function indicates success via the return value,
* clients can't see this so must check the error codes.
*
* @return <code>true</code> if the Freetype library was
* successfully initialised, <code>false</code>
* otherwise.
*/
bool Init();
/**
* Freetype library handle.
*/
FT_Library* lib;
// FTC_Manager* manager;
/**
* Gets a pointer to the native Freetype library.
*
* @return A handle to a FreeType library instance.
*/
FT_Library* GetLibrary() const { return lib;}
/**
* Queries the library for errors.
*
* @return The current error code.
*/
virtual FT_Error Error() const { return err;}
/**
* Destructor
*
* Disposes of the Freetype library
*/
virtual ~FTLibrary();
private:
/**
* Default constructors.
*
* Made private to stop clients creating there own FTLibrary
* objects.
*/
FTLibrary();
FTLibrary( const FT_Library&){}
FTLibrary& operator=( const FT_Library&) { return *this; }
/**
* Initialises the Freetype library
*
* Even though this function indicates success via the return value,
* clients can't see this so must check the error codes.
*
* @return <code>true</code> if the Freetype library was
* successfully initialised, <code>false</code>
* otherwise.
*/
bool Init();
/**
* Freetype library handle.
*/
FT_Library* lib;
// FTC_Manager* manager;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
};
#endif // __FTLibrary__
#endif // __FTLibrary__

View File

@@ -1,82 +1,82 @@
#include "FTOutlineGlyph.h"
#include "FTVectoriser.h"
#include "FTGL.h"
#include "FTOutlineGlyph.h"
#include "FTVectoriser.h"
#include "FTGL.h"
FTOutlineGlyph::FTOutlineGlyph( FT_Glyph glyph)
: FTGlyph(),
vectoriser(0),
numPoints(0),
numContours(0),
contourLength(0),
data(0),
glList(0)
: FTGlyph(),
vectoriser(0),
numPoints(0),
numContours(0),
contourLength(0),
data(0),
glList(0)
{
if( ft_glyph_format_outline != glyph->format)
{
return;
}
if( ft_glyph_format_outline != glyph->format)
{
return;
}
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
contourLength = new int[ numContours];
for( int cn = 0; cn < numContours; ++cn)
{
contourLength[cn] = vectoriser->contourSize( cn);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
vectoriser->MakeOutline( data);
advance = glyph->advance.x >> 16;
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
contourLength = new int[ numContours];
for( int cn = 0; cn < numContours; ++cn)
{
contourLength[cn] = vectoriser->contourSize( cn);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
vectoriser->MakeOutline( data);
advance = glyph->advance.x >> 16;
delete vectoriser;
if ( ( numContours < 1) || ( numPoints < 3))
return;
glList = glGenLists(1);
int d = 0;
delete vectoriser;
if ( ( numContours < 1) || ( numPoints < 3))
return;
glList = glGenLists(1);
int d = 0;
glNewList( glList, GL_COMPILE);
for( int c = 0; c < numContours; ++c)
{
glBegin( GL_LINE_LOOP);
for( int p = 0; p < ( contourLength[c]); ++p)
{
glVertex2dv( data + d);
d += 3;
}
glEnd();
}
glEndList();
glNewList( glList, GL_COMPILE);
for( int c = 0; c < numContours; ++c)
{
glBegin( GL_LINE_LOOP);
for( int p = 0; p < ( contourLength[c]); ++p)
{
glVertex2dv( data + d);
d += 3;
}
glEnd();
}
glEndList();
// discard glyph image (bitmap or not)
FT_Done_Glyph( glyph); // Why does this have to be HERE
// discard glyph image (bitmap or not)
FT_Done_Glyph( glyph); // Why does this have to be HERE
}
FTOutlineGlyph::~FTOutlineGlyph()
{
delete [] data;
delete [] contourLength;
delete [] data;
delete [] contourLength;
}
float FTOutlineGlyph::Render( const FT_Vector& pen)
{
if( glList)
{
glTranslatef( pen.x, pen.y, 0);
glCallList( glList);
glTranslatef( -pen.x, -pen.y, 0);
}
return advance;
if( glList)
{
glTranslatef( pen.x, pen.y, 0);
glCallList( glList);
glTranslatef( -pen.x, -pen.y, 0);
}
return advance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTOutlineGlyph__
#define __FTOutlineGlyph__
#ifndef __FTOutlineGlyph__
#define __FTOutlineGlyph__
#include "FTGL.h"
@@ -21,61 +21,61 @@ class FTVectoriser;
*/
class FTGL_EXPORT FTOutlineGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTOutlineGlyph( FT_Glyph glyph);
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTOutlineGlyph( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTOutlineGlyph();
/**
* Destructor
*/
virtual ~FTOutlineGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* An object that helps convert freetype outlines into point
* data
*/
FTVectoriser* vectoriser;
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* An object that helps convert freetype outlines into point
* data
*/
FTVectoriser* vectoriser;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
};
#endif // __FTOutlineGlyph__
#endif // __FTOutlineGlyph__

View File

@@ -1,37 +1,37 @@
#include "FTPixmapGlyph.h"
#include "FTGL.h"
#include "FTPixmapGlyph.h"
#include "FTGL.h"
FTPixmapGlyph::FTPixmapGlyph( FT_Glyph glyph)
: FTGlyph(),
destWidth(0),
destHeight(0),
numGreys(0),
data(0)
: FTGlyph(),
destWidth(0),
destHeight(0),
numGreys(0),
data(0)
{
// This function will always fail if the glyph's format isn't scalable????
FT_Error err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1);
if( err || ft_glyph_format_bitmap != glyph->format)
{
return;
}
// This function will always fail if the glyph's format isn't scalable????
FT_Error err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1);
if( err || ft_glyph_format_bitmap != glyph->format)
{
return;
}
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
numGreys = source->num_grays;
advance = glyph->advance.x >> 16;
numGreys = source->num_grays;
advance = glyph->advance.x >> 16;
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
// FIXME What about dest alignment?
destWidth = srcWidth;
destHeight = srcHeight;
@@ -44,49 +44,49 @@ FTPixmapGlyph::FTPixmapGlyph( FT_Glyph glyph)
for(int y = 0; y < srcHeight; ++y)
{
--destHeight;
for(int x = 0; x < srcWidth; ++x)
{
*( data + ( destHeight * destWidth + x) * 4 + 0) = static_cast<unsigned char>( ftglColour[0] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 1) = static_cast<unsigned char>( ftglColour[1] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 2) = static_cast<unsigned char>( ftglColour[2] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 3) = static_cast<unsigned char>( ftglColour[3] * (*( source->buffer + ( y * srcPitch) + x)));
}
--destHeight;
for(int x = 0; x < srcWidth; ++x)
{
*( data + ( destHeight * destWidth + x) * 4 + 0) = static_cast<unsigned char>( ftglColour[0] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 1) = static_cast<unsigned char>( ftglColour[1] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 2) = static_cast<unsigned char>( ftglColour[2] * 255.0f);
*( data + ( destHeight * destWidth + x) * 4 + 3) = static_cast<unsigned char>( ftglColour[3] * (*( source->buffer + ( y * srcPitch) + x)));
}
}
destHeight = srcHeight;
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
}
FTPixmapGlyph::~FTPixmapGlyph()
{
delete[] data;
delete[] data;
}
float FTPixmapGlyph::Render( const FT_Vector& pen)
{
if( data != 0 )
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
// Move the glyph origin
glBitmap( 0, 0, 0.0, 0.0, pen.x + pos.x, pen.y - pos.y, (const GLubyte *)0);
if( data != 0 )
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
// Move the glyph origin
glBitmap( 0, 0, 0.0, 0.0, pen.x + pos.x, pen.y - pos.y, (const GLubyte *)0);
glPixelStorei( GL_UNPACK_ROW_LENGTH, destWidth);
glPixelStorei( GL_UNPACK_ROW_LENGTH, destWidth);
glDrawPixels( destWidth, destHeight, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)data);
glDrawPixels( destWidth, destHeight, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)data);
// Restore the glyph origin
glBitmap( 0, 0, 0.0, 0.0, -pen.x - pos.x, -pen.y + pos.y, (const GLubyte *)0);
// Restore the glyph origin
glBitmap( 0, 0, 0.0, 0.0, -pen.x - pos.x, -pen.y + pos.y, (const GLubyte *)0);
glPopClientAttrib();
}
glPopClientAttrib();
}
return advance;
return advance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTPixmapGlyph__
#define __FTPixmapGlyph__
#ifndef __FTPixmapGlyph__
#define __FTPixmapGlyph__
#include "FTGL.h"
@@ -7,7 +7,7 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
#include "FTGlyph.h"
/**
@@ -18,51 +18,51 @@
*/
class FTGL_EXPORT FTPixmapGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPixmapGlyph( FT_Glyph glyph);
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPixmapGlyph( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTPixmapGlyph();
/**
* Destructor
*/
virtual ~FTPixmapGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
// attributes
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
// attributes
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* The number of greys or bit depth of the image
*/
int numGreys;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* The number of greys or bit depth of the image
*/
int numGreys;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
};
#endif // __FTPixmapGlyph__
#endif // __FTPixmapGlyph__

View File

@@ -1,6 +1,6 @@
#include "FTPolyGlyph.h"
#include "FTVectoriser.h"
#include "FTPolyGlyph.h"
#include "FTVectoriser.h"
#ifndef CALLBACK
#define CALLBACK
@@ -9,145 +9,145 @@
void CALLBACK ftglError( GLenum errCode)
{
// const GLubyte* estring;
// estring = gluErrorString( errCode);
// fprintf( stderr, "ERROR : %s\n", estring);
// exit(1);
// const GLubyte* estring;
// estring = gluErrorString( errCode);
// fprintf( stderr, "ERROR : %s\n", estring);
// exit(1);
}
void CALLBACK ftglVertex( void* data)
{
glVertex3dv( (double*)data);
glVertex3dv( (double*)data);
}
void CALLBACK ftglBegin( GLenum type)
{
glBegin( type);
glBegin( type);
}
void CALLBACK ftglEnd()
{
glEnd();
glEnd();
}
void CALLBACK ftglCombine( GLdouble coords[3], void* vertex_data[4], GLfloat weight[4], void** outData)
{
double* vertex = new double[3]; // FIXME MEM LEAK
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
double* vertex = new double[3]; // FIXME MEM LEAK
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
*outData = vertex;
*outData = vertex;
}
FTPolyGlyph::FTPolyGlyph( FT_Glyph glyph)
: FTGlyph(),
vectoriser(0),
numPoints(0),
numContours(0),
contourLength(0),
data(0),
glList(0)
: FTGlyph(),
vectoriser(0),
numPoints(0),
numContours(0),
contourLength(0),
data(0),
glList(0)
{
if( ft_glyph_format_outline != glyph->format)
{ return;}
if( ft_glyph_format_outline != glyph->format)
{ return;}
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
contourLength = new int[ numContours];
for( int c = 0; c < numContours; ++c)
{
contourLength[c] = vectoriser->contourSize( c);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
// FIXME MakeMesh
vectoriser->MakeOutline( data);
contourFlag = vectoriser->ContourFlag();
advance = glyph->advance.x >> 16;
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
contourLength = new int[ numContours];
for( int c = 0; c < numContours; ++c)
{
contourLength[c] = vectoriser->contourSize( c);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
// FIXME MakeMesh
vectoriser->MakeOutline( data);
contourFlag = vectoriser->ContourFlag();
advance = glyph->advance.x >> 16;
delete vectoriser;
delete vectoriser;
if ( ( numContours < 1) || ( numPoints < 3))
return;
if ( ( numContours < 1) || ( numPoints < 3))
return;
Tesselate();
Tesselate();
// discard glyph image (bitmap or not)
FT_Done_Glyph( glyph); // Why does this have to be HERE
// discard glyph image (bitmap or not)
FT_Done_Glyph( glyph); // Why does this have to be HERE
}
void FTPolyGlyph::Tesselate()
{
glList = glGenLists(1);
GLUtesselator* tobj = gluNewTess();
int d = 0;
gluTessCallback( tobj, GLU_TESS_BEGIN, (void (CALLBACK*)())ftglBegin);
gluTessCallback( tobj, GLU_TESS_VERTEX, (void (CALLBACK*)())ftglVertex);
gluTessCallback( tobj, GLU_TESS_COMBINE, (void (CALLBACK*)())ftglCombine);
gluTessCallback( tobj, GLU_TESS_END, ftglEnd);
gluTessCallback( tobj, GLU_TESS_ERROR, (void (CALLBACK*)())ftglError);
glNewList( glList, GL_COMPILE);
if( contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill
{
gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
}
else
{
gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
}
gluTessProperty( tobj, GLU_TESS_TOLERANCE, 0);
gluTessBeginPolygon( tobj, NULL);
for( int c = 0; c < numContours; ++c)
{
gluTessBeginContour( tobj);
for( int p = 0; p < ( contourLength[c]); ++p)
{
gluTessVertex( tobj, data + d, data + d);
d += 3;
}
gluTessEndContour( tobj);
}
gluTessEndPolygon( tobj);
glEndList();
glList = glGenLists(1);
GLUtesselator* tobj = gluNewTess();
int d = 0;
gluTessCallback( tobj, GLU_TESS_BEGIN, (void (CALLBACK*)())ftglBegin);
gluTessCallback( tobj, GLU_TESS_VERTEX, (void (CALLBACK*)())ftglVertex);
gluTessCallback( tobj, GLU_TESS_COMBINE, (void (CALLBACK*)())ftglCombine);
gluTessCallback( tobj, GLU_TESS_END, ftglEnd);
gluTessCallback( tobj, GLU_TESS_ERROR, (void (CALLBACK*)())ftglError);
glNewList( glList, GL_COMPILE);
if( contourFlag & ft_outline_even_odd_fill) // ft_outline_reverse_fill
{
gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
}
else
{
gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
}
gluTessProperty( tobj, GLU_TESS_TOLERANCE, 0);
gluTessBeginPolygon( tobj, NULL);
for( int c = 0; c < numContours; ++c)
{
gluTessBeginContour( tobj);
for( int p = 0; p < ( contourLength[c]); ++p)
{
gluTessVertex( tobj, data + d, data + d);
d += 3;
}
gluTessEndContour( tobj);
}
gluTessEndPolygon( tobj);
glEndList();
gluDeleteTess( tobj);
gluDeleteTess( tobj);
}
FTPolyGlyph::~FTPolyGlyph()
{
delete [] data;
delete [] contourLength;
delete [] data;
delete [] contourLength;
}
float FTPolyGlyph::Render( const FT_Vector& pen)
{
if( glList)
{
glTranslatef( pen.x, pen.y, 0);
glCallList( glList);
glTranslatef( -pen.x, -pen.y, 0);
}
return advance;
if( glList)
{
glTranslatef( pen.x, pen.y, 0);
glCallList( glList);
glTranslatef( -pen.x, -pen.y, 0);
}
return advance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTPolyGlyph__
#define __FTPolyGlyph__
#ifndef __FTPolyGlyph__
#define __FTPolyGlyph__
#include "FTGL.h"
@@ -21,73 +21,73 @@ class FTVectoriser;
*/
class FTGL_EXPORT FTPolyGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPolyGlyph( FT_Glyph glyph);
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPolyGlyph( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTPolyGlyph();
/**
* Destructor
*/
virtual ~FTPolyGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* Convert the point data into a mesh.
*
* Uses GLUtesselator to create a mesh
*/
void Tesselate();
/**
* An object that helps convert freetype outlines into point
* data
*/
FTVectoriser* vectoriser;
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
private:
/**
* Convert the point data into a mesh.
*
* Uses GLUtesselator to create a mesh
*/
void Tesselate();
/**
* An object that helps convert freetype outlines into point
* data
*/
FTVectoriser* vectoriser;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* An flag indicating the tesselation rules for this glyph
*/
int contourFlag;
/**
* An flag indicating the tesselation rules for this glyph
*/
int contourFlag;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
};
#endif // __FTPolyGlyph__
#endif // __FTPolyGlyph__

View File

@@ -1,11 +1,11 @@
#include "FTSize.h"
#include "FTGL.h"
#include "FTSize.h"
#include "FTGL.h"
FTSize::FTSize()
: ftFace(0),
size(0),
err(0)
: ftFace(0),
size(0),
err(0)
{}
@@ -15,77 +15,77 @@ FTSize::~FTSize()
bool FTSize::CharSize( FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution )
{
ftFace = face;
size = point_size;
err = FT_Set_Char_Size( *ftFace, 0L, point_size * 64, x_resolution, y_resolution);
ftSize = (*ftFace)->size;
return !err;
ftFace = face;
size = point_size;
err = FT_Set_Char_Size( *ftFace, 0L, point_size * 64, x_resolution, y_resolution);
ftSize = (*ftFace)->size;
return !err;
}
int FTSize::Ascender() const
{
return ftSize->metrics.ascender >> 6;
return ftSize->metrics.ascender >> 6;
}
int FTSize::Descender() const
{
return ftSize->metrics.descender >> 6;
return ftSize->metrics.descender >> 6;
}
int FTSize::Height() const
{
if( FT_IS_SCALABLE((*ftFace)))
{
float height;
if( FT_IS_SFNT((*ftFace))) // Don't think this is correct
{
height = ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin); // bbox.yMax-bbox.yMin
}
else
{
height = ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) >> 16; // bbox.yMax-bbox.yMin
}
if( FT_IS_SCALABLE((*ftFace)))
{
float height;
if( FT_IS_SFNT((*ftFace))) // Don't think this is correct
{
height = ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin); // bbox.yMax-bbox.yMin
}
else
{
height = ((*ftFace)->bbox.yMax - (*ftFace)->bbox.yMin) >> 16; // bbox.yMax-bbox.yMin
}
height = height * ( (float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM);
return static_cast<int>(height);
}
else
{
return ftSize->metrics.height >> 6;
}
height = height * ( (float)ftSize->metrics.y_ppem / (float)(*ftFace)->units_per_EM);
return static_cast<int>(height);
}
else
{
return ftSize->metrics.height >> 6;
}
}
int FTSize::Width() const
{
if( FT_IS_SCALABLE((*ftFace)))
{
float width;
if( FT_IS_SFNT((*ftFace))) // Don't think this is correct
{
width = ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin); // bbox.xMax-bbox.xMin
}
else
{
width = ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) >> 16; // bbox.xMax-bbox.xMin
}
width = width * ( (float)ftSize->metrics.x_ppem / (float)(*ftFace)->units_per_EM);
return static_cast<int>(width);
}
else
{
return ftSize->metrics.max_advance >> 6;
}
if( FT_IS_SCALABLE((*ftFace)))
{
float width;
if( FT_IS_SFNT((*ftFace))) // Don't think this is correct
{
width = ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin); // bbox.xMax-bbox.xMin
}
else
{
width = ((*ftFace)->bbox.xMax - (*ftFace)->bbox.xMin) >> 16; // bbox.xMax-bbox.xMin
}
width = width * ( (float)ftSize->metrics.x_ppem / (float)(*ftFace)->units_per_EM);
return static_cast<int>(width);
}
else
{
return ftSize->metrics.max_advance >> 6;
}
}
int FTSize::Underline() const
{
return 0;
return 0;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTSize__
#define __FTSize__
#ifndef __FTSize__
#define __FTSize__
#include "FTGL.h"
@@ -11,110 +11,110 @@
/**
* FTSize class provides an abstraction layer for the Freetype Size.
*
* @see "Freetype 2 Documentation - 2.0.4"
* @see "Freetype 2 Documentation - 2.0.4"
*
*/
class FTGL_EXPORT FTSize
{
public:
/**
* Default Constructor
*/
FTSize();
/**
* Destructor
*/
virtual ~FTSize();
/**
* Sets the char size for the current face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param point_size the face size in points (1/72 inch)
* @param x_resolution the horizontal resolution of the target device.
* @param y_resolution the vertical resolution of the target device.
* @return <code>true</code> if the size has been set. Clients should check Error() for more information if this function returns false()
*/
bool CharSize( FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution );
/**
* Gets the global ascender height for the face in pixels.
*
* @return Ascender height
*/
int Ascender() const;
/**
* Gets the global descender height for the face in pixels.
*
* @return Ascender height
*/
int Descender() const;
/**
* Gets the global face height for the face.
*
* If the face is scalable this returns the height of the global
* bounding box which ensures that any glyph will be less than or
* equal to this height. If the font isn't scalable there is no
* guarantee that glyphs will not be taller than this value.
*
* @return height in pixels.
*/
int Height() const;
/**
* Gets the global face width for the face.
*
* If the face is scalable this returns the width of the global
* bounding box which ensures that any glyph will be less than or
* equal to this width. If the font isn't scalable this value is
* the max_advance for the face.
*
* @return width in pixels.
*/
int Width() const;
/**
* Gets the underline position for the face.
*
* @return underline position in pixels
*/
int Underline() const;
public:
/**
* Default Constructor
*/
FTSize();
/**
* Destructor
*/
virtual ~FTSize();
/**
* Sets the char size for the current face.
*
* This doesn't guarantee that the size was set correctly. Clients
* should check errors.
*
* @param point_size the face size in points (1/72 inch)
* @param x_resolution the horizontal resolution of the target device.
* @param y_resolution the vertical resolution of the target device.
* @return <code>true</code> if the size has been set. Clients should check Error() for more information if this function returns false()
*/
bool CharSize( FT_Face* face, unsigned int point_size, unsigned int x_resolution, unsigned int y_resolution );
/**
* Gets the global ascender height for the face in pixels.
*
* @return Ascender height
*/
int Ascender() const;
/**
* Gets the global descender height for the face in pixels.
*
* @return Ascender height
*/
int Descender() const;
/**
* Gets the global face height for the face.
*
* If the face is scalable this returns the height of the global
* bounding box which ensures that any glyph will be less than or
* equal to this height. If the font isn't scalable there is no
* guarantee that glyphs will not be taller than this value.
*
* @return height in pixels.
*/
int Height() const;
/**
* Gets the global face width for the face.
*
* If the face is scalable this returns the width of the global
* bounding box which ensures that any glyph will be less than or
* equal to this width. If the font isn't scalable this value is
* the max_advance for the face.
*
* @return width in pixels.
*/
int Width() const;
/**
* Gets the underline position for the face.
*
* @return underline position in pixels
*/
int Underline() const;
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err; }
private:
/**
* The current Freetype face that this FTSize object relates to.
*/
FT_Face* ftFace;
/**
* The Freetype size.
*/
FT_Size ftSize;
/**
* The size in points.
*/
unsigned int size;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
/**
* Queries for errors.
*
* @return The current error code.
*/
FT_Error Error() const { return err; }
private:
/**
* The current Freetype face that this FTSize object relates to.
*/
FT_Face* ftFace;
/**
* The Freetype size.
*/
FT_Size ftSize;
/**
* The size in points.
*/
unsigned int size;
/**
* Current error code. Zero means no error.
*/
FT_Error err;
};
#endif // __FTSize__
#endif // __FTSize__

View File

@@ -1,64 +1,64 @@
#include "FTTextureGlyph.h"
#include "FTGL.h"
#include "FTTextureGlyph.h"
#include "FTGL.h"
FTTextureGlyph::FTTextureGlyph( FT_Glyph glyph, int id, unsigned char* data, GLsizei stride, GLsizei height, float u, float v)
: FTGlyph(),
destWidth(0),
destHeight(0),
numGreys(0),
glTextureID(id)
: FTGlyph(),
destWidth(0),
destHeight(0),
numGreys(0),
glTextureID(id)
{
// This function will always fail if the glyph's format isn't scalable????
err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1);
if( err || glyph->format != ft_glyph_format_bitmap)
{
return;
}
// This function will always fail if the glyph's format isn't scalable????
err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1);
if( err || glyph->format != ft_glyph_format_bitmap)
{
return;
}
FT_BitmapGlyph bitmap = ( FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
FT_BitmapGlyph bitmap = ( FT_BitmapGlyph)glyph;
FT_Bitmap* source = &bitmap->bitmap;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
//check the pixel mode
//ft_pixel_mode_grays
int srcWidth = source->width;
int srcHeight = source->rows;
int srcPitch = source->pitch;
numGreys = source->num_grays;
advance = glyph->advance.x >> 16;
numGreys = source->num_grays;
advance = glyph->advance.x >> 16;
pos.x = bitmap->left;
pos.y = bitmap->top;
pos.x = bitmap->left;
pos.y = bitmap->top;
destWidth = srcWidth;
destHeight = srcHeight;
for(int y = 0; y < srcHeight; ++y)
{
for(int x = 0; x < srcWidth; ++x)
{
*( data + ( y * stride + x)) = *( source->buffer + ( y * srcPitch) + x);
}
for(int x = 0; x < srcWidth; ++x)
{
*( data + ( y * stride + x)) = *( source->buffer + ( y * srcPitch) + x);
}
}
// 0
// +----+
// | |
// | |
// | |
// +----+
// 1
uv[0].x = u;
uv[0].y = v;
uv[1].x = uv[0].x + ( (float)destWidth / (float)stride);
uv[1].y = uv[0].y + ( (float)destHeight / (float)height);
// 0
// +----+
// | |
// | |
// | |
// +----+
// 1
uv[0].x = u;
uv[0].y = v;
uv[1].x = uv[0].x + ( (float)destWidth / (float)stride);
uv[1].y = uv[0].y + ( (float)destHeight / (float)height);
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph);
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph);
}
@@ -70,20 +70,20 @@ FTTextureGlyph::~FTTextureGlyph()
float FTTextureGlyph::Render( const FT_Vector& pen)
{
glGetIntegerv( GL_TEXTURE_2D_BINDING_EXT, &activeTextureID);
if( activeTextureID != glTextureID)
{
glBindTexture( GL_TEXTURE_2D, (GLuint)glTextureID);
}
glBegin( GL_QUADS);
glTexCoord2f( uv[0].x, uv[0].y); glVertex2f( pen.x + pos.x, pen.y + pos.y);
glTexCoord2f( uv[1].x, uv[0].y); glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y);
glTexCoord2f( uv[1].x, uv[1].y); glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y - destHeight);
glTexCoord2f( uv[0].x, uv[1].y); glVertex2f( pen.x + pos.x, pen.y + pos.y - destHeight);
glEnd();
glGetIntegerv( GL_TEXTURE_2D_BINDING_EXT, &activeTextureID);
if( activeTextureID != glTextureID)
{
glBindTexture( GL_TEXTURE_2D, (GLuint)glTextureID);
}
glBegin( GL_QUADS);
glTexCoord2f( uv[0].x, uv[0].y); glVertex2f( pen.x + pos.x, pen.y + pos.y);
glTexCoord2f( uv[1].x, uv[0].y); glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y);
glTexCoord2f( uv[1].x, uv[1].y); glVertex2f( pen.x + destWidth + pos.x, pen.y + pos.y - destHeight);
glTexCoord2f( uv[0].x, uv[1].y); glVertex2f( pen.x + pos.x, pen.y + pos.y - destHeight);
glEnd();
return advance;
return advance;
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTTextureGlyph__
#define __FTTextureGlyph__
#ifndef __FTTextureGlyph__
#define __FTTextureGlyph__
#include "FTGL.h"
@@ -19,78 +19,78 @@
*/
class FTGL_EXPORT FTTextureGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
* @param id The index of the texture that this glyph will
* be drawn in
* @param data A pointer to the texture memory
* @param stride The stride of the texture memory
* @param height The height (number of rows) of the texture memory
* @param u The texture co-ord for this glyph
* @param v The texture co-ord for this glyph
*/
FTTextureGlyph( FT_Glyph glyph, int id, unsigned char* data, GLsizei stride, GLsizei height, float u, float v);
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
* @param id The index of the texture that this glyph will
* be drawn in
* @param data A pointer to the texture memory
* @param stride The stride of the texture memory
* @param height The height (number of rows) of the texture memory
* @param u The texture co-ord for this glyph
* @param v The texture co-ord for this glyph
*/
FTTextureGlyph( FT_Glyph glyph, int id, unsigned char* data, GLsizei stride, GLsizei height, float u, float v);
/**
* Destructor
*/
virtual ~FTTextureGlyph();
/**
* Destructor
*/
virtual ~FTTextureGlyph();
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
/**
* The texture index of the currently active texture
*
* We call glGetIntegerv( GL_TEXTURE_2D_BINDING, activeTextureID);
* to get the currently active texture to try to reduce the number
* of texture bind operations
*/
GLint activeTextureID;
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
/**
* Renders this glyph at the current pen position.
*
* @param pen The current pen position.
* @return The advance distance for this glyph.
*/
virtual float Render( const FT_Vector& pen);
/**
* The texture index of the currently active texture
*
* We call glGetIntegerv( GL_TEXTURE_2D_BINDING, activeTextureID);
* to get the currently active texture to try to reduce the number
* of texture bind operations
*/
GLint activeTextureID;
private:
/**
* The width of the glyph 'image'
*/
int destWidth;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* The number of greys or bit depth of the image
*/
int numGreys;
/**
* A structure to hold the uv co-ords.
*/
struct FTPoint
{
float x;
float y;
};
/**
* The number of greys or bit depth of the image
*/
int numGreys;
/**
* A structure to hold the uv co-ords.
*/
struct FTPoint
{
float x;
float y;
};
/**
* The texture co-ords of this glyph within the texture.
*/
FTPoint uv[2];
/**
* The texture index that this glyph is contained in.
*/
int glTextureID;
/**
* The texture co-ords of this glyph within the texture.
*/
FTPoint uv[2];
/**
* The texture index that this glyph is contained in.
*/
int glTextureID;
};
#endif // __FTTextureGlyph__
#endif // __FTTextureGlyph__

View File

@@ -1,174 +1,174 @@
#include "FTVectoriser.h"
#include "FTGL.h"
#include "FTVectoriser.h"
#include "FTGL.h"
FTContour::FTContour()
: kMAXPOINTS( 1000)
{
pointList.reserve( kMAXPOINTS);
: kMAXPOINTS( 1000)
{
pointList.reserve( kMAXPOINTS);
}
FTContour::~FTContour()
{
pointList.clear();
pointList.clear();
}
void FTContour::AddPoint( const float x, const float y)
{
ftPoint point( x, y, 0.0);
// Eliminate duplicate points.
if( pointList.empty() || ( pointList[pointList.size() - 1] != point && pointList[0] != point))
{
pointList.push_back( point);
}
ftPoint point( x, y, 0.0);
// Eliminate duplicate points.
if( pointList.empty() || ( pointList[pointList.size() - 1] != point && pointList[0] != point))
{
pointList.push_back( point);
}
}
FTVectoriser::FTVectoriser( const FT_Glyph glyph)
: contour(0),
contourFlag(0),
kBSTEPSIZE( 0.2)
: contour(0),
contourFlag(0),
kBSTEPSIZE( 0.2)
{
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
ftOutline = outline->outline;
contourList.reserve( ftOutline.n_contours);
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
ftOutline = outline->outline;
contourList.reserve( ftOutline.n_contours);
}
FTVectoriser::~FTVectoriser()
{
for( int c = 0; c < contours(); ++c)
{
delete contourList[c];
}
for( int c = 0; c < contours(); ++c)
{
delete contourList[c];
}
contourList.clear();
contourList.clear();
}
int FTVectoriser::points()
{
int s = 0;
for( int c = 0; c < contours(); ++c)
{
s += contourList[c]->size();
}
return s;
int s = 0;
for( int c = 0; c < contours(); ++c)
{
s += contourList[c]->size();
}
return s;
}
bool FTVectoriser::Process()
{
short first = 0;
short last;
const short cont = ftOutline.n_contours;
for( short c = 0; c < cont; ++c)
{
contour = new FTContour;
contourFlag = ftOutline.flags;
last = ftOutline.contours[c];
short first = 0;
short last;
const short cont = ftOutline.n_contours;
for( short c = 0; c < cont; ++c)
{
contour = new FTContour;
contourFlag = ftOutline.flags;
last = ftOutline.contours[c];
for( short p = first; p <= last; ++p)
{
switch( ftOutline.tags[p])
{
case FT_Curve_Tag_Conic:
p += Conic( p, first, last);
break;
case FT_Curve_Tag_Cubic:
p += Cubic( p, first, last);
break;
case FT_Curve_Tag_On:
default:
contour->AddPoint( ftOutline.points[p].x, ftOutline.points[p].y);
}
}
contourList.push_back( contour);
first = last + 1;
}
return true;
for( short p = first; p <= last; ++p)
{
switch( ftOutline.tags[p])
{
case FT_Curve_Tag_Conic:
p += Conic( p, first, last);
break;
case FT_Curve_Tag_Cubic:
p += Cubic( p, first, last);
break;
case FT_Curve_Tag_On:
default:
contour->AddPoint( ftOutline.points[p].x, ftOutline.points[p].y);
}
}
contourList.push_back( contour);
first = last + 1;
}
return true;
}
int FTVectoriser::Conic( const int index, const int first, const int last)
{
int next = index + 1;
int prev = index - 1;
if( index == last)
next = first;
if( index == first)
prev = last;
if( ftOutline.tags[next] != FT_Curve_Tag_Conic)
{
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = ftOutline.points[next].x; ctrlPtArray[2][1] = ftOutline.points[next].y;
evaluateCurve( 2);
return 1;
}
else
{
int next2 = next + 1;
if( next == last)
next2 = first;
//create a phantom point
float x = ( ftOutline.points[index].x + ftOutline.points[next].x) / 2;
float y = ( ftOutline.points[index].y + ftOutline.points[next].y) / 2;
// process first curve
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = x; ctrlPtArray[2][1] = y;
evaluateCurve( 2);
// process second curve
ctrlPtArray[0][0] = x; ctrlPtArray[0][1] = y;
ctrlPtArray[1][0] = ftOutline.points[next].x; ctrlPtArray[1][1] = ftOutline.points[next].y;
ctrlPtArray[2][0] = ftOutline.points[next2].x; ctrlPtArray[2][1] = ftOutline.points[next2].y;
evaluateCurve( 2);
return 2;
}
int next = index + 1;
int prev = index - 1;
if( index == last)
next = first;
if( index == first)
prev = last;
if( ftOutline.tags[next] != FT_Curve_Tag_Conic)
{
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = ftOutline.points[next].x; ctrlPtArray[2][1] = ftOutline.points[next].y;
evaluateCurve( 2);
return 1;
}
else
{
int next2 = next + 1;
if( next == last)
next2 = first;
//create a phantom point
float x = ( ftOutline.points[index].x + ftOutline.points[next].x) / 2;
float y = ( ftOutline.points[index].y + ftOutline.points[next].y) / 2;
// process first curve
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = x; ctrlPtArray[2][1] = y;
evaluateCurve( 2);
// process second curve
ctrlPtArray[0][0] = x; ctrlPtArray[0][1] = y;
ctrlPtArray[1][0] = ftOutline.points[next].x; ctrlPtArray[1][1] = ftOutline.points[next].y;
ctrlPtArray[2][0] = ftOutline.points[next2].x; ctrlPtArray[2][1] = ftOutline.points[next2].y;
evaluateCurve( 2);
return 2;
}
}
int FTVectoriser::Cubic( const int index, const int first, const int last)
{
int next = index + 1;
int prev = index - 1;
if( index == last)
next = first;
int next2 = next + 1;
if( next == last)
next2 = first;
if( index == first)
prev = last;
int next = index + 1;
int prev = index - 1;
if( index == last)
next = first;
int next2 = next + 1;
if( next == last)
next2 = first;
if( index == first)
prev = last;
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = ftOutline.points[next].x; ctrlPtArray[2][1] = ftOutline.points[next].y;
ctrlPtArray[3][0] = ftOutline.points[next2].x; ctrlPtArray[3][1] = ftOutline.points[next2].y;
ctrlPtArray[0][0] = ftOutline.points[prev].x; ctrlPtArray[0][1] = ftOutline.points[prev].y;
ctrlPtArray[1][0] = ftOutline.points[index].x; ctrlPtArray[1][1] = ftOutline.points[index].y;
ctrlPtArray[2][0] = ftOutline.points[next].x; ctrlPtArray[2][1] = ftOutline.points[next].y;
ctrlPtArray[3][0] = ftOutline.points[next2].x; ctrlPtArray[3][1] = ftOutline.points[next2].y;
evaluateCurve( 3);
return 2;
evaluateCurve( 3);
return 2;
}
@@ -179,12 +179,12 @@ void FTVectoriser::deCasteljau( const float t, const int n)
for( int i = 1; i <= n; i++)
for( int k = 0; k <= (n - i); k++)
{
bValues[i][k][0] = (1 - t) * bValues[i - 1][k][0] + t * bValues[i - 1][k + 1][0];
bValues[i][k][1] = (1 - t) * bValues[i - 1][k][1] + t * bValues[i - 1][k + 1][1];
}
bValues[i][k][0] = (1 - t) * bValues[i - 1][k][0] + t * bValues[i - 1][k + 1][0];
bValues[i][k][1] = (1 - t) * bValues[i - 1][k][1] + t * bValues[i - 1][k + 1][1];
}
//Specify next vertex to be included on curve
contour->AddPoint( bValues[n][0][0], bValues[n][0][1]);
contour->AddPoint( bValues[n][0][0], bValues[n][0][1]);
}
@@ -193,16 +193,16 @@ void FTVectoriser::evaluateCurve( const int n)
{
// setting the b(0) equal to the control points
for( int i = 0; i <= n; i++)
{
bValues[0][i][0] = ctrlPtArray[i][0];
bValues[0][i][1] = ctrlPtArray[i][1];
{
bValues[0][i][0] = ctrlPtArray[i][0];
bValues[0][i][1] = ctrlPtArray[i][1];
}
float t; //parameter for curve point calc. [0.0, 1.0]
float t; //parameter for curve point calc. [0.0, 1.0]
for( int m = 0; m <= ( 1 / kBSTEPSIZE); m++)
{
t = m * kBSTEPSIZE;
t = m * kBSTEPSIZE;
deCasteljau( t, n); //calls to evaluate point on curve att.
}
}
@@ -210,19 +210,19 @@ void FTVectoriser::evaluateCurve( const int n)
void FTVectoriser::MakeOutline( double* data)
{
int i = 0;
for( int c= 0; c < contours(); ++c)
{
const FTContour* contour = contourList[c];
for( int p = 0; p < contour->size(); ++p)
{
data[i] = static_cast<double>(contour->pointList[p].x / 64.0f); // is 64 correct?
data[i + 1] = static_cast<double>(contour->pointList[p].y / 64.0f);
data[i + 2] = 0.0; // static_cast<double>(contour->pointList[p].z / 64.0f);
i += 3;
}
}
int i = 0;
for( int c= 0; c < contours(); ++c)
{
const FTContour* contour = contourList[c];
for( int p = 0; p < contour->size(); ++p)
{
data[i] = static_cast<double>(contour->pointList[p].x / 64.0f); // is 64 correct?
data[i + 1] = static_cast<double>(contour->pointList[p].y / 64.0f);
data[i + 2] = 0.0; // static_cast<double>(contour->pointList[p].z / 64.0f);
i += 3;
}
}
}

View File

@@ -1,5 +1,5 @@
#ifndef __FTVectoriser__
#define __FTVectoriser__
#ifndef __FTVectoriser__
#define __FTVectoriser__
#include "FTGL.h"
@@ -17,61 +17,61 @@ using namespace std;
* ftPoint class is a basic 3 dimensional point for holding outline font
* point data.
*
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see FTOutlineGlyph
* @see FTPolyGlyph
*
*/
class FTGL_EXPORT ftPoint
{
public:
/**
* Default constructor. Point is set to zero.
*/
ftPoint()
: x(0), y(0), z(0)
{}
/**
* Constructor.
*
* @param X
* @param Y
* @param Z
*/
ftPoint( const float X, const float Y, const float Z)
: x(X), y(Y), z(Z)
{}
/**
* Operator == Tests for eqaulity
*
* @param a
* @param b
* @return
*/
friend bool operator == ( const ftPoint &a, const ftPoint &b)
{
return((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
}
public:
/**
* Default constructor. Point is set to zero.
*/
ftPoint()
: x(0), y(0), z(0)
{}
/**
* Constructor.
*
* @param X
* @param Y
* @param Z
*/
ftPoint( const float X, const float Y, const float Z)
: x(X), y(Y), z(Z)
{}
/**
* Operator == Tests for eqaulity
*
* @param a
* @param b
* @return
*/
friend bool operator == ( const ftPoint &a, const ftPoint &b)
{
return((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
}
/**
* Operator != Tests for non equality
*
* @param a
* @param b
* @return
*/
friend bool operator != ( const ftPoint &a, const ftPoint &b)
{
return((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
}
/**
* The point data
*/
float x, y, z; // FIXME make private
private:
/**
* Operator != Tests for non equality
*
* @param a
* @param b
* @return
*/
friend bool operator != ( const ftPoint &a, const ftPoint &b)
{
return((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
}
/**
* The point data
*/
float x, y, z; // FIXME make private
private:
};
@@ -79,54 +79,54 @@ class FTGL_EXPORT ftPoint
* FTContour class is a container of points that describe an outline
* point data.
*
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see ftPoint
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see ftPoint
*
*/
class FTGL_EXPORT FTContour
{
public:
/**
* Default constructor
*/
FTContour();
public:
/**
* Default constructor
*/
FTContour();
/**
* Destructor
*/
~FTContour();
/**
* Add a point to the end of this contour.
*
* Doesn't add the point if it's already on the end or the start
* of the contour. The Z component is always 0
*
* @param x The X component of the point
* @param y The Y component of the point
*/
void AddPoint( const float x, const float y);
/**
* How many points define this contour
*
* @return the number of points in this contour
*/
int size() const { return pointList.size();}
/**
* Destructor
*/
~FTContour();
/**
* Add a point to the end of this contour.
*
* Doesn't add the point if it's already on the end or the start
* of the contour. The Z component is always 0
*
* @param x The X component of the point
* @param y The Y component of the point
*/
void AddPoint( const float x, const float y);
/**
* How many points define this contour
*
* @return the number of points in this contour
*/
int size() const { return pointList.size();}
/**
* The list of points in this contour
*/
vector< ftPoint> pointList;
private:
/**
* A 'max' number of points that this contour holds. Note however it
* can hold more than this number. It is just used to reserve space
* in the <vector>
*/
const unsigned int kMAXPOINTS;
/**
* The list of points in this contour
*/
vector< ftPoint> pointList;
private:
/**
* A 'max' number of points that this contour holds. Note however it
* can hold more than this number. It is just used to reserve space
* in the <vector>
*/
const unsigned int kMAXPOINTS;
};
@@ -134,136 +134,136 @@ class FTGL_EXPORT FTContour
* FTVectoriser class is a helper class that converts font outlines into
* point data. It includes a bezier curve evaluator
*
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see FTContour
* @see ftPoint
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see FTContour
* @see ftPoint
*
*/
class FTGL_EXPORT FTVectoriser
{
public:
/**
* Constructor
*
* @param glyph The freetype glyph to be processed
*/
FTVectoriser( FT_Glyph glyph);
public:
/**
* Constructor
*
* @param glyph The freetype glyph to be processed
*/
FTVectoriser( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTVectoriser();
/**
* Destructor
*/
virtual ~FTVectoriser();
/**
* Process the freetype outline data into contours of points
*
* @return <code>true</code> on success
*/
bool Process();
/**
* Process the freetype outline data into contours of points
*
* @return <code>true</code> on success
*/
bool Process();
/**
* Copy the outline data into a block of <code>doubles</code>
* @param d
*/
void MakeOutline( double* d);
/**
* Copy the outline data into a block of <code>doubles</code>
* @param d
*/
void MakeOutline( double* d);
/**
* Get the total count of points in this outline
*
* @return the number of points
*/
int points();
/**
* Get the total count of points in this outline
*
* @return the number of points
*/
int points();
/**
* Get the count of contours in this outline
*
* @return the number of contours
*/
int contours() const { return contourList.size();}
/**
* Get the count of contours in this outline
*
* @return the number of contours
*/
int contours() const { return contourList.size();}
/**
* Get the nuber of points in a contour in this outline
*
* @param c The contour index
* @return the number of points in contour[c]
*/
int contourSize( int c) const { return contourList[c]->size();}
/**
* Get the nuber of points in a contour in this outline
*
* @param c The contour index
* @return the number of points in contour[c]
*/
int contourSize( int c) const { return contourList[c]->size();}
/**
* Get the flag for the tesselation rule for this outline
*
* @return The contour flag
*/
int ContourFlag() const { return contourFlag;}
private:
/**
* Process a conic ( second order bezier curve)
*
* @param index The index of the current point in the point list.
* @param first The index into the pointlist of the first point in
* the contour that the current point is part of.
* @param last The index into the pointlist of the last point in
* the contour that the current point is part of.
* @return the number of control points processed
*/
int Conic( const int index, const int first, const int last);
/**
* Get the flag for the tesselation rule for this outline
*
* @return The contour flag
*/
int ContourFlag() const { return contourFlag;}
private:
/**
* Process a conic ( second order bezier curve)
*
* @param index The index of the current point in the point list.
* @param first The index into the pointlist of the first point in
* the contour that the current point is part of.
* @param last The index into the pointlist of the last point in
* the contour that the current point is part of.
* @return the number of control points processed
*/
int Conic( const int index, const int first, const int last);
/**
* Process a cubic ( third order) bezier curve
*
* @param index The index of the current point in the point list.
* @param first The index into the pointlist of the first point in
* the contour that the current point is part of.
* @param last The index into the pointlist of the last point in
* the contour that the current point is part of.
* @return the number of control points processed
*/
int Cubic( const int index, const int first, const int last);
/**
* Process a cubic ( third order) bezier curve
*
* @param index The index of the current point in the point list.
* @param first The index into the pointlist of the first point in
* the contour that the current point is part of.
* @param last The index into the pointlist of the last point in
* the contour that the current point is part of.
* @return the number of control points processed
*/
int Cubic( const int index, const int first, const int last);
/**
* @param a
* @param b
*/
void deCasteljau( const float t, const int n);
/**
* @param a
* @param b
*/
void deCasteljau( const float t, const int n);
/**
* @param a
*/
void evaluateCurve( const int n);
/**
* @param a
*/
void evaluateCurve( const int n);
/**
* The list of contours in this outline
*/
vector< const FTContour*> contourList;
/**
* A temporary FTContour
*/
FTContour* contour;
/**
* The list of contours in this outline
*/
vector< const FTContour*> contourList;
/**
* A temporary FTContour
*/
FTContour* contour;
/**
* A flag indicating the tesselation rule for this outline
*/
int contourFlag;
/**
* A flag indicating the tesselation rule for this outline
*/
int contourFlag;
/**
* A Freetype outline
*/
FT_Outline ftOutline;
/**
*/
// Magic numbers -- #define MAX_DEG 4
float bValues[4][4][2]; //3D array storing values of de Casteljau algorithm.
float ctrlPtArray[4][2]; // Magic numbers
/**
*/
const float kBSTEPSIZE;
/**
* A Freetype outline
*/
FT_Outline ftOutline;
/**
*/
// Magic numbers -- #define MAX_DEG 4
float bValues[4][4][2]; //3D array storing values of de Casteljau algorithm.
float ctrlPtArray[4][2]; // Magic numbers
/**
*/
const float kBSTEPSIZE;
};
#endif // __FTVectoriser__
#endif // __FTVectoriser__

View File

@@ -110,21 +110,28 @@ open(const std::string& font)
return false;
}
bool Font::
open(const char* font)
{ return open(std::string(font)); }
bool Font::
create(int pointSize,const unsigned int res)
create(osg::State& state,int pointSize,const unsigned int res)
{
_pointSize=pointSize;
_res=res;
return create();
return create(state);
}
bool Font::
create()
create(osg::State& state)
{
if(_init)
{
if(_font->FaceSize(_pointSize,_res))
if(_font->Created(state.getContextID()))
return true;
if(_font->FaceSize(_pointSize,_res,state.getContextID()))
{
_created=true;
return true;
@@ -137,12 +144,12 @@ create()
}
void Font::
output(const char* text)
output(osg::State& state,const char* text)
{
if(_created)
_font->render(text);
_font->render(text,state.getContextID());
else
create(_pointSize);
create(state,_pointSize);
}
void Font::
@@ -328,6 +335,19 @@ VectorFont(font)
_precision=precision;
}
PolygonFont::
PolygonFont(const char* font,
int point_size,
double precision):
VectorFont(std::string(font))
{
if(init(font))
{
}
_pointSize=point_size;
_precision=precision;
}
FTFont* PolygonFont::
createFontObj(void)
{

View File

@@ -1,6 +1,6 @@
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
@@ -160,7 +160,7 @@ void Text::drawImmediateMode(State& state)
if(!_font->isCreated())
{
_font->create();
_font->create(state);
dirtyBound();
}
@@ -183,23 +183,23 @@ void Text::drawImmediateMode(State& state)
{
case POLYGON:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(_text.c_str());
_font->output(state,_text.c_str());
break;
case OUTLINE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(_text.c_str());
_font->output(state,_text.c_str());
break;
case BITMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(_text.c_str());
_font->output(state,_text.c_str());
break;
case PIXMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(_text.c_str());
_font->output(state,_text.c_str());
break;
case TEXTURE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(_text.c_str());
_font->output(state,_text.c_str());
break;
};