First cut of new osgText implementation.

This commit is contained in:
Robert Osfield 2003-03-02 21:05:05 +00:00
parent a826f5ee31
commit fbe674b321
71 changed files with 1933 additions and 7226 deletions

View File

@ -33,10 +33,11 @@ PLUGIN_DIRS = \
lib3ds\
directx\
flt\
geo\
freetype\
iv\
obj\
lwo\
geo\
txp\
dw\
bmp\
@ -45,7 +46,7 @@ PLUGIN_DIRS = \
logos\
osgtgz\
tgz\
zip
zip
# comment in if you have Performer installed.
# PLUGIN_DIRS += pfb
@ -100,6 +101,7 @@ DEMOS_DIRS = \
osggeometry\
osghangglide\
osghud\
osgtext\
osgimpostor\
osglight\
osglightpoint\
@ -115,7 +117,6 @@ DEMOS_DIRS = \
osgshape\
osgstereoimage\
osgteapot\
osgtext\
osgtexture1D\
osgtexture2D\
osgtexture3D\
@ -124,4 +125,3 @@ DEMOS_DIRS = \
osgvertexprogram\
osgviews\
sgv

View File

@ -93,90 +93,14 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\..\src\osgText\DefaultFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\Font.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTBitmapGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTCharmap.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTFace.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLBitmapFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLOutlineFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLPixmapFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLPolygonFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLTextureFont.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGlyphContainer.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTLibrary.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTOutlineGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTPixmapGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTPolyGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTSize.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTTextureGlyph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTVectoriser.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\EncodedText.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\Paragraph.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\Text.cpp
# End Source File
# Begin Source File
@ -197,90 +121,6 @@ SOURCE=..\..\include\osgText\Font
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTBitmapGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTCharmap.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTFace.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGL.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLBitmapFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLOutlineFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLPixmapFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLPolygonFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGLTextureFont.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTGlyphContainer.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTLibrary.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTOutlineGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTPixmapGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTPolyGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTSize.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTTextureGlyph.h
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\FTVectoriser.h
# End Source File
# Begin Source File
SOURCE=..\..\include\osgText\EncodedText
# End Source File
# Begin Source File
SOURCE=..\..\include\osgText\Paragraph
# End Source File
# Begin Source File
SOURCE=..\..\include\osgText\Text
# End Source File
# Begin Source File

View File

@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs
CXXFILES =\
osgtext.cpp\
LIBS += -losgText -losgProducer -lProducer $(OSG_LIBS) -L/usr/local/lib $(FREETYPE_LIB) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
LIBS += -osgText -losgProducer -lProducer $(OSG_LIBS) -L/usr/local/lib $(FREETYPE_LIB) $(GLUT_LIB) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
EXEC = osgtext

View File

@ -21,218 +21,109 @@
#include <osg/Depth>
#include <osg/Projection>
#include <osg/MatrixTransform>
#include <osgText/Text>
///////////////////////////////////////////////////////////////////////////////
// globals
#define TEXT_POLYGON "Polygon Font - jygq"
#define TEXT_OUTLINE "Outline Font - jygq"
#define TEXT_TEXTURE "Texture Font - jygq"
#define TEXT_BITMAP "Bitmap Font - jygq"
#define TEXT_PIXMAP "Pixmap Font - jygq"
#define TEXT_COL_2D osg::Vec4(.9,.9,.9,1)
#define TEXT_COL_3D osg::Vec4(.99,.3,.2,1)
std::string ttfPath("fonts/times.ttf");
std::string ttfPath1("fonts/arial.ttf");
int gFontSize=18;
int gFontSize1=24;
std::vector<osg::ref_ptr<osgText::Text > > gTextList;
osgText::Text::AlignmentType gAlignment=osgText::Text::LEFT_BOTTOM;
osg::Group* createText()
osg::Group* createHUDText()
{
osg::Geode* geode = new osg::Geode;
osgText::Text* text1 = new osgText::Text;
text1->setCharacterSize(12.0f);
text1->setText("20 GOTO 10");
geode->addDrawable(text1);
osgText::Text* text2 = new osgText::Text;
text2->setPosition(osg::Vec3(0.0f,50.0f,0.0f));
text2->setCharacterSize(12.0f);
text2->setText("10 PRINT \"Hello World\"");
geode->addDrawable(text2);
osgText::Text* text3 = new osgText::Text;
text3->setFont(osgText::readFontFile("fonts/arial.ttf"));
text3->setPosition(osg::Vec3(100.0f,100.0f,0.0f));
text3->setText("This is a test of text AVAV/.|¬!£$%^&*() - fonts/arial.ttf");
geode->addDrawable(text3);
osgText::Text* text4 = new osgText::Text;
text4->setFont(osgText::readFontFile("fonts/times.ttf"));
text4->setFontSize(64,64);
text4->setPosition(osg::Vec3(200.0f,200.0f,0.0f));
text4->setLayout(osgText::Text::RIGHT_TO_LEFT);
text4->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX);
text4->setText("This is a test of text AVAV/.|¬!£$%^&*() - fonts/times.ttf");
geode->addDrawable(text4);
osgText::Text* text5 = new osgText::Text;
text5->setFont(osgText::readFontFile("fonts/dirtydoz.ttf"));
text5->setPosition(osg::Vec3(300.0f,300.0f,0.0f));
text5->setColor(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
text5->setLayout(osgText::Text::VERTICAL);
text5->setDrawMode(osgText::Text::TEXT|osgText::Text::ALIGNMENT|osgText::Text::BOUNDINGBOX);
text5->setText("This is a test of text AVAV/.|¬!£$%^&*() - fonts/dirtydoz.ttf");
geode->addDrawable(text5);
// osgText::Text::TextString string;
// for(int i=0;i<2048;++i)
// string.push_back(i);
//
// osgText::Text* text6 = new osgText::Text;
// text6->setFont(osgText::readFontFile("/home/robert/Documents/GuopingSun/msmincho.ttc"));
// text6->setFontSize(64,64);
// text6->setText(string);
// text6->setPosition(osg::Vec3(00.0f,400.0f,0.0f));
// geode->addDrawable(text6);
osg::Group* rootNode = new osg::Group;
osgText::Text* text;
osg::Geode* geode;
osg::Material* textMaterial;
osg::StateSet* textState;
double xOffset=150;
double yOffset=gFontSize+10;
///////////////////////////////////////////////////////////////////////////
// setup the texts
///////////////////////////////////////////////////////////////////////////
// BitmapFont
osgText::BitmapFont* bitmapFont= new osgText::BitmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(bitmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_BITMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("BitmapFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PixmapFont
osgText::PixmapFont* pixmapFont= new osgText::PixmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(pixmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_PIXMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("PixmapFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_2D);
// to get antiaA pixmapFonts we have to draw them with blending
osg::BlendFunc *transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setMode(GL_BLEND,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// TextureFont
osgText::TextureFont* textureFont= new osgText::TextureFont(ttfPath1,
gFontSize1);
text= new osgText::Text(textureFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_TEXTURE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("TextureFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
// to get antiaA pixmapFonts we have to draw them with blending
transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PolygonFont
osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(polygonFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string("TEXT_POLYGON"));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("PolygonFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// OutlineFont
osgText::OutlineFont* outlineFont= new osgText::OutlineFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(outlineFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_OUTLINE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("OutlineFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
rootNode->addChild(geode);
// now add a depth attribute to the scene to force it to draw on top.
osg::Depth* depth = new osg::Depth;
depth->setRange(0.0,0.0);
osg::StateSet* rootState = new osg::StateSet();
rootState->setAttribute(depth);
rootState->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
rootNode->setStateSet(rootState);
return rootNode;
}
osg::Group* create3DText()
{
osg::Geode* geode = new osg::Geode;
osgText::Text* text1 = new osgText::Text;
text1->setFont("fonts/times.ttf");
text1->setAxisAlignment(osgText::Text::XY_PLANE);
text1->setText("XY_PLANE");
geode->addDrawable(text1);
osgText::Text* text2 = new osgText::Text;
text2->setFont("fonts/times.ttf");
text2->setPosition(osg::Vec3(0.0f,0.0f,0.0f));
text2->setAxisAlignment(osgText::Text::YZ_PLANE);
text2->setText("YZ_PLANE");
geode->addDrawable(text2);
osgText::Text* text3 = new osgText::Text;
text3->setFont("fonts/times.ttf");
text3->setPosition(osg::Vec3(00.0f,00.0f,00.0f));
text3->setAxisAlignment(osgText::Text::XZ_PLANE);
text3->setText("XZ_PLANE");
geode->addDrawable(text3);
osgText::Text* text4 = new osgText::Text;
text4->setFont("fonts/times.ttf");
text4->setAxisAlignment(osgText::Text::SCREEN);
text4->setPosition(osg::Vec3(00.0f,00.0f,00.0f));
text4->setText("SCREEN");
geode->addDrawable(text4);
osg::Group* rootNode = new osg::Group;
rootNode->addChild(geode);
return rootNode;
}
int main( int argc, char **argv )
{
@ -296,19 +187,26 @@ int main( int argc, char **argv )
rootNode = group;
}
// create the hud.
osg::Projection* projection = new osg::Projection;
projection->setMatrix(osg::Matrix::ortho2D(0,1024,0,768));
{
// create the hud.
osg::Projection* projection = new osg::Projection;
projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
modelview_abs->setMatrix(osg::Matrix::identity());
osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
modelview_abs->setReferenceFrame(osg::Transform::RELATIVE_TO_ABSOLUTE);
modelview_abs->setMatrix(osg::Matrix::identity());
modelview_abs->addChild(createText());
modelview_abs->addChild(createHUDText());
projection->addChild(modelview_abs);
projection->addChild(modelview_abs);
group->addChild(projection);
group->addChild(projection);
}
osg::MatrixTransform* scale = new osg::MatrixTransform;
scale->setMatrix(osg::Matrix::scale(1.0f,1.0f,1.0f));
scale->addChild(create3DText());
group->addChild(scale);
}

View File

@ -59,7 +59,10 @@ class SG_EXPORT Texture2D : public Texture
_textureHeight = height;
}
/** Get the texture subload width. */
int getTextureWidth() const { return _textureWidth; }
int getTextureHeight() const { return _textureHeight; }
// deprecated.
inline void getTextureSize(int& width, int& height) const
{
width = _textureWidth;

View File

@ -63,6 +63,47 @@ class buffered_value
std::vector<T> _array;
};
template<class T>
class buffered_object
{
public:
inline buffered_object():
_array(DisplaySettings::instance()->getMaxNumberOfGraphicsContexts())
{}
buffered_object& operator = (const buffered_object& rhs)
{
_array = rhs._array;
return *this;
}
inline void clear() { _array.clear(); }
inline bool empty() const { return _array.empty(); }
inline unsigned int size() const { return _array.size(); }
inline T& operator[] (unsigned int pos)
{
// automatically resize array.
if (_array.size()<=pos)
_array.resize(pos+1);
return _array[pos];
}
/* // do we implement the const version???
inline T operator[] (unsigned int pos) const
{
return 0;
}
*/
protected:
std::vector<T> _array;
};
}
#endif

View File

@ -1,91 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* --------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
#ifndef OSGTEXT_ENCODEDTEXT
#define OSGTEXT_ENCODEDTEXT 1
#include <osg/Referenced>
#include <osgText/Export>
#include <vector>
#include <string>
namespace osgText {
class OSGTEXT_EXPORT EncodedText : public osg::Referenced
{
public:
/**
* Types of string encodings supported
*/
enum Encoding
{
ENCODING_UNDEFINED, /// not using Unicode
ENCODING_ASCII = ENCODING_UNDEFINED,/// unsigned char ASCII
ENCODING_UTF8, /// 8-bit unicode transformation format
ENCODING_UTF16, /// 16-bit signature
ENCODING_UTF16_BE, /// 16-bit big-endian
ENCODING_UTF16_LE, /// 16-bit little-endian
ENCODING_UTF32, /// 32-bit signature
ENCODING_UTF32_BE, /// 32-bit big-endian
ENCODING_UTF32_LE, /// 32-bit little-endian
ENCODING_SIGNATURE, /// detect encoding from signature
};
EncodedText();
void setOverrideEncoding(Encoding encoding);
Encoding getOverrideEncoding() const { return _overrideEncoding; }
Encoding getEncoding() const { return _encoding; }
std::vector<int>::const_iterator begin() const { return _unicodeText.begin(); }
std::vector<int>::const_iterator end() const { return _unicodeText.end(); }
protected:
friend class Text;
std::string convertWideString(const wchar_t* text);
void setText(const unsigned char* text, int length = -1);
int getNextCharacter(const unsigned char*& charString) const;
/// This method will extract any ZWNBSP signature at the start of the string
Encoding findEncoding(const unsigned char*& charString) const;
Encoding _encoding;
Encoding _overrideEncoding;
std::vector<int> _unicodeText;
};
}
#endif // OSGTEXT_TEXT

View File

@ -10,9 +10,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSGTEXT_EXPORT_
#define OSGTEXT_EXPORT_ 1

View File

@ -10,269 +10,188 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* --------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
#ifndef OSGTEXT_FONT
#define OSGTEXT_FONT 1
#define OSGTEXT_FONT 1
#include <osg/Object>
#include <osg/State>
#include <osg/Vec2>
#include <osg/Image>
#include <osg/Texture2D>
#include <osg/StateSet>
#include <osg/buffered_value>
#include <osgText/Export>
#include <osgText/EncodedText>
#include <string>
// http://homepages.paradise.net.nz/henryj/code/
class FTFont;
namespace osgText {
/** META_Font macro define the standard clone, isSameKindAs,
* className and getType methods.
* Use when subclassing from Object to make it more convinient to define
* the standard pure virtual methods which are required for all Object
* subclasses.*/
#define META_Font(library,name) \
virtual osg::Object* cloneType() const { return new name(); } \
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
virtual const char* libraryName() const { return #library; } \
virtual const char* className() const { return #name; } \
class Font;
/** read a font from specified file.*/
extern OSGTEXT_EXPORT Font* readFontFile(const std::string& filename);
/** Pure virtual base class for fonts.
* Concrete implementation are the DefaultFont found in src/osgText/DefaultFont.cpp
* and FreeTypeFont found in src/osgPlugins/freetype/FreeTypeFont.cpp*/
class OSGTEXT_EXPORT Font : public osg::Object
{
public:
Font();
Font(const Font& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
osg::Object(font,copyop),
_init(false),
_created(false),
_font(0L),
_fontName(font._fontName),
_pointSize(font._pointSize),
_res(font._res),
_textureSize(font._textureSize)
{}
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Font *>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgText"; }
virtual const char* className() const { return "Font"; }
bool open(const char* font);
bool open(const std::string& font);
virtual bool create(osg::State& state,int pointSize, unsigned int res = 72 );
virtual bool create(osg::State& state);
virtual void output(osg::State& state, const EncodedText* text) const;
virtual bool isOk(void) const { return _init; }
virtual bool isCreated(void) const { return isOk() && _created; }
virtual float getWidth(const EncodedText* text) const;
virtual int getHeight() const;
virtual int getDescender() const;
virtual int getAscender() const;
int getPointSize(void) const { return _pointSize; }
int getTextureSize(void) const { return _textureSize; }
const std::string& getFontName() const { return _fontName; }
/// Transfer font settings to another Font object and invalidate this one.
void copyAndInvalidate(Font &dest);
FTFont* getFont(void) { return _font; }
protected:
virtual ~Font();
virtual void clear();
virtual FTFont* createFontObj(void)=0;
bool init(const std::string& font);
bool _init;
bool _created;
FTFont* _font;
std::string _fontName;
int _pointSize;
int _res;
int _textureSize;
};
class OSGTEXT_EXPORT RasterFont:public Font
{
public:
RasterFont():Font(){}
RasterFont(const RasterFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
Font(font,copyop) {}
RasterFont(const std::string& /*font*/):Font() {}
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RasterFont *>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgText"; }
virtual const char* className() const { return "RasterFont"; }
protected:
};
class OSGTEXT_EXPORT VectorFont:public Font
{
public:
VectorFont():Font(),_precision(0.0) {}
VectorFont(const VectorFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
Font(font,copyop),
_precision(font._precision) {}
VectorFont(const std::string& /*font*/):Font(){}
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const VectorFont *>(obj)!=NULL; }
virtual const char* libraryName() const { return "osgText"; }
virtual const char* className() const { return "VectorFont"; }
protected:
double _precision;
};
class OSGTEXT_EXPORT BitmapFont:public RasterFont
{
public:
BitmapFont() {}
BitmapFont(const BitmapFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
RasterFont(font,copyop) {}
BitmapFont(const std::string& font,
int point_size);
META_Font(osgText,BitmapFont);
protected:
virtual FTFont* createFontObj(void);
};
class OSGTEXT_EXPORT PixmapFont:public RasterFont
{
public:
PixmapFont() {}
PixmapFont(const PixmapFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
RasterFont(font,copyop) {}
PixmapFont(const std::string& font,
int point_size);
META_Font(osgText,PixmapFont);
protected:
virtual FTFont* createFontObj(void);
};
class OSGTEXT_EXPORT TextureFont:public RasterFont
{
public:
TextureFont() {}
TextureFont(const TextureFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
RasterFont(font,copyop) {}
TextureFont(const std::string& font,
int point_size);
TextureFont(const std::string& font,
int point_size,
int textureSize );
META_Font(osgText,TextureFont);
protected:
virtual FTFont* createFontObj(void);
};
class OSGTEXT_EXPORT OutlineFont:public VectorFont
{
public:
OutlineFont() {}
OutlineFont(const OutlineFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
VectorFont(font,copyop) {}
OutlineFont(const std::string& font,
int point_size,
double precision);
META_Font(osgText,OutlineFont);
protected:
virtual FTFont* createFontObj(void);
};
class OSGTEXT_EXPORT PolygonFont:public VectorFont
{
// declare the interface to a font.
public:
PolygonFont() {}
PolygonFont(const PolygonFont& font,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
VectorFont(font,copyop) {}
// forward declare nested classes.
class Glyph;
class GlyphTexture;
Font();
virtual osg::Object* cloneType() const { return 0; } // cloneType() not appropriate
virtual osg::Object* clone(const osg::CopyOp&) const { return 0; } // clone() not appropriate
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Font*>(obj)!=NULL; }
virtual const char* className() const { return "Font"; }
virtual const char* libraryName() const { return "osgText"; }
virtual std::string getFileName() const = 0;
/** Set the pixel width and height */
virtual void setSize(unsigned int width, unsigned int height) = 0;
PolygonFont(const std::string& font,
int point_size,
double precision);
unsigned int getWidth() { return _width; }
unsigned int getHeight() { return _height; }
virtual Glyph* getGlyph(unsigned int charcode) = 0;
PolygonFont(const char* font,
int point_size,
double precision);
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode) = 0;
META_Font(osgText,PolygonFont);
virtual bool hasVertical() const = 0;
protected:
virtual FTFont* createFontObj(void);
virtual ~Font();
void addGlyph(unsigned int charcode, Glyph* glyph);
typedef std::vector< osg::ref_ptr<GlyphTexture> > GlyphTextureList;
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap;
GlyphMap _glyphMap;
GlyphTextureList _glyphTextureList;
StateSetList _stateSetList;
// current active size of font
unsigned int _width;
unsigned int _height;
// declare the nested classes.
public:
class OSGTEXT_EXPORT GlyphTexture : public osg::Texture2D
{
public:
GlyphTexture();
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset; }
const osg::StateSet* getStateSet() const { return _stateset; }
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
void addGlyph(Glyph* glyph,int posX, int posY);
virtual void apply(osg::State& state) const;
protected:
virtual ~GlyphTexture();
osg::StateSet* _stateset;
// parameter used to compute the size and position of empty space
// in the texture which could accomodate new glyphs.
int _usedY;
int _partUsedX;
int _partUsedY;
typedef std::vector<Glyph*> GlyphList;
typedef osg::buffered_object<GlyphList> GlyphBuffer;
GlyphList _glyphs;
mutable GlyphBuffer _glyphsToSubload;
};
class OSGTEXT_EXPORT Glyph : public osg::Image
{
public:
Glyph();
virtual ~Glyph();
unsigned int getGlyphCode() const { return _glyphCode; }
void setFont(Font* font) { _font = font; }
Font* getFont() const { return _font; }
void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
const osg::Vec2& getHorizontalBearing() const { return _horizontalBearing; }
void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
float getHorizontalAdvance() const { return _horizontalAdvance; }
void setVerticalBearing(const osg::Vec2& bearing) { _verticalBearing=bearing; }
const osg::Vec2& getVerticalBearing() const { return _verticalBearing; }
void setVerticalAdvance(float advance) { _verticalAdvance=advance; }
float getVerticalAdvance() const { return _verticalAdvance; }
void setTexture(GlyphTexture* texture) { _texture = texture; }
GlyphTexture* getTexture() { return _texture.get(); }
const GlyphTexture* getTexture() const { return _texture.get(); }
osg::StateSet* getStateSet() { return _texture.valid()?_texture->getStateSet():0; }
const osg::StateSet* getStateSet() const { return _texture.valid()?_texture->getStateSet():0; }
void setTexturePosition(int posX,int posY) { _texturePosX = posX; _texturePosY = posY; }
int getTexturePositionX() const { return _texturePosX; }
int getTexturePositionY() const { return _texturePosY; }
void setMinTexCoord(const osg::Vec2& coord) { _minTexCoord=coord; }
const osg::Vec2& getMinTexCoord() const { return _minTexCoord; }
void setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; }
const osg::Vec2& getMaxTexCoord() const { return _maxTexCoord; }
void subload();
protected:
Font* _font;
unsigned int _glyphCode;
osg::Vec2 _horizontalBearing;
float _horizontalAdvance;
osg::Vec2 _verticalBearing;
float _verticalAdvance;
osg::ref_ptr<GlyphTexture> _texture;
int _texturePosX;
int _texturePosY;
osg::Vec2 _minTexCoord;
osg::Vec2 _maxTexCoord;
};
};
}
#endif // OSGTEXT_FONT
#endif

View File

@ -1,74 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSGTEXT_PARAGRAPH
#define OSGTEXT_PARAGRAPH
#include <osg/Geode>
#include <osgText/Text>
namespace osgText {
class OSGTEXT_EXPORT Paragraph : public osg::Geode
{
public:
Paragraph();
Paragraph(const Paragraph& paragraph,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
Paragraph(const osg::Vec3& position,const std::string& text,osgText::Font* font);
META_Node(osgText,Paragraph);
void setFont(osgText::Font* font);
osgText::Font* getFont() { return _font.get(); }
const osgText::Font* getFont() const { return _font.get(); }
void setMaximumNoCharactersPerLine(unsigned int maxCharsPerLine);
unsigned int getMaximumNoCharactersPerLine() const { return _maxCharsPerLine; }
void setText(const std::string& text);
std::string& getText() { return _text; }
const std::string& getText() const { return _text; }
void setPosition(const osg::Vec3& position);
const osg::Vec3& getPosition() const { return _position; }
void setAlignment(int alignment);
int getAlignment() const { return _alignment; }
float getHeight() const;
static bool createFormatedText(unsigned int noCharsPerLine,const std::string& str,std::vector<std::string>& formatedText);
protected:
virtual ~Paragraph() {}
void createDrawables();
osg::Vec3 _position;
std::string _text;
osg::ref_ptr<osgText::Font> _font;
int _alignment;
unsigned int _maxCharsPerLine;
};
}
#endif

View File

@ -10,173 +10,203 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* --------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
#ifndef OSGTEXT_TEXT
#define OSGTEXT_TEXT 1
#define OSGTEXT_TEXT 1
#include <osg/Drawable>
#include <osg/GL>
#include <osg/Vec3>
#include <osg/Vec2>
#include <osg/Quat>
#include <osgText/Font>
#include <string>
namespace osgText {
class OSGTEXT_EXPORT Text : public osg::Drawable
{
public:
public:
enum AlignmentType
{ // from left to right, top to bottom
LEFT_TOP,
LEFT_CENTER,
LEFT_BOTTOM,
Text();
Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
CENTER_TOP,
CENTER_CENTER,
CENTER_BOTTOM,
RIGHT_TOP,
RIGHT_CENTER,
RIGHT_BOTTOM,
};
enum BoundingBoxType
{
GEOMETRY,
GLYPH,
};
enum DrawModeType
{ // from left to right, top to bottom
TEXT = 1<<0,
BOUNDINGBOX = 1<<1,
ALIGNMENT = 1<<2,
DEFAULT = TEXT,
};
enum AxisAlignment
{
XY_PLANE,
XZ_PLANE,
YZ_PLANE
};
Text();
Text(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
Text(Font* font);
virtual osg::Object* cloneType() const { return new Text(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
virtual const char* className() const { return "Text"; }
virtual const char* libraryName() const { return "osgText"; }
void setPosition(const osg::Vec2& pos);
void setPosition(const osg::Vec3& pos);
const osg::Vec3& getPosition() const { return _pos; }
virtual osg::Object* cloneType() const { return new Text(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new Text(*this,copyop); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Text*>(obj)!=NULL; }
virtual const char* className() const { return "Text"; }
virtual const char* libraryName() const { return "osgText"; }
void setColor(const osg::Vec4& color) { _color = color; }
osg::Vec4& getColor() { return _color; }
const osg::Vec4& getColor() const { return _color; }
/** Set the Font to use to render the text.
* setFont(0) sets the use of the default font.*/
void setFont(Font* font=0);
/** Set the font, loaded from the specified front file, to use to render the text,
* setFont("") sets the use of the default font.*/
void setFont(const std::string& fontfile);
/** Get the font. Return 0 if default is being used.*/
const Font* getFont() const { return _font.get(); }
/** Set the Font reference width and height resolution in texels.
* Note, the size may not be supported by current font,
* the closest supported font size will be selected.*/
void setFontSize(unsigned int width, unsigned int height);
unsigned int getFontWidth() const { return _fontWidth; }
unsigned int getFontHeight() const { return _fontWidth; }
/** TextString is a general purpose vector of char codes (unsigned int's)
* which is used internally by Text to represent strings.*/
typedef std::vector<unsigned int> TextString;
/** Set the text using a TextString.*/
void setText(const TextString& text);
/** Set the text using a std::string,
* which is converted to an internal TextString.*/
void setText(const std::string& text);
/** Set the text using a wchar_t string,
* which is converted to an internal TextString.*/
void setText(const wchar_t* text);
/** Get the const text string.*/
const TextString& getText() const { return _text; }
void setDrawMode(int mode) { _drawMode=mode; }
int getDrawMode() const { return _drawMode; }
/** Set the rendered character size in object coordinates.*/
void setCharacterSize(float height,float ascpectRatio=1.0f);
float getCharacterHeight() const { return _characterHeight; }
float getCharacterAspectRatio() const { return _characterAspectRatio; }
void setBoundingBox(int mode);
int getBoundingBox() const { return _boundingBoxType; }
void setAlignment(int alignment);
int getAlignment() const { return _alignment; }
void setAxisAlignment(AxisAlignment axis) { _axisAlignment = axis; dirtyDisplayList(); }
AxisAlignment getAxisAlignment() const { return _axisAlignment; }
/** Set the position of text.*/
void setPosition(const osg::Vec3& pos);
/** Get the position of text.*/
const osg::Vec3& getPosition() const { return _position; }
void setFont(Font* font);
Font* getFont() { return _font.get(); }
const Font* getFont() const { return _font.get(); }
enum AlignmentType
{
LEFT_TOP,
LEFT_CENTER,
LEFT_BOTTOM,
void setText(const char* text);
void setText(const std::string& text);
const std::string& getText() const { return _text; }
void setText(const wchar_t* text);
CENTER_TOP,
CENTER_CENTER,
CENTER_BOTTOM,
virtual bool supports(PrimitiveFunctor& pf) const;
virtual void accept(PrimitiveFunctor& pf) const;
RIGHT_TOP,
RIGHT_CENTER,
RIGHT_BOTTOM,
BASE_LINE /// default.
};
void setAlignment(AlignmentType alignment);
virtual void drawImplementation(osg::State& state) const;
virtual void drawBoundingBox(void) const;
virtual void drawAlignment(void) const;
AlignmentType getAlignment() const { return _alignment; }
const osg::Vec3& getAlignmentPos() const { return _alignmentPos; };
void setEncodedText(EncodedText* encodedText) { _encodedText = encodedText; }
const EncodedText* getEncodedText() const { return _encodedText.get(); }
enum AxisAlignment
{
XY_PLANE,
XZ_PLANE,
YZ_PLANE,
SCREEN
};
/// override the compile to set up the alignment etc.
virtual void compile(osg::State& state) const;
void setAxisAlignment(AxisAlignment axis);
AxisAlignment getAxisAlignment() const { return _axisAlignment; }
protected:
enum FontType
{
UNDEF,
BITMAP,
PIXMAP,
OUTLINE,
POLYGON,
TEXTURE,
};
void setRotation(const osg::Quat& quat);
const osg::Quat& getRotation() const { return _rotation; }
virtual ~Text();
virtual void setDefaults(void);
virtual bool computeBound(void) const;
virtual void calcBounds(osg::Vec3* min,osg::Vec3* max) const;
void initAlignment(osg::Vec3* min,osg::Vec3* max);
bool initAlignment(void);
enum Layout
{
LEFT_TO_RIGHT, /// default
RIGHT_TO_LEFT,
VERTICAL
};
void setLayout(Layout layout);
Layout getLayout() const { return _layout; }
osg::ref_ptr<Font> _font;
bool _init;
bool _initAlignment;
std::string _text;
int _fontType;
int _alignment;
int _drawMode;
int _boundingBoxType;
AxisAlignment _axisAlignment;
void setColor(const osg::Vec4& color);
const osg::Vec4& getColor() const { return _color; }
enum DrawModeMask
{
TEXT = 1, /// default
BOUNDINGBOX = 2,
ALIGNMENT = 4
};
void setDrawMode(unsigned int mode) { _drawMode=mode; }
unsigned int getDrawMode() const { return _drawMode; }
/** Draw the text.*/
virtual void drawImplementation(osg::State& state) const;
protected:
virtual ~Text();
virtual bool computeBound() const;
Font* getActiveFont();
const Font* getActiveFont() const;
// members which have public access.
osg::ref_ptr<Font> _font;
unsigned int _fontWidth;
unsigned int _fontHeight;
float _characterHeight;
float _characterAspectRatio;
TextString _text;
osg::Vec3 _position;
AlignmentType _alignment;
AxisAlignment _axisAlignment;
osg::Quat _rotation;
Layout _layout;
osg::Vec4 _color;
unsigned int _drawMode;
// internal structures, variable and methods used for rendering of characters.
struct GlyphQuads
{
typedef std::vector<osg::Vec2> Coords;
typedef std::vector<osg::Vec2> TexCoords;
Coords _coords;
TexCoords _texcoords;
};
typedef std::map<osg::ref_ptr<osg::StateSet>,GlyphQuads> TextureGlyphQuadMap;
// iternal map used for rendering. Set up by the computeGlyphRepresentation() method.
TextureGlyphQuadMap _textureGlyphQuadMap;
mutable osg::BoundingBox _textBB;
void computeGlyphRepresentation();
osg::ref_ptr<EncodedText> _encodedText;
osg::Vec3 _pos;
osg::Vec3 _alignmentPos;
osg::Vec4 _color;
};
}
#endif // OSGTEXT_TEXT
#endif

View File

@ -104,7 +104,6 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor
protected:
/** \internal JAVA: SUPPRESS UNBRIDGABLE :JAVA */
class IntersectState : public osg::Referenced
{
public:

View File

@ -68,197 +68,70 @@ void write_usage(std::ostream& out,const std::string& name)
#define TEXT_COL_3D osg::Vec4(.99,.3,.2,1)
std::string ttfPath("fonts/times.ttf");
std::string ttfPath1("fonts/arial.ttf");
std::string timesFont("fonts/times.ttf");
std::string arialFont("fonts/arial.ttf");
int gFontSize=18;
int gFontSize1=24;
std::vector<osg::ref_ptr<osgText::Text > > gTextList;
osgText::Text::AlignmentType gAlignment=osgText::Text::LEFT_BOTTOM;
osgText::Text::AlignmentType gAlignment=osgText::Text::LEFT_BOTTOM;
void set2dScene(osg::Group* rootNode)
{
osgText::Text* text;
osg::Geode* geode;
osg::Material* textMaterial;
osg::StateSet* textState;
double xOffset=150;
double yOffset=gFontSize+10;
///////////////////////////////////////////////////////////////////////////
// setup the texts
///////////////////////////////////////////////////////////////////////////
// BitmapFont
osgText::BitmapFont* bitmapFont= new osgText::BitmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(bitmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_BITMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("BitmapFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PixmapFont
osgText::PixmapFont* pixmapFont= new osgText::PixmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(pixmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_PIXMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("PixmapFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_2D);
// to get antiaA pixmapFonts we have to draw them with blending
osg::BlendFunc *transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setMode(GL_BLEND,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// TextureFont
osgText::TextureFont* textureFont= new osgText::TextureFont(ttfPath1,
gFontSize1);
text= new osgText::Text(textureFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_TEXTURE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("TextureFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
// to get antiaA pixmapFonts we have to draw them with blending
transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PolygonFont
osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(polygonFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string("TEXT_POLYGON"));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("PolygonFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// OutlineFont
osgText::OutlineFont* outlineFont= new osgText::OutlineFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(outlineFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_OUTLINE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
geode = new osg::Geode();
geode->setName("OutlineFont");
geode->addDrawable( text );
textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK, TEXT_COL_2D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
osg::Geode* geode = new osg::Geode();
rootNode->addChild(geode);
// now add a depth attribute to the scene to force it to draw on top.
osg::Depth* depth = new osg::Depth;
depth->setRange(0.0,0.0);
osg::StateSet* rootState = new osg::StateSet();
rootState->setAttribute(depth);
rootState->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
rootNode->setStateSet(rootState);
osg::Vec3 position(150.0f,10.0f,0.0f);
osg::Vec3 delta(90.0f,120.0f,0.0f);
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
}
struct MyCallback : public osg::NodeCallback

View File

@ -159,17 +159,18 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb)
{
osg::Geode* geode = new osg::Geode();
osgText::PolygonFont* polygonFont= new osgText::PolygonFont("fonts/times.ttf",20, 3);
osgText::Text* text = new osgText::Text(polygonFont);
text->setText("OpenSceneGraph");
std::string font("fonts/arial.ttf");
osgText::Text* text = new osgText::Text;
text->setFont(font);
text->setFontSize(64,64);
text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAxisAlignment(osgText::Text::XZ_PLANE);
text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin())));
text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f));
osg::StateSet* stateset = text->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
text->setText("OpenSceneGraph");
geode->addDrawable( text );
return geode;
@ -182,34 +183,38 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb)
osg::StateSet* stateset = geode->getOrCreateStateSet();
osg::BlendFunc *transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// osg::BlendFunc *transp= new osg::BlendFunc();
// transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
stateset->setAttributeAndModes(transp,osg::StateAttribute::ON);
stateset->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
// stateset->setAttributeAndModes(transp,osg::StateAttribute::ON);
// stateset->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
// stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
//std::string font("fonts/times.ttf");
std::string font("fonts/arial.ttf");
osgText::Text* text = new osgText::Text(new osgText::TextureFont(font,100));
osgText::Text* text = new osgText::Text;
text->setText("OpenSceneGraph");
text->setFont(font);
text->setFontSize(64,64);
text->setAlignment(osgText::Text::RIGHT_CENTER);
text->setAxisAlignment(osgText::Text::XZ_PLANE);
text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.3f));
//text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's orignal OSG colour
text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour
text->setText("OpenSceneGraph");
geode->addDrawable( text );
if (s_ProfessionalServices)
{
osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45));
//osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45));
osgText::Text* subscript = new osgText::Text;
subscript->setFont(font);
subscript->setText("Professional Services");
subscript->setAlignment(osgText::Text::RIGHT_CENTER);
subscript->setAxisAlignment(osgText::Text::XZ_PLANE);

View File

@ -44,339 +44,137 @@ using namespace osgGLUT;
#define TEXT_COL_3D osg::Vec4(.99,.3,.2,1)
std::string ttfPath("fonts/times.ttf");
std::string ttfPath1("fonts/arial.ttf");
std::string timesFont("fonts/times.ttf");
std::string arialFont("fonts/arial.ttf");
int gFontSize=18;
int gFontSize1=24;
std::vector<osg::ref_ptr<osgText::Text > > gTextList;
osgText::Text::AlignmentType gAlignment=osgText::Text::LEFT_BOTTOM;
std::vector<osgText::Text*> gTextList;
osgText::Text::AlignmentType gAlignment=osgText::Text::BASE_LINE;
void set2dScene(osg::Group* rootNode)
{
osgText::Text* text;
osg::Geode* geode;
osg::StateSet* textState;
double xOffset=150;
double yOffset=gFontSize+10;
///////////////////////////////////////////////////////////////////////////
// setup the texts
///////////////////////////////////////////////////////////////////////////
// BitmapFont
osgText::BitmapFont* bitmapFont= new osgText::BitmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(bitmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_BITMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_2D);
geode = new osg::Geode();
geode->setName("BitmapFont");
geode->addDrawable( text );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PixmapFont
osgText::PixmapFont* pixmapFont= new osgText::PixmapFont(ttfPath,
gFontSize1);
text= new osgText::Text(pixmapFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_PIXMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_2D);
geode = new osg::Geode();
geode->setName("PixmapFont");
geode->addDrawable( text );
// to get antiaA pixmapFonts we have to draw them with blending
osg::BlendFunc *transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttributeAndModes(transp,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// TextureFont
osgText::TextureFont* textureFont= new osgText::TextureFont(ttfPath1,
gFontSize1);
text= new osgText::Text(textureFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_TEXTURE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_2D);
geode = new osg::Geode();
geode->setName("TextureFont");
geode->addDrawable( text );
// to get antiaA pixmapFonts we have to draw them with blending
transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
textState->setAttributeAndModes(transp,osg::StateAttribute::ON);
textState->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// PolygonFont
osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(polygonFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string("TEXT_POLYGON"));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_2D);
geode = new osg::Geode();
geode->setName("PolygonFont");
geode->addDrawable( text );
rootNode->addChild(geode);
xOffset+=90;
yOffset+=120;
///////////////////////////////////////////////////////////////////////////
// OutlineFont
osgText::OutlineFont* outlineFont= new osgText::OutlineFont(ttfPath,
gFontSize1,
3);
text= new osgText::Text(outlineFont);
gTextList.push_back(text);
text->setText(std::string("2d ")+std::string(TEXT_OUTLINE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_2D);
geode = new osg::Geode();
geode->setName("OutlineFont");
geode->addDrawable( text );
osg::Geode* geode = new osg::Geode();
rootNode->addChild(geode);
// now add a depth attribute to the scene to force it to draw on top.
osg::Depth* depth = new osg::Depth;
depth->setRange(0.0,0.0);
osg::StateSet* rootState = new osg::StateSet();
rootState->setAttribute(depth);
rootNode->setStateSet(rootState);
osg::Vec3 position(150.0f,10.0f,0.0f);
osg::Vec3 delta(90.0f,120.0f,0.0f);
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
}
void setScene(osg::Group* rootNode)
{
osgText::Text* text;
osg::Geode* geode;
osg::StateSet* textState;
double xOffset=0;
double yOffset=0;
///////////////////////////////////////////////////////////////////////////
// setup the texts
///////////////////////////////////////////////////////////////////////////
// BitmapFont
osgText::BitmapFont* bitmapFont= new osgText::BitmapFont(ttfPath,
gFontSize);
text= new osgText::Text(bitmapFont);
gTextList.push_back(text);
text->setText(std::string(TEXT_BITMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_3D);
geode = new osg::Geode();
geode->setName("BitmapFont");
geode->addDrawable( text );
/*
osg::Material* textMaterial = new osg::Material();
textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_3D);
textState = new osg::StateSet();
textState->setAttribute(textMaterial );
geode->setStateSet( textState );
*/
osg::Geode* geode = new osg::Geode();
rootNode->addChild(geode);
osg::Vec3 position(150.0f,10.0f,0.0f);
osg::Vec3 delta(90.0f,120.0f,0.0f);
yOffset+=gFontSize+5;
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
///////////////////////////////////////////////////////////////////////////
// PixmapFont
osgText::PixmapFont* pixmapFont= new osgText::PixmapFont(ttfPath,
gFontSize);
text= new osgText::Text(pixmapFont);
gTextList.push_back(text);
text->setText(std::string(TEXT_PIXMAP));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_3D);
geode = new osg::Geode();
geode->setName("PixmapFont");
geode->addDrawable( text );
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
// textMaterial = new osg::Material();
// textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
// textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_3D);
// to get antiaA pixmapFonts we have to draw them with blending
osg::BlendFunc *transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
// textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setMode(GL_BLEND,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
rootNode->addChild(geode);
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
yOffset+=gFontSize+5;
///////////////////////////////////////////////////////////////////////////
// TextureFont
osgText::TextureFont* textureFont= new osgText::TextureFont(ttfPath,
gFontSize);
text= new osgText::Text(textureFont);
gTextList.push_back(text);
text->setText(std::string(TEXT_TEXTURE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_3D);
geode = new osg::Geode();
geode->setName("TextureFont");
geode->addDrawable( text );
{
osgText::Text* text = new osgText::Text;
geode->addDrawable( text );
gTextList.push_back(text);
// textMaterial = new osg::Material();
// textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
// textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_3D);
// to get antiaA pixmapFonts we have to draw them with blending
transp= new osg::BlendFunc();
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
textState = new osg::StateSet();
// textState->setAttribute(textMaterial );
textState->setAttribute(transp);
textState->setMode(GL_BLEND,osg::StateAttribute::ON);
textState->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON);
textState->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
geode->setStateSet( textState );
rootNode->addChild(geode);
yOffset+=gFontSize+5;
///////////////////////////////////////////////////////////////////////////
// PolygonFont
osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath,
gFontSize,
3);
text= new osgText::Text(polygonFont);
gTextList.push_back(text);
text->setText(std::string(TEXT_POLYGON));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_3D);
geode = new osg::Geode();
geode->setName("PolygonFont");
geode->addDrawable( text );
// textMaterial = new osg::Material();
// textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
// textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_3D);
// textState = new osg::StateSet();
// textState->setAttribute(textMaterial );
// geode->setStateSet( textState );
rootNode->addChild(geode);
yOffset+=gFontSize+5;
///////////////////////////////////////////////////////////////////////////
// OutlineFont
osgText::OutlineFont* outlineFont= new osgText::OutlineFont(ttfPath,
gFontSize,
3);
text= new osgText::Text(outlineFont);
gTextList.push_back(text);
text->setText(std::string(TEXT_OUTLINE));
text->setPosition(osg::Vec3(xOffset,yOffset,0));
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
text->setColor(TEXT_COL_3D);
geode = new osg::Geode();
geode->setName("OutlineFont");
geode->addDrawable( text );
// textMaterial = new osg::Material();
// textMaterial->setColorMode( osg::Material::AMBIENT_AND_DIFFUSE);
// textMaterial->setDiffuse( osg::Material::FRONT_AND_BACK,TEXT_COL_3D);
// textState = new osg::StateSet();
// textState->setAttribute(textMaterial );
// geode->setStateSet( textState );
rootNode->addChild(geode);
text->setFont(timesFont);
text->setFontSize(gFontSize,gFontSize);
text->setText("String 1");
text->setPosition(position);
text->setDrawMode( osgText::Text::TEXT |
osgText::Text::BOUNDINGBOX |
osgText::Text::ALIGNMENT );
text->setAlignment(gAlignment);
position += delta;
}
}
@ -474,44 +272,33 @@ protected:
{
case '1':
{ // change DrawMode
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
std::vector<osgText::Text*>::iterator itr=gTextList.begin();
for(;itr!=gTextList.end();itr++)
(*itr)->setDrawMode(osgText::Text::TEXT ^ (*itr)->getDrawMode());
}
return;
case '2':
{ // change DrawMode
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
std::vector<osgText::Text*>::iterator itr=gTextList.begin();
for(;itr!=gTextList.end();itr++)
(*itr)->setDrawMode(osgText::Text::BOUNDINGBOX ^ (*itr)->getDrawMode());
}
return;
case '3':
{ // change DrawMode
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
std::vector<osgText::Text*>::iterator itr=gTextList.begin();
for(;itr!=gTextList.end();itr++)
(*itr)->setDrawMode(osgText::Text::ALIGNMENT ^ (*itr)->getDrawMode());
}
return;
///////////////////////////////////////////////////////////////////
case '4':
{ // change BoundingBoxType to GEOMETRY
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
osgText::Text::BoundingBoxType type=(*itr)->getBoundingBox()==osgText::Text::GLYPH ?
osgText::Text::GEOMETRY :
osgText::Text::GLYPH;
for(;itr!=gTextList.end();itr++)
(*itr)->setBoundingBox(type);
}
return;
///////////////////////////////////////////////////////////////////
case '5':
{ // change the textAlignment
gAlignment=(osgText::Text::AlignmentType)((int)gAlignment+1);
if(gAlignment>osgText::Text::RIGHT_BOTTOM)
if(gAlignment>osgText::Text::BASE_LINE)
gAlignment=osgText::Text::LEFT_TOP;
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
std::vector<osgText::Text*>::iterator itr=gTextList.begin();
for(;itr!=gTextList.end();itr++)
(*itr)->setAlignment(gAlignment);
}
@ -532,9 +319,9 @@ int main( int argc, char **argv )
// get the fontName
if(argc > 1)
ttfPath=argv[1];
timesFont=argv[1];
if(argc > 2)
ttfPath1=argv[2];
arialFont=argv[2];
if(argc > 3)
{
gFontSize=atoi(argv[3]);

View File

@ -77,6 +77,20 @@ Registry::Registry()
addFileExtensionAlias("lw", "lwo");
addFileExtensionAlias("wrl", "iv");
// add alias for the text/freetype plugin.
addFileExtensionAlias("ttf", "freetype"); // true type
addFileExtensionAlias("ttc", "freetype"); // true type
addFileExtensionAlias("cid", "freetype"); // Postscript CID-Fonts
addFileExtensionAlias("cff", "freetype"); // OpenType
addFileExtensionAlias("cef", "freetype"); // OpenType
addFileExtensionAlias("fon", "freetype"); // Windows bitmap fonts
addFileExtensionAlias("fnt", "freetype"); // Windows bitmap fonts
// wont't add type1 and type2 until resolve extension collision with Peformer binary and ascii files.
// addFileExtensionAlias("pfb", "freetype"); // type1 binary
// addFileExtensionAlias("pfa", "freetype"); // type2 ascii
}

View File

@ -0,0 +1,126 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "FreeTypeFont.h"
#include FT_GLYPH_H
#include <osgDB/WriteFile>
FreeTypeFont::FreeTypeFont(const std::string& filename, FT_Face face):
_filename(filename),
_face(face)
{
}
void FreeTypeFont::setSize(unsigned int width, unsigned int height)
{
FT_Error error = FT_Set_Pixel_Sizes( _face, /* handle to face object */
width, /* pixel_width */
height ); /* pixel_height */
if (error)
{
std::cout<<"FT_Set_Pixel_Sizes() - error "<<error<<std::endl;
}
else
{
_width = width;
_height = height;
}
}
osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode)
{
// search for glyph amoungst existing glyphs.
GlyphMap::iterator itr = _glyphMap.find(charcode);
if (itr!=_glyphMap.end()) return itr->second.get();
FT_Error error = FT_Load_Char( _face, charcode, FT_LOAD_RENDER|FT_LOAD_NO_BITMAP );
if (error)
{
std::cout << "FT_Load_Char(...) error "<<error<<std::endl;
return 0;
}
FT_GlyphSlot glyphslot = _face->glyph;
int rows = glyphslot->bitmap.rows;
int width = glyphslot->bitmap.width;
int pitch = glyphslot->bitmap.pitch;
unsigned char* buffer = glyphslot->bitmap.buffer;
osg::ref_ptr<Glyph> glyph = new Glyph;
unsigned char* data = new unsigned char[width*rows*2];
glyph->setImage(width,rows,1,
GL_LUMINANCE_ALPHA,
GL_LUMINANCE_ALPHA,GL_UNSIGNED_BYTE,
data,
osg::Image::USE_NEW_DELETE,
1);
// copy image across to osgText::Glyph image.
for(int r=rows-1;r>=0;--r)
{
unsigned char* ptr = buffer+r*pitch;
for(int c=0;c<width;++c,++ptr)
{
(*data++)=255;
(*data++)=*ptr;
}
}
FT_Glyph_Metrics* metrics = &(glyphslot->metrics);
glyph->setFont(this);
glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left.
glyph->setHorizontalAdvance((float)metrics->horiAdvance/64.0f);
glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX/64.0f,(float)(metrics->vertBearingY-metrics->height)/64.0f)); // top middle.
glyph->setVerticalAdvance((float)metrics->vertAdvance/64.0f);
addGlyph(charcode,glyph.get());
return glyph.get();
}
osg::Vec2 FreeTypeFont::getKerning(unsigned int leftcharcode,unsigned int rightcharcode)
{
if (!FT_HAS_KERNING(_face)) return osg::Vec2(0.0f,0.0f);
// convert character code to glyph index
FT_UInt left = FT_Get_Char_Index( _face, leftcharcode );
FT_UInt right = FT_Get_Char_Index( _face, rightcharcode );
// get the kerning distances.
FT_Vector kerning;
FT_Error error = FT_Get_Kerning( _face, // handle to face object
left, // left glyph index
right, // right glyph index
ft_kerning_default, // kerning mode
&kerning ); // target vector
if (error)
{
return osg::Vec2(0.0f,0.0f);
}
return osg::Vec2((float)kerning.x/64.0f,(float)kerning.y/64.0f);
}
bool FreeTypeFont::hasVertical() const
{
return FT_HAS_VERTICAL(_face);
}

View File

@ -0,0 +1,46 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef FREETYPE_FONT
#define FREETYPE_FONT 1
#include <osgText/Font>
#include <ft2build.h>
#include FT_FREETYPE_H
class FreeTypeFont : public osgText::Font
{
// declare the interface to a font.
public:
FreeTypeFont(const std::string& filename, FT_Face face);
virtual std::string getFileName() const { return _filename; }
virtual void setSize(unsigned int width, unsigned int height);
virtual osgText::Font::Glyph* getGlyph(unsigned int charcode);
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode);
virtual bool hasVertical() const;
protected:
std::string _filename;
FT_Face _face;
};
#endif

View File

@ -0,0 +1,57 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "FreeTypeLibrary.h"
FreeTypeLibrary::FreeTypeLibrary()
{
FT_Error error = FT_Init_FreeType( &_ftlibrary );
if (error)
{
std::cout<<"Warning: an error occured during FT_Init_FreeType(..) initialisation .. "<<std::endl;
}
}
FreeTypeLibrary::~FreeTypeLibrary()
{
FT_Done_FreeType( _ftlibrary);
}
FreeTypeLibrary* FreeTypeLibrary::instance()
{
static FreeTypeLibrary s_library;
return &s_library;
}
FreeTypeFont* FreeTypeLibrary::getFont(const std::string& fontfile,unsigned int index)
{
FT_Face face; /* handle to face object */
FT_Error error = FT_New_Face( _ftlibrary, fontfile.c_str(), index, &face );
if (error == FT_Err_Unknown_File_Format)
{
std::cout<<" .... the font file could be opened and read, but it appears"<<std::endl;
std::cout<<" .... that its font format is unsupported"<<std::endl;
return 0;
}
else if (error)
{
std::cout<<" .... another error code means that the font file could notd"<<std::endl;
std::cout<<" .... be opened, read or simply that it is broken..d"<<std::endl;
return 0;
}
return new FreeTypeFont(fontfile,face);
}

View File

@ -0,0 +1,42 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGTEXT_LIBRARY
#define OSGTEXT_LIBRARY
#include "FreeTypeFont.h"
class FreeTypeLibrary
{
public:
/** get the singleton instance.*/
static FreeTypeLibrary* instance();
FreeTypeFont* getFont(const std::string& fontfile,unsigned int index=0);
protected:
/** protected constructor to ensure the only way to create the
* library is via the singleton instance method.*/
FreeTypeLibrary();
/** protected destrcutor to prevent inappropriate deletion.*/
virtual ~FreeTypeLibrary();
FT_Library _ftlibrary;
};
#endif

View File

@ -0,0 +1,29 @@
TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
FreeTypeLibrary.cpp\
FreeTypeFont.cpp\
ReaderWriterFreeType.cpp\
LIBS += $(OSG_LIBS) $(FREETYPE_LIB) $(OTHER_LIBS)
ifneq ($(OS),HP-UX)
INC += -I$(OSGHOME)/include \
-I/usr/include/freetype2 \
-I/usr/local/include \
-I/usr/local/include/freetype2 \
-I/usr/freeware/include \
-I/usr/freeware/include/freetype2
LINKARGS += -L/usr/local/lib\
-L/usr/freeware/lib$(ARCH)
else
INC += $(FREETYPE_INCLUDE)
endif
TARGET_BASENAME = freetype
include $(TOPDIR)/Make/cygwin_plugin_def
PLUGIN = $(PLUGIN_PREFIX)$(TARGET_BASENAME).$(PLUGIN_EXT)
include $(TOPDIR)/Make/makerules

View File

@ -0,0 +1,37 @@
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
#include "FreeTypeLibrary.h"
class ReaderWriterFreeType : public osgDB::ReaderWriter
{;
public:
virtual const char* className() { return "FreeType Font Reader/Writer"; }
virtual bool acceptsExtension(const std::string& extension)
{
return osgDB::equalCaseInsensitive(extension,"ttf") || // true type
osgDB::equalCaseInsensitive(extension,"ttc") || // true type
osgDB::equalCaseInsensitive(extension,"pfb") || // type1 binary
osgDB::equalCaseInsensitive(extension,"pfa") || // type2 ascii
osgDB::equalCaseInsensitive(extension,"cid") || // Postscript CID-Fonts
osgDB::equalCaseInsensitive(extension,"cff") || // OpenType
osgDB::equalCaseInsensitive(extension,"cef") || // OpenType
osgDB::equalCaseInsensitive(extension,"fon") || // Windows bitmap fonts
osgDB::equalCaseInsensitive(extension,"fnt"); // Windows bitmap fonts
}
virtual ReadResult readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*)
{
std::string ext = osgDB::getFileExtension(fileName);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
osgText::Font* font = FreeTypeLibrary::instance()->getFont(fileName,0);
return font;
}
};
// now register with Registry to instantiate the above
// reader/writer.
osgDB::RegisterReaderWriterProxy<ReaderWriterFreeType> g_readerWriter_FreeType_Proxy;

View File

@ -703,10 +703,8 @@ class ReaderWriterGEO : public ReaderWriter
osg::MatrixTransform *numt=NULL;
std::string ttfPath("fonts/times.ttf");
int gFontSize1=2;
osgText::PolygonFont* polygonFont= new osgText::PolygonFont(ttfPath,
gFontSize1,
3);
osgText::Text *text= new osgText::Text(polygonFont);
osgText::Text *text= new osgText::Text;
text->setFont(ttfPath);
const geoField *gfd=gr->getField(GEO_DB_TEXT_NAME);
//const char *name=gfd ? gfd->getChar() : "a text";
gfd=gr->getField(GEO_DB_TEXT_STRING);

View File

@ -1,205 +0,0 @@
#include <osgText/Font>
#include <osgText/Font>
#include <iostream>
#include <string>
#include <osg/Vec3>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
/////////////////////////////////////////////////////////////////////////////
// class Font
/////////////////////////////////////////////////////////////////////////////
bool Font_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
osgDB::RegisterDotOsgWrapperProxy Font_Proxy
(
0,
"Font",
"Object Font",
0,
Font_writeLocalData
);
bool Font_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgText::Font &myobj = static_cast<const osgText::Font &>(obj);
fw.indent() << "parameters ";
fw << myobj.getPointSize() << " " << myobj.getTextureSize() << " ";
fw << fw.wrapString(myobj.getFontName()) << std::endl;
return true;
}
/////////////////////////////////////////////////////////////////////////////
// class BitmapFont
/////////////////////////////////////////////////////////////////////////////
bool BitmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr);
osgDB::RegisterDotOsgWrapperProxy BitmapFont_Proxy
(
new osgText::BitmapFont,
"BitmapFont",
"Object Font RasterFont BitmapFont",
BitmapFont_readLocalData,
0
);
bool BitmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::BitmapFont &myobj = static_cast<osgText::BitmapFont &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("parameters")) {
int psize;
if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) {
osgText::BitmapFont *temp = new osgText::BitmapFont(std::string(fr[3].getStr()), psize);
temp->copyAndInvalidate(myobj);
fr += 4;
itAdvanced = true;
}
}
return itAdvanced;
}
/////////////////////////////////////////////////////////////////////////////
// class PixmapFont
/////////////////////////////////////////////////////////////////////////////
bool PixmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr);
osgDB::RegisterDotOsgWrapperProxy PixmapFont_Proxy
(
new osgText::PixmapFont,
"PixmapFont",
"Object Font RasterFont PixmapFont",
PixmapFont_readLocalData,
0
);
bool PixmapFont_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::PixmapFont &myobj = static_cast<osgText::PixmapFont &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("parameters")) {
int psize;
if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) {
osgText::PixmapFont *temp = new osgText::PixmapFont(std::string(fr[3].getStr()), psize);
temp->copyAndInvalidate(myobj);
fr += 4;
itAdvanced = true;
}
}
return itAdvanced;
}
/////////////////////////////////////////////////////////////////////////////
// class TextureFont
/////////////////////////////////////////////////////////////////////////////
bool TextureFont_readLocalData(osg::Object &obj, osgDB::Input &fr);
osgDB::RegisterDotOsgWrapperProxy TextureFont_Proxy
(
new osgText::TextureFont,
"TextureFont",
"Object Font RasterFont TextureFont",
TextureFont_readLocalData,
0
);
bool TextureFont_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::TextureFont &myobj = static_cast<osgText::TextureFont &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("parameters")) {
int psize, txsize;
if (fr[1].getInt(psize) && fr[2].getInt(txsize) && fr[3].isString()) {
osgText::TextureFont *temp = new osgText::TextureFont(std::string(fr[3].getStr()), psize, txsize);
temp->copyAndInvalidate(myobj);
fr += 4;
itAdvanced = true;
}
}
return itAdvanced;
}
/////////////////////////////////////////////////////////////////////////////
// class OutlineFont
/////////////////////////////////////////////////////////////////////////////
bool OutlineFont_readLocalData(osg::Object &obj, osgDB::Input &fr);
osgDB::RegisterDotOsgWrapperProxy OutlineFont_Proxy
(
new osgText::OutlineFont,
"OutlineFont",
"Object Font VectorFont OutlineFont",
OutlineFont_readLocalData,
0
);
bool OutlineFont_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::OutlineFont &myobj = static_cast<osgText::OutlineFont &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("parameters")) {
int psize;
if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) {
osgText::OutlineFont *temp = new osgText::OutlineFont(std::string(fr[3].getStr()), psize, 1);
temp->copyAndInvalidate(myobj);
fr += 4;
itAdvanced = true;
}
}
return itAdvanced;
}
/////////////////////////////////////////////////////////////////////////////
// class PolygonFont
/////////////////////////////////////////////////////////////////////////////
bool PolygonFont_readLocalData(osg::Object &obj, osgDB::Input &fr);
osgDB::RegisterDotOsgWrapperProxy PolygonFont_Proxy
(
new osgText::PolygonFont,
"PolygonFont",
"Object Font VectorFont PolygonFont",
PolygonFont_readLocalData,
0
);
bool PolygonFont_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::PolygonFont &myobj = static_cast<osgText::PolygonFont &>(obj);
bool itAdvanced = false;
if (fr[0].matchWord("parameters")) {
int psize;
if (fr[1].getInt(psize) && fr[2].isInt() && fr[3].isString()) {
osgText::PolygonFont *temp = new osgText::PolygonFont(std::string(fr[3].getStr()), psize, 1);
temp->copyAndInvalidate(myobj);
fr += 4;
itAdvanced = true;
}
}
return itAdvanced;
}

View File

@ -1,100 +0,0 @@
#include <osgText/Paragraph>
#include <osgText/Font>
#include <iostream>
#include <string>
#include <osg/Vec3>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
bool Paragraph_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool Paragraph_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
// osgDB::RegisterDotOsgWrapperProxy Paragraph_Proxy
// (
// new osgText::Paragraph,
// "Paragraph",
// "Object Node Geode Paragraph",
// Paragraph_readLocalData,
// Paragraph_writeLocalData
// );
//
bool Paragraph_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::Paragraph &myobj = static_cast<osgText::Paragraph &>(obj);
bool itAdvanced = false;
// font
osgText::Font *font = dynamic_cast<osgText::Font *>(fr.readObject());
if (font) {
myobj.setFont(font);
itAdvanced = true;
}
// maximum chars
if (fr[0].matchWord("maximumNoCharactersPerLine")) {
int i;
if (fr[1].getInt(i)) {
myobj.setMaximumNoCharactersPerLine(i);
fr += 2;
itAdvanced = true;
}
}
// text
if (fr[0].matchWord("text") && fr[1].isString()) {
myobj.setText(std::string(fr[1].getStr()));
fr += 2;
itAdvanced = true;
}
// position
if (fr[0].matchWord("position")) {
osg::Vec3 p;
if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) {
myobj.setPosition(p);
fr += 4;
itAdvanced = true;
}
}
// alignment
if (fr[0].matchWord("alignment")) {
int i;
if (fr[1].getInt(i)) {
myobj.setAlignment(i);
fr += 2;
itAdvanced = true;
}
}
return itAdvanced;
}
bool Paragraph_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgText::Paragraph &myobj = static_cast<const osgText::Paragraph &>(obj);
// font
fw.writeObject(*myobj.getFont());
// maximum chars
fw.indent() << "maximumNoCharactersPerLine " << myobj.getMaximumNoCharactersPerLine() << std::endl;
// text
fw.indent() << "text " << myobj.getText() << std::endl;
// position
osg::Vec3 p = myobj.getPosition();
fw.indent() << "position " << p.x() << " " << p.y() << " " << p.z() << std::endl;
// alignment
fw.indent() << "alignment " << myobj.getAlignment() << std::endl;
return true;
}

View File

@ -25,14 +25,14 @@ osgDB::RegisterDotOsgWrapperProxy Text_Proxy
bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
{
osgText::Text &myobj = static_cast<osgText::Text &>(obj);
osgText::Text &text = static_cast<osgText::Text &>(obj);
bool itAdvanced = false;
// position
if (fr[0].matchWord("position")) {
osg::Vec3 p;
if (fr[1].getFloat(p.x()) && fr[2].getFloat(p.y()) && fr[3].getFloat(p.z())) {
myobj.setPosition(p);
text.setPosition(p);
fr += 4;
itAdvanced = true;
}
@ -42,7 +42,7 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
if (fr[0].matchWord("color")) {
osg::Vec4 c;
if (fr[1].getFloat(c.x()) && fr[2].getFloat(c.y()) && fr[3].getFloat(c.z()) && fr[4].getFloat(c.w())) {
myobj.setColor(c);
text.setColor(c);
fr += 4;
itAdvanced = true;
}
@ -52,17 +52,7 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
if (fr[0].matchWord("drawMode")) {
int i;
if (fr[1].getInt(i)) {
myobj.setDrawMode(i);
fr += 2;
itAdvanced = true;
}
}
// bounding box
if (fr[0].matchWord("boundingBox")) {
int i;
if (fr[1].getInt(i)) {
myobj.setBoundingBox(i);
text.setDrawMode(i);
fr += 2;
itAdvanced = true;
}
@ -72,22 +62,15 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
if (fr[0].matchWord("alignment")) {
int i;
if (fr[1].getInt(i)) {
myobj.setAlignment(i);
text.setAlignment((osgText::Text::AlignmentType)i);
fr += 2;
itAdvanced = true;
}
}
// font
osgText::Font *font = dynamic_cast<osgText::Font *>(fr.readObject());
if (font) {
myobj.setFont(font);
itAdvanced = true;
}
// text
if (fr.matchSequence("text %s")) {
myobj.setText(std::string(fr[1].getStr()));
text.setText(std::string(fr[1].getStr()));
fr += 2;
itAdvanced = true;
}
@ -97,30 +80,47 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
{
const osgText::Text &myobj = static_cast<const osgText::Text &>(obj);
const osgText::Text &text = static_cast<const osgText::Text &>(obj);
if (text.getFont())
{
fw.indent() << "font " << text.getFont()->getFileName() << std::endl;
}
fw.indent() << "fontSize " << text.getFontWidth() << " " << text.getFontHeight() << std::endl;
// position
osg::Vec3 p = myobj.getPosition();
osg::Vec3 p = text.getPosition();
fw.indent() << "position " << p.x() << " " << p.y() << " " << p.z() << std::endl;
// color
osg::Vec4 c = myobj.getColor();
osg::Vec4 c = text.getColor();
fw.indent() << "color " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl;
// draw mode
fw.indent() << "drawMode " << myobj.getDrawMode() << std::endl;
// bounding box
fw.indent() << "boundingBox " << myobj.getBoundingBox() << std::endl;
fw.indent() << "drawMode " << text.getDrawMode() << std::endl;
// alignment
fw.indent() << "alignment " << myobj.getAlignment() << std::endl;
// font
fw.writeObject(*myobj.getFont());
fw.indent() << "alignment " << text.getAlignment() << std::endl;
// text
fw.indent() << "text " << fw.wrapString(myobj.getText()) << std::endl;
const osgText::Text::TextString& textstring = text.getText();
bool isACString = true;
for(osgText::Text::TextString::const_iterator itr=textstring.begin();
itr!=textstring.end() && isACString;
++itr)
{
if (*itr==0 || *itr>256) isACString=false;
}
if (isACString)
{
std::string str(textstring.begin(),textstring.end());
fw.indent() << "text " << fw.wrapString(str) << std::endl;
}
else
{
// do it the hardway...
}
return true;
}

View File

@ -2,10 +2,7 @@ TOPDIR = ../../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
IO_Text.cpp \
IO_Font.cpp \
IO_Paragraph.cpp \
IO_Text.cpp
LIBS += -losgText $(OSG_LIBS) $(OTHER_LIBS)

215
src/osgText/DefaultFont.cpp Normal file
View File

@ -0,0 +1,215 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY{
}
without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "DefaultFont.h"
#include <osg/Notify>
using namespace osgText;
DefaultFont::DefaultFont()
{
constructGlyphs();
}
DefaultFont::~DefaultFont()
{
}
DefaultFont* DefaultFont::instance()
{
static osg::ref_ptr<DefaultFont> s_defaultFont = new DefaultFont;
return s_defaultFont.get();
}
void DefaultFont::setSize(unsigned int, unsigned int)
{
osg::notify(osg::INFO)<<"DefaultFont::setSize(,) call is ignored."<<std::endl;
}
Font::Glyph* DefaultFont::getGlyph(unsigned int charcode)
{
GlyphMap::iterator itr = _glyphMap.find(charcode);
if (itr!=_glyphMap.end()) return itr->second.get();
else return 0;
}
osg::Vec2 DefaultFont::getKerning(unsigned int,unsigned int)
{
// no kerning on default font.
return osg::Vec2(0.0f,0.0f);
}
bool DefaultFont::hasVertical() const
{
return true;
}
void DefaultFont::constructGlyphs()
{
static GLubyte rasters[][12] = { // ascii symbols 32-127, small font
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, 0x00},
{0x00, 0x00, 0x28, 0x28, 0x7e, 0x14, 0x14, 0x14, 0x3f, 0x0a, 0x0a, 0x00},
{0x00, 0x00, 0x08, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x08, 0x00},
{0x00, 0x00, 0x02, 0x45, 0x22, 0x10, 0x08, 0x04, 0x22, 0x51, 0x20, 0x00},
{0x00, 0x00, 0x3b, 0x44, 0x4a, 0x49, 0x30, 0x10, 0x20, 0x20, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x00},
{0x04, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00},
{0x10, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x36, 0x1c, 0x7f, 0x1c, 0x36, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x08, 0x00},
{0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x0c, 0x02, 0x02, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x0e, 0x04, 0x3e, 0x24, 0x14, 0x14, 0x0c, 0x0c, 0x04, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x3c, 0x20, 0x20, 0x20, 0x3e, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x10, 0x0c, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x22, 0x3e, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x04, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x04, 0x02, 0x02, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x1c, 0x20, 0x4e, 0x55, 0x55, 0x55, 0x4d, 0x21, 0x1e, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x3e, 0x22, 0x14, 0x14, 0x08, 0x08, 0x18, 0x00},
{0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00},
{0x00, 0x00, 0x1e, 0x21, 0x40, 0x40, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00},
{0x00, 0x00, 0x7c, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x7c, 0x00},
{0x00, 0x00, 0x7f, 0x21, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00},
{0x00, 0x00, 0x78, 0x20, 0x20, 0x24, 0x3c, 0x24, 0x20, 0x21, 0x7f, 0x00},
{0x00, 0x00, 0x1e, 0x21, 0x41, 0x47, 0x40, 0x40, 0x40, 0x21, 0x1e, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00},
{0x00, 0x00, 0x38, 0x44, 0x44, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1e, 0x00},
{0x00, 0x00, 0x73, 0x22, 0x24, 0x38, 0x28, 0x24, 0x24, 0x22, 0x73, 0x00},
{0x00, 0x00, 0x7f, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x36, 0x22, 0x63, 0x00},
{0x00, 0x00, 0x72, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x67, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x78, 0x20, 0x20, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00},
{0x00, 0x1b, 0x1c, 0x22, 0x41, 0x41, 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00},
{0x00, 0x00, 0x73, 0x22, 0x24, 0x24, 0x3e, 0x21, 0x21, 0x21, 0x7e, 0x00},
{0x00, 0x00, 0x3e, 0x41, 0x01, 0x01, 0x3e, 0x40, 0x40, 0x41, 0x3e, 0x00},
{0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x49, 0x7f, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x14, 0x22, 0x22, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x14, 0x14, 0x08, 0x14, 0x14, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x1c, 0x08, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00},
{0x00, 0x00, 0x7f, 0x21, 0x10, 0x10, 0x08, 0x04, 0x04, 0x42, 0x7f, 0x00},
{0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00},
{0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08},
{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00},
{0x00, 0x00, 0x3d, 0x42, 0x42, 0x3e, 0x02, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x21, 0x21, 0x21, 0x21, 0x3e, 0x20, 0x20, 0x60, 0x00},
{0x00, 0x00, 0x3e, 0x41, 0x40, 0x40, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3f, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x06, 0x00},
{0x00, 0x00, 0x3e, 0x41, 0x40, 0x7f, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x10, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x0c, 0x00},
{0x3c, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x20, 0x20, 0x60, 0x00},
{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x08, 0x00},
{0x38, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x00, 0x00, 0x04, 0x00},
{0x00, 0x00, 0x63, 0x24, 0x38, 0x28, 0x24, 0x26, 0x20, 0x20, 0x60, 0x00},
{0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00},
{0x00, 0x00, 0x6b, 0x2a, 0x2a, 0x2a, 0x2a, 0x74, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x22, 0x22, 0x32, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x41, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x20, 0x3e, 0x21, 0x21, 0x21, 0x21, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x07, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x19, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x41, 0x06, 0x38, 0x41, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x12, 0x10, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x26, 0x22, 0x22, 0x22, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x14, 0x2a, 0x2a, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x77, 0x22, 0x1c, 0x1c, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x22, 0x10, 0x08, 0x44, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08},
{0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x49, 0x31, 0x00, 0x00},
{0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00}
};
_width = 8;
_height = 12;
// populate the glyph mp
for(unsigned int i=32;i<127;i++)
{
osg::ref_ptr<Glyph> glyph = new Glyph;
unsigned char* data = new unsigned char[8*12*2];
glyph->setImage(_width,_height,1,
GL_LUMINANCE_ALPHA,
GL_LUMINANCE_ALPHA,GL_UNSIGNED_BYTE,
data,
osg::Image::USE_NEW_DELETE,
1);
// now populate data arry by converting bitmap into a luminance_alpha map.
unsigned char* ptr = rasters[i-32];
unsigned char value_on = 255;
unsigned char value_off = 0;
for(unsigned int row=0;row<_height;++row,++ptr)
{
(*data++)=((*ptr)&128)?value_on:value_off;
(*data++)=((*ptr)&128)?value_on:value_off;
(*data++)=((*ptr)&64)?value_on:value_off;
(*data++)=((*ptr)&64)?value_on:value_off;
(*data++)=((*ptr)&32)?value_on:value_off;
(*data++)=((*ptr)&32)?value_on:value_off;
(*data++)=((*ptr)&16)?value_on:value_off;
(*data++)=((*ptr)&16)?value_on:value_off;
(*data++)=((*ptr)&8)?value_on:value_off;
(*data++)=((*ptr)&8)?value_on:value_off;
(*data++)=((*ptr)&4)?value_on:value_off;
(*data++)=((*ptr)&4)?value_on:value_off;
(*data++)=((*ptr)&2)?value_on:value_off;
(*data++)=((*ptr)&2)?value_on:value_off;
(*data++)=((*ptr)&1)?value_on:value_off;
(*data++)=((*ptr)&1)?value_on:value_off;
}
glyph->setFont(this);
glyph->setHorizontalBearing(osg::Vec2(0.0f,0.0f)); // bottom left.
glyph->setHorizontalAdvance((float)_width);
glyph->setVerticalBearing(osg::Vec2((float)_width*0.5f,(float)_height)); // top middle.
glyph->setVerticalAdvance((float)_height);
addGlyph(i,glyph.get());
}
}

54
src/osgText/DefaultFont.h Normal file
View File

@ -0,0 +1,54 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef NEWTEXT_DEFAULTFONT_H
#define NEWTEXT_DEFAULTFONT_H 1
#include <osg/ref_ptr>
#include <osgText/Font>
#include <map>
namespace osgText {
class DefaultFont : public Font
{
public:
static DefaultFont* instance();
virtual std::string getFileName() const { return ""; }
/** NOP with DefaultFont since it only supports a single fixed sized font. */
virtual void setSize(unsigned int width, unsigned int height);
virtual Font::Glyph* getGlyph(unsigned int charcode);
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode);
virtual bool hasVertical() const;
protected:
DefaultFont();
virtual ~DefaultFont();
void constructGlyphs();
};
}
#endif

View File

@ -1,258 +0,0 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* --------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
#include <osgText/EncodedText>
#include <osg/Notify>
using namespace osgText;
EncodedText::EncodedText()
{
_encoding = ENCODING_ASCII;
_overrideEncoding = ENCODING_SIGNATURE;
}
int EncodedText::getNextCharacter(const unsigned char*& charString) const
{
// For more info on unicode encodings see:
// http://www-106.ibm.com/developerworks/unicode/library/u-encode.html
switch(_encoding)
{
case ENCODING_ASCII:
{
return *charString++;
}
case ENCODING_UTF8:
{
int char0 = *charString++;
if (char0 < 0x80) // 1-byte character
{
return char0;
}
int char1 = *charString++;
if (char0<0xe0) // 2-byte character
{
return ((char0&0x1f)<<6) | (char1&0x3f);
}
int char2 = *charString++;
if (char0<0xf0) // 3-byte character
{
return ((char0&0xf)<<12) | ((char1&0x3f)<<6) | (char2&0x3f);
}
int char3 = *charString++;
if (char0<0xf8) // 4-byte character
{
return ((char0&0x7)<<18) | ((char1&0x3f)<<12) | ((char2&0x3f)<<6) | (char3&0x3f);
}
break;
}
case ENCODING_UTF16_BE:
{
int char0 = *charString++;
int char1 = *charString++;
if ((char0<=0xD7) || (char0>=0xE0)) // simple character
{
return (char0<<8) | char1;
}
else if ((char0>=0xD8)&&(char0<=0xDB)) //using planes (this should get called very rarely)
{
int char2 = *charString++;
int char3 = *charString++;
int highSurrogate = (char0<<8) | char1;
int lowSurrogate = (char2<<8) | char3;
if ((char2>=0xDC)&&(char2<=0xDF)) //only for the valid range of low surrogate
{
// This covers the range of all 17 unicode planes
return ((highSurrogate-0xD800)*0x400) + (lowSurrogate-0xD800) + 0x10000;
}
}
break;
}
case ENCODING_UTF16_LE:
{
int char1 = *charString++;
int char0 = *charString++;
if ((char0<=0xD7) || (char0>=0xE0)) // simple character
{
return (char0<<8) | char1;
}
else if ((char0>=0xD8)&&(char0<=0xDB)) //using planes (this should get called very rarely)
{
int char3 = *charString++;
int char2 = *charString++;
int highSurrogate = (char0<<8) | char1;
int lowSurrogate = (char2<<8) | char3;
if ((char2>=0xDC)&&(char2<=0xDF)) //only for the valid range of low surrogate
{
// This covers the range of all 17 unicode planes
return ((highSurrogate-0xD800)*0x400) + (lowSurrogate-0xD800) + 0x10000;
}
}
break;
}
case ENCODING_UTF32_BE:
{
int character = ((((int)charString[0])<<24) | (((int)charString[1])<<16) |
(((int)charString[2])<<8) | charString[3]);
charString+=4;
if (character<0x110000)
{
// Character is constrained to the range set by the unicode standard
return character;
}
break;
}
case ENCODING_UTF32_LE:
{
int character = ((((int)charString[3])<<24) | (((int)charString[2])<<16) |
(((int)charString[1])<<8) | charString[0]);
charString+=4;
if (character<0x110000)
{
// Character is constrained to the range set by the unicode standard
return character;
}
break;
}
default:
{
// Should not reach this point unless the encoding is unhandled
// ENCODING_UTF16, ENCODING_UTF32 and ENCODING_SIGNATURE should never enter this method
osg::notify(osg::FATAL)<<"Error: Invalid string encoding"<<std::endl;
break;
}
}
return 0;
}
EncodedText::Encoding EncodedText::findEncoding(const unsigned char*& charString) const
{
switch (charString[0])
{
case 0xEF: // 8-bit encoding
{
// 8-bit signature = EF BB BF
if ((charString[1]==0xBB) && (charString[2]==0xBF))
{
charString+=3;
return ENCODING_UTF8;
}
break;
}
case 0xFE: // big-endian 16-bit
{
// 16-bit signature = FE FF
if (charString[1]==0xFF)
{
charString+=2;
return ENCODING_UTF16_BE;
}
break;
}
case 0xFF: // little-endian
{
// 16-bit signature = FF FE
// 32-bit signature = FF FE 00 00
if (charString[1]==0xFE)
{
// NOTE: There is an a potential problem as a 16-bit empty string
// is identical to a 32-bit start signature
if ((charString[2]==0) && (charString[3]==0) && (_overrideEncoding != ENCODING_UTF16)) //32-bit
{
charString+=4;
return ENCODING_UTF32_LE;
}
else //16-bit
{
charString+=2;
return ENCODING_UTF16_LE;
}
}
break;
}
case 0x00: // 32-bit big-endian
{
// 32-bit signature = 00 00 FE FF
if ((charString[1]==0x00) && (charString[2]==0xFE) && (charString[3]==0xFF))
{
charString+=4;
return ENCODING_UTF32_BE;
}
break;
}
}
return ENCODING_ASCII;
}
void EncodedText::setText(const unsigned char* text, int length)
{
_unicodeText.clear();
if (text != NULL)
{
const unsigned char* textStart = text;
if ((_overrideEncoding == ENCODING_SIGNATURE) ||
(_overrideEncoding == ENCODING_UTF16) ||
(_overrideEncoding == ENCODING_UTF32))
_encoding = findEncoding(text);
int character = getNextCharacter(text);
int charCount = (int)(text-textStart);
while ((character) && (length<0 || (charCount <= length)))
{
_unicodeText.push_back(character);
character = getNextCharacter(text);
charCount = (int)(text-textStart);
}
}
}
void EncodedText::setOverrideEncoding(EncodedText::Encoding encoding)
{
if (_overrideEncoding != encoding)
{
_overrideEncoding = encoding;
_encoding = encoding;
//NB As the original text is not cached we cannot confirm any ENCODING_SIGNATURE until text is set again
}
}
std::string EncodedText::convertWideString(const wchar_t* text)
{
std::string utf8string;
const wchar_t* pChars = text;
int currentChar = *pChars;
while (currentChar)
{
if (currentChar < 0x80)
utf8string+=(char)currentChar;
else if (currentChar < 0x800)
{
utf8string+=(char)(0xc0 | (currentChar>>6));
utf8string+=(char)(0x80 | currentChar & 0x3f);
}
else
{
utf8string+=(char)(0xe0 | (currentChar>>12));
utf8string+=(char)(0x80 | (currentChar>>6) & 0x3f);
utf8string+=(char)(0x80 | currentChar & 0x3f);
}
currentChar = *(++pChars);
}
return utf8string;
}

View File

@ -1,80 +0,0 @@
#include "FTBitmapGlyph.h"
FTBitmapGlyph::FTBitmapGlyph( FT_Glyph glyph)
: 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;}
advance = glyph->advance.x >> 16;
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;
if (srcPitch*srcHeight==0)
{
FT_Done_Glyph( glyph );
return;
}
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
// FIXME What about dest alignment?
destWidth = srcWidth;
destHeight = srcHeight;
data = new unsigned char[srcPitch * destHeight];
// !!!! THIS assumes a positive Pitch value. No allowance for negative pitch
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 = srcHeight;
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
}
FTBitmapGlyph::~FTBitmapGlyph()
{
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 );
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;
}

View File

@ -1,66 +0,0 @@
#ifndef __FTBitmapGlyph__
#define __FTBitmapGlyph__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
/**
* FTBitmapGlyph is a specialisation of FTGlyph for creating bitmaps.
*
* It provides the interface between Freetype glyphs and their openGL
* renderable counterparts. This is an abstract class and derived classes
* must implement the <code>render</code> function.
*
* @see FTGlyphContainer
*
*/
class FTGL_EXPORT FTBitmapGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTBitmapGlyph( FT_Glyph glyph);
/**
* 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;
/**
* The height of the glyph 'image'
*/
int destHeight;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
};
#endif // __FTBitmapGlyph__

View File

@ -1,97 +0,0 @@
#include "FTCharmap.h"
FTCharmap::FTCharmap( FT_Face face)
: ftFace( face),
err(0)
{
// Check that the default is valid
if( !face->charmap)
{
FT_Set_Charmap( ftFace, ftFace->charmaps[0]);
}
ftEncoding = face->charmap->encoding;
}
FTCharmap::~FTCharmap()
{
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;
}
bool FTCharmap::CharMap( FT_UShort platform, FT_UShort encoding)
{
FT_CharMap found = 0;
FT_CharMap charmap;
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( !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;
}
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;
}
}

View File

@ -1,124 +0,0 @@
#ifndef __FTCharmap__
#define __FTCharmap__
#include "FTGL.h"
#include <map>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
//#include "FTGL.h"
using namespace std;
/**
* FTCharmap takes care of specifying the encodeing for a font and mapping
* character codes to glyph indices.
*
* It doesn't preprocess all indices, only on as needed basis. This may seem
* like a performance penalty but it is quicker than using the 'raw'
* freetype calls and will save significant amounts of memory when dealing
* with uncode encoding
*
*/
class FTGL_EXPORT FTCharmap
{
public:
/**
* Constructor
*/
FTCharmap( FT_Face ftFace);
/**
* 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);
/**
* 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 );
/**
* 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__

View File

@ -1,113 +0,0 @@
#include "FTFace.h"
#include "FTLibrary.h"
#include "FTCharmap.h"
#include "FTGL.h"
FTFace::FTFace():
charMap(0),
ftFace(0),
ftGlyph(0),
numCharMaps(0),
numGlyphs(0),
err(0)
{
kernAdvance.x = 0;
kernAdvance.y = 0;
}
FTFace::~FTFace()
{
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);
if( err)
{
delete ftFace;
ftFace = 0;
return false;
}
else
{
charMap = new FTCharmap( *ftFace);
return true;
}
}
void FTFace::Close()
{
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;
}
bool FTFace::CharMap( FT_Encoding encoding)
{
return charMap->CharMap( encoding);
}
unsigned int FTFace::CharIndex( unsigned int index) const
{
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;
}
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;
}
}

View File

@ -1,147 +0,0 @@
#ifndef __FTFace__
#define __FTFace__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTSize.h"
class FTCharmap;
/**
* FTFace class provides an abstraction layer for the Freetype Face.
*
* @see "Freetype 2 Documentation - 2.0.4"
*
*/
class FTGL_EXPORT FTFace
{
public:
/**
* Default Constructor
*/
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);
/**
* 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);
/**
* 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);
/**
* 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;}
/**
* 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;
/**
* Temporary variable to hold a glyph
*/
FT_Glyph ftGlyph;
/**
* The number of character maps in this face.
*/
int numCharMaps;
/**
* 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;
};
#endif // __FTFace__

View File

@ -1,228 +0,0 @@
#include "FTFace.h"
#include "FTFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include <osg/DisplaySettings>
// mrn@changes
FTFont::FTFont():
face(),
numFaces(0),
numGlyphs(0),
err(0)
{
_contextGlyphList.resize(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),NULL);
pen.x = 0;
pen.y = 0;
}
FTFont::~FTFont()
{
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;
}
}
// mrn@changes
void FTFont::Close()
{
GlyphContextContainer::iterator itr;
for(itr=_contextGlyphList.begin();itr!=_contextGlyphList.end();itr++)
delete *itr;
_contextGlyphList.clear();
}
// mrn@changes
bool FTFont::FaceSize( const unsigned int size, const unsigned int res , unsigned int renderContext)
{
charSize = face.Size( size, res);
// check the context
if (_contextGlyphList.size() <= renderContext)
_contextGlyphList.resize(renderContext,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;
}
int FTFont::Ascender() const
{
return charSize.Ascender();
}
int FTFont::Descender() const
{
return charSize.Descender();
}
// mrn@changes
float FTFont::Advance( const wchar_t* string)
{
// all are the same, a bit a hack
FTGlyphContainer* glyphList=getValidGlypContainer();
if (!glyphList) return 1.0f;
const wchar_t* c = string; // wchar_t IS unsigned?
float width = 0;
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
return width;
}
// mrn@changes
float FTFont::Advance( const char* string)
{
// all are the same, a bit a hack
FTGlyphContainer* glyphList=getValidGlypContainer();
if (!glyphList) return 1.0f;
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
float width = 0;
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
++c;
}
return width;
}
float FTFont::Advance( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last)
{
// all are the same, a bit a hack
FTGlyphContainer* glyphList=getValidGlypContainer();
if (!glyphList) return 1.0f;
float width = 0;
for (std::vector<int>::const_iterator c = first;
c!=last;
++c)
{
width += glyphList->Advance( *c, *(c + 1));
}
return width;
}
// mrn@changes
void FTFont::render( const char* string , unsigned int renderContext)
{
FTGlyphContainer* glyphList=_contextGlyphList[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;
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
++c;
}
}
// mrn@changes
void FTFont::render( const wchar_t* string , unsigned int renderContext)
{
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
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;
}
}
void FTFont::render( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last,
unsigned int renderContext)
{
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
for (std::vector<int>::const_iterator c = first;
c!=last;
++c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
}
}

View File

@ -1,223 +0,0 @@
#ifndef __FTFont__
#define __FTFont__
#include <string>
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include "FTFace.h"
#include "FTGL.h"
// mrn@changes
#include <vector>
class FTGlyphContainer;
using namespace std;
/**
* FTFont is the public interface for the FTGL library.
*
* Specific font classes are derived from this class. It uses the helper
* classes FTFace and FTSize to access the Freetype library. This class
* is abstract and deriving classes must implement the protected
* <code>MakeGlyphList</code> function to build a glyphList with the
* appropriate glyph type.
*
* @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
*/
// 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);
/**
* 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);
/**
* Gets the advance width for a string.
*
* @param string a char string
* @return advance width
*/
float Advance( const char* string);
/**
* Gets the advance width for a string.
*
* @param string a pointer to an array of decoded unicode characters
* @return advance width
*/
float Advance( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last);
/**
* 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 unicode string to be output.
*/
// mrn@changes
virtual void render( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last,
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);
/**
* 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
*/
// 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;
/**
* 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;
FTGlyphContainer* getValidGlypContainer()
{
for(GlyphContextContainer::iterator itr=_contextGlyphList.begin();
itr!=_contextGlyphList.end();
++itr)
{
if ((*itr)!=0) return *itr;
}
return 0;
}
private:
};
#endif // __FTFont__

View File

@ -1,112 +0,0 @@
#ifndef __FTGL__
#define __FTGL__
#ifdef _MSC_VER
// stl stuff
#pragma warning( disable : 4244 )
#pragma warning( disable : 4251 )
#pragma warning( disable : 4275 )
#pragma warning( disable : 4786 )
#endif
#ifndef WIN32
// non windows, doesn't require nonesense as seen below :-)
#ifndef __gl_h_
#ifdef __DARWIN_OSX__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#endif
// required for compatibility with glext.h style function definitions of
// OpenGL extensions, such as in src/osg/Point.cpp.
#ifndef APIENTRY
#define APIENTRY
#endif
#else
#if defined(__CYGWIN__) || defined(__MINGW32__)
# ifndef APIENTRY
# define GLUT_APIENTRY_DEFINED
# define APIENTRY __stdcall
# endif
// XXX This is from Win32's <winnt.h>
# ifndef CALLBACK
# define CALLBACK __stdcall
# endif
#else // ! __CYGWIN__
// Under windows avoid including <windows.h>
// to avoid name space pollution, but Win32's <GL/gl.h>
// needs APIENTRY and WINGDIAPI defined properly.
// F
# if 0
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# else
// XXX This is from Win32's <windef.h>
# ifndef APIENTRY
# define GLUT_APIENTRY_DEFINED
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
# define APIENTRY __stdcall
# else
# define APIENTRY
# endif
# endif
// XXX This is from Win32's <winnt.h>
# ifndef CALLBACK
# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS)
# define CALLBACK __stdcall
# else
# define CALLBACK
# endif
# endif
#endif // __CYGWIN__
// XXX This is from Win32's <wingdi.h> and <winnt.h>
# ifndef WINGDIAPI
# define GLUT_WINGDIAPI_DEFINED
# define WINGDIAPI __declspec(dllimport)
# endif
// XXX This is from Win32's <ctype.h>
# ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
# define _WCHAR_T_DEFINED
# endif
# endif
#ifndef __gl_h_
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#endif
// lifted from glext.h, to remove dependancy on glext.h
#ifndef GL_TEXTURE_2D_BINDING_EXT
#define GL_TEXTURE_2D_BINDING_EXT 0x8069
#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 */
#else
# define FTGL_EXPORT
#endif
#endif // __FTGL__

View File

@ -1,97 +0,0 @@
#include "FTGLBitmapFont.h"
#include "FTGlyphContainer.h"
#include "FTBitmapGlyph.h"
FTGLBitmapFont::FTGLBitmapFont()
{}
FTGLBitmapFont::~FTGLBitmapFont()
{}
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
// mrn@changes
bool FTGLBitmapFont::MakeGlyphList(unsigned int renderContext)
{
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)
{
FTBitmapGlyph* tempGlyph = new FTBitmapGlyph( *ftGlyph);
glyphList->Add( tempGlyph);
}
else
{
err = face.Error();
}
}
return !err;
}
// 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);
#if (FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR>=1)
glPixelStorei( GL_UNPACK_ALIGNMENT, 2);
#else
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
#endif
FTFont::render( string,renderContext);
glPopClientAttrib();
}
// 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);
#if (FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR>=1)
glPixelStorei( GL_UNPACK_ALIGNMENT, 2);
#else
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
#endif
FTFont::render( string,renderContext);
glPopClientAttrib();
}
// mrn@changes
void FTGLBitmapFont::render( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last,
unsigned int renderContext)
{
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
#if (FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR>=1)
glPixelStorei( GL_UNPACK_ALIGNMENT, 2);
#else
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
#endif
FTFont::render( first,last,renderContext);
glPopClientAttrib();
}

View File

@ -1,68 +0,0 @@
#ifndef __FTGLBitmapFont__
#define __FTGLBitmapFont__
#include "FTGL.h"
#include "FTFont.h"
class FTBitmapGlyph;
/**
* FTGLBitmapFont is a specialisation of the FTFont class for handling
* Bitmap fonts
*
* @see FTFont
*/
class FTGL_EXPORT FTGLBitmapFont : public FTFont
{
public:
/**
* Constructor
*/
FTGLBitmapFont();
/**
* 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.
*/
// mrn@changes
void render( const wchar_t* string, unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string unicode string to be output.
*/
// mrn@changes
void render( std::vector<int>::const_iterator first,
std::vector<int>::const_iterator last,
unsigned int renderContext=0);
// 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__

View File

@ -1,70 +0,0 @@
#include "FTGLOutlineFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTOutlineGlyph.h"
FTGLOutlineFont::FTGLOutlineFont()
{}
FTGLOutlineFont::~FTGLOutlineFont()
{}
// mrn@changes
bool FTGLOutlineFont::MakeGlyphList( unsigned int renderContext)
{
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;
}
// 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,renderContext);
glPopAttrib();
}
// 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,renderContext);
glPopAttrib();
}

View File

@ -1,59 +0,0 @@
#ifndef __FTGLOutlineFont__
#define __FTGLOutlineFont__
#include "FTGL.h"
#include "FTFont.h"
class FTOutlineGlyph;
/**
* FTGLOutlineFont is a specialisation of the FTFont class for handling
* Vector Outline fonts
*
* @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.
*/
// 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
*/
// mrn@changes
virtual bool MakeGlyphList( unsigned int renderContext=0);
};
#endif // __FTGLOutlineFont__

View File

@ -1,68 +0,0 @@
#include "FTGLPixmapFont.h"
#include "FTGlyphContainer.h"
#include "FTPixmapGlyph.h"
FTGLPixmapFont::FTGLPixmapFont()
{}
FTGLPixmapFont::~FTGLPixmapFont()
{}
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
// mrn@changes
bool FTGLPixmapFont::MakeGlyphList(unsigned int renderContext)
{
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,unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
// Why is this modifying state here? - DB
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FTFont::render( string,renderContext);
glPopAttrib();
}
void FTGLPixmapFont::render( const wchar_t* string,unsigned int renderContext)
{
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
// Why is this modifying state here? - DB
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
FTFont::render( string,renderContext);
glPopAttrib();
}

View File

@ -1,61 +0,0 @@
#ifndef __FTGLPixmapFont__
#define __FTGLPixmapFont__
#include "FTGL.h"
#include "FTFont.h"
class FTPixmapGlyph;
/**
* FTGLPixmapFont is a specialisation of the FTFont class for handling
* Pixmap (Grey Scale) fonts
*
* @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.
*/
// 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
*/
// mrn@changes
virtual bool MakeGlyphList(unsigned int renderContext=0);
};
#endif // __FTGLPixmapFont__

View File

@ -1,37 +0,0 @@
#include "FTGLPolygonFont.h"
#include "FTGlyphContainer.h"
#include "FTGL.h"
#include "FTPolyGlyph.h"
FTGLPolygonFont::FTGLPolygonFont()
{}
FTGLPolygonFont::~FTGLPolygonFont()
{}
// mrn@changes
bool FTGLPolygonFont::MakeGlyphList( unsigned int renderContext)
{
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,44 +0,0 @@
#ifndef __FTGLPolygonFont__
#define __FTGLPolygonFont__
#include "FTGL.h"
#include "FTFont.h"
class FTPolyGlyph;
/**
* FTGLPolygonFont is a specialisation of the FTFont class for handling
* tesselated Polygon Mesh fonts
*
* @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
*/
// mrn@changes
virtual bool MakeGlyphList( unsigned int renderContext=0);
};
#endif // __FTGLPolygonFont__

View File

@ -1,242 +0,0 @@
#include "FTGLTextureFont.h"
#include "FTGlyphContainer.h"
#include "FTTextureGlyph.h"
#include <osg/DisplaySettings>
inline GLuint NextPowerOf2( GLuint in)
{
in -= 1;
in |= in >> 16;
in |= in >> 8;
in |= in >> 4;
in |= in >> 2;
in |= in >> 1;
return in + 1;
}
FTGLTextureFont::FTGLTextureFont()
: maxTextSize(0),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
{
glContextTextureID.resize(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0);
}
FTGLTextureFont::FTGLTextureFont(int textureSize)
: maxTextSize(textureSize),
textureWidth(0),
textureHeight(0),
numTextures(1),
textMem(0),
glyphHeight(0),
glyphWidth(0),
padding(1)
{
glContextTextureID.resize(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts(),0);
}
FTGLTextureFont::~FTGLTextureFont()
{
ContextTextureId::iterator itr;
for(itr=glContextTextureID.begin();itr != glContextTextureID.end(); itr++)
{
if (*itr)
{
glDeleteTextures( numTextures, (const GLuint*)*itr);
delete [] *itr;
}
}
}
// mrn@changes
bool FTGLTextureFont::MakeGlyphList(unsigned int renderContext)
{
// FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
// check the context
if (glContextTextureID.size() <= renderContext)
glContextTextureID.resize(renderContext,0);
unsigned long* glTextureID=glContextTextureID[renderContext];
if(glTextureID)
return true;
else
{
glTextureID= new unsigned long[16];
memset(glTextureID,0,sizeof(unsigned long)*16);
glContextTextureID[renderContext]=glTextureID;
}
if( !maxTextSize)
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
glyphHeight = ( charSize.Height()) + padding;
glyphWidth = ( charSize.Width()) + padding;
GetSize();
GLuint totalMem;
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;
}
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);
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, 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);
}
// 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();
}
// 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,164 +0,0 @@
#ifndef __FTGLTextureFont__
#define __FTGLTextureFont__
#include "FTGL.h"
#include "FTFont.h"
class FTTextureGlyph;
/**
* FTGLTextureFont is a specialisation of the FTFont class for handling
* Texture mapped fonts
*
* @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.
*/
// 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
*/
// 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();
/**
* 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 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;
};
#endif // __FTGLTextureFont__

View File

@ -1,23 +0,0 @@
#include "FTGlyph.h"
#include <iostream>
#include <string.h>
FTGlyph::FTGlyph()
: advance(0),
err(0)
{
//cout << "**** FTGlyph() size = "<<sizeof(FTGlyph)<<endl;
memset(this,0,sizeof(FTGlyph));
advance=0;
err=0;
pos.x = 0;
pos.y = 0;
}
FTGlyph::~FTGlyph()
{}

View File

@ -1,79 +0,0 @@
#ifndef __FTGlyph__
#define __FTGlyph__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
//#include "FTGL.h"
/**
* FTGlyph is the base class for FTGL glyphs.
*
* It provides the interface between Freetype glyphs and their openGL
* renderable counterparts. This is an abstract class and derived classes
* must implement the <code>render</code> function.
*
* @see FTGlyphContainer
*
*/
class FTGL_EXPORT FTGlyph
{
public:
/**
* Constructor
*/
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;
/**
* 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:
};
#endif // __FTGlyph__

View File

@ -1,67 +0,0 @@
#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)
{
glyphs.reserve( g);
}
FTGlyphContainer::~FTGlyphContainer()
{
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;
}
float FTGlyphContainer::Advance( unsigned int index, unsigned int 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;
}
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 = static_cast<FT_Pos>(advance) + kernAdvance.x;
// kernAdvance.y = advance.y + kernAdvance.y;
return kernAdvance;
}

View File

@ -1,116 +0,0 @@
#ifndef __FTGlyphContainer__
#define __FTGlyphContainer__
#include "FTGL.h"
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
//#include "FTGL.h"
class FTFace;
class FTGlyph;
using namespace std;
/**
* FTGlyphContainer holds the post processed FTGlyph objects.
*
* @see FTGlyph
*/
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);
/**
* Destructor
*/
virtual ~FTGlyphContainer();
/**
* 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;}
private:
/**
* A flag to indicate preprocessing of glyphs. Not used.
*/
bool preCache;
/**
* How meny glyphs are stored in this container
*/
int numGlyphs;
/**
* The current Freetype face
*/
FTFace* face;
/**
* The kerning vector for the current pair of glyphs
*/
FT_Vector kernAdvance;
/**
* 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
/**
* Current error code. Zero means no error.
*/
FT_Error err;
};
#endif // __FTGlyphContainer__

View File

@ -1,64 +0,0 @@
#include "FTLibrary.h"
FTLibrary& FTLibrary::Instance()
{
static FTLibrary ftlib;
return ftlib;
}
FTLibrary::~FTLibrary()
{
if( lib != 0)
{
FT_Done_FreeType( *lib);
delete lib;
lib= 0;
}
// if( manager != 0)
// {
// FTC_Manager_Done( manager );
//
// delete manager;
// manager= 0;
// }
}
FTLibrary::FTLibrary()
: lib(0),
err(0)
{
Init();
}
bool FTLibrary::Init()
{
if( lib != 0 )
return true;
lib = new FT_Library;
err = FT_Init_FreeType( lib);
if( err)
{
delete lib;
lib = 0;
return false;
}
// FTC_Manager* manager;
//
// if( FTC_Manager_New( lib, 0, 0, 0, my_face_requester, 0, manager )
// {
// delete manager;
// manager= 0;
// return false;
// }
return true;
}

View File

@ -1,95 +0,0 @@
#ifndef __FTLibrary__
#define __FTLibrary__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
//#include FT_CACHE_H
/**
* FTLibrary class is the global accessor for the Freetype library.
*
* This class encapsulates the Freetype Library. This is a singleton class
* and ensures that only one FT_Library is in existence at any one time.
* All constructors are private therefore clients cannot create or
* instantiate this class themselves and must access it's methods via the
* static <code>FTLibrary::Instance()</code> function.
*
* Just because this class returns a valid <code>FTLibrary</code> object
* doesn't mean that the Freetype Library has been successfully initialised.
* Clients should check for errors. You can initialse the library AND check
* for errors using the following code...
* <code>err = FTLibrary::Instance().Error();</code>
*
* @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();
/**
* 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;
};
#endif // __FTLibrary__

View File

@ -1,99 +0,0 @@
#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)
{
if( ft_glyph_format_outline != glyph->format)
{
FT_Done_Glyph( glyph);
return;
}
advance = glyph->advance.x >> 16;
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
if (numContours==0)
{
FT_Done_Glyph( glyph);
return;
}
contourLength = new int[ numContours];
memset(contourLength,0,sizeof(int)*numContours);
for( int cn = 0; cn < numContours; ++cn)
{
contourLength[cn] = vectoriser->contourSize( cn);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
for( int cp = 0; cp < numPoints * 3; ++cp)
{
data[cp]=0.0;
}
vectoriser->MakeOutline( data);
vectoriser=0;
if ( ( numContours < 1) || ( numPoints < 3))
{
FT_Done_Glyph( glyph);
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();
// discard glyph image (bitmap or not)
FT_Done_Glyph( glyph); // Why does this have to be HERE
}
FTOutlineGlyph::~FTOutlineGlyph()
{
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;
}

View File

@ -1,87 +0,0 @@
#ifndef __FTOutlineGlyph__
#define __FTOutlineGlyph__
#include <osg/ref_ptr>
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
#include "FTVectoriser.h"
/**
* FTOutlineGlyph is a specialisation of FTGlyph for creating outlines.
*
* @see FTGlyphContainer
* @see FTVectoriser
*
*/
class FTGL_EXPORT FTOutlineGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTOutlineGlyph( FT_Glyph glyph);
/**
* 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:
FTOutlineGlyph() {}
FTOutlineGlyph(const FTOutlineGlyph&):FTGlyph() {}
/**
* An object that helps convert freetype outlines into point
* data
*/
osg::ref_ptr<FTVectoriser> vectoriser;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
};
#endif // __FTOutlineGlyph__

View File

@ -1,99 +0,0 @@
#include "FTPixmapGlyph.h"
#include "FTGL.h"
FTPixmapGlyph::FTPixmapGlyph( FT_Glyph glyph)
: 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;
}
advance = glyph->advance.x >> 16;
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;
if (srcWidth*srcHeight==0)
{
FT_Done_Glyph( glyph );
return;
}
numGreys = source->num_grays;
pos.x = bitmap->left;
pos.y = srcHeight - bitmap->top;
// FIXME What about dest alignment?
destWidth = srcWidth;
destHeight = srcHeight;
data = new unsigned char[destWidth * destHeight * 4];
// Get the current glColor.
float ftglColour[4] = { 1.0, 1.0, 1.0, 1.0 };
// What if the current color is black... Nah.
//glGetFloatv( GL_CURRENT_COLOR, ftglColour);
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 = srcHeight;
// discard glyph image (bitmap or not)
// Is this the right place to do this?
FT_Done_Glyph( glyph );
}
FTPixmapGlyph::~FTPixmapGlyph()
{
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);
glPixelStorei( GL_UNPACK_ROW_LENGTH, destWidth);
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);
glPopClientAttrib();
}
return advance;
}

View File

@ -1,70 +0,0 @@
#ifndef __FTPixmapGlyph__
#define __FTPixmapGlyph__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
/**
* FTPixmapGlyph is a specialisation of FTGlyph for creating pixmaps.
*
* @see FTGlyphContainer
*
*/
class FTGL_EXPORT FTPixmapGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPixmapGlyph( FT_Glyph glyph);
/**
* 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
//
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;
/**
* Pointer to the 'image' data
*/
unsigned char* data;
};
#endif // __FTPixmapGlyph__

View File

@ -1,185 +0,0 @@
#include "FTPolyGlyph.h"
#include "FTVectoriser.h"
#ifndef CALLBACK
#define CALLBACK
#endif
void CALLBACK ftglError( GLenum /*errCode*/)
{
// const GLubyte* estring;
// estring = gluErrorString( errCode);
// fprintf( stderr, "ERROR : %s\n", estring);
// exit(1);
}
void CALLBACK ftglVertex( void* data)
{
glVertex3dv( (double*)data);
}
void CALLBACK ftglBegin( GLenum type)
{
glBegin( type);
}
void CALLBACK ftglEnd()
{
glEnd();
}
// this static vector is to keep track of memory allocated by the combine
// callback below, so that it can be later deleted. This approach does
// assume that the Tesselate method is single threaded.
typedef std::vector<double*> CreatedVertices;
static CreatedVertices s_createdVertices;
void CALLBACK ftglCombine( GLdouble coords[3], void* /*vertex_data*/[4], GLfloat /*weight*/[4], void** outData)
{
double* vertex = new double[3]; // FIXME MEM LEAK
s_createdVertices.push_back(vertex);
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
*outData = vertex;
}
FTPolyGlyph::FTPolyGlyph( FT_Glyph glyph)
: FTGlyph(),
vectoriser(0),
numPoints(0),
numContours(0),
contourFlag(0),
contourLength(0),
data(0),
glList(0)
{
if( ft_glyph_format_outline != glyph->format)
{
FT_Done_Glyph( glyph );
return;
}
advance = glyph->advance.x >> 16;
vectoriser = new FTVectoriser( glyph);
vectoriser->Process();
numContours = vectoriser->contours();
if (numContours==0) return;
contourLength = new int[ numContours];
memset(contourLength,0,sizeof(int)*numContours);
for( int c = 0; c < numContours; ++c)
{
contourLength[c] = vectoriser->contourSize( c);
}
numPoints = vectoriser->points();
data = new double[ numPoints * 3];
// initalize memory.
for( int pc=0;pc<numPoints*3;++pc) data[pc]=0.0;
// FIXME MakeMesh
vectoriser->MakeOutline( data);
contourFlag = vectoriser->ContourFlag();
vectoriser=0; // delete it, using ref_ptr.
if ( ( numContours < 1) || ( numPoints < 3))
{
FT_Done_Glyph( glyph );
return;
}
Tesselate();
// 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();
gluDeleteTess( tobj);
// clean up the vertices create in the combine callback.
for(CreatedVertices::iterator itr=s_createdVertices.begin();
itr!=s_createdVertices.end();
++itr)
{
delete [] (*itr);
}
s_createdVertices.clear();
}
FTPolyGlyph::~FTPolyGlyph()
{
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;
}

View File

@ -1,94 +0,0 @@
#ifndef __FTPolyGlyph__
#define __FTPolyGlyph__
#include <osg/ref_ptr>
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
#include "FTVectoriser.h"
/**
* FTPolyGlyph is a specialisation of FTGlyph for creating tessellated
* polygon glyphs.
*
* @see FTGlyphContainer
* @see FTVectoriser
*
*/
class FTGL_EXPORT FTPolyGlyph : public FTGlyph
{
public:
/**
* Constructor
*
* @param glyph The Freetype glyph to be processed
*/
FTPolyGlyph( FT_Glyph glyph);
/**
* 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
*/
osg::ref_ptr<FTVectoriser> vectoriser;
/**
* The total number of points in the Freetype outline
*/
int numPoints;
/**
* The totals number of contours in the Freetype outline
*/
int numContours;
/**
* An flag indicating the tesselation rules for this glyph
*/
int contourFlag;
/**
* An array containing the number of points in each outline
*/
int* contourLength;
/**
* Pointer to the point data
*/
double* data;
/**
* OpenGL display list
*/
int glList;
};
#endif // __FTPolyGlyph__

View File

@ -1,91 +0,0 @@
#include "FTSize.h"
#include "FTGL.h"
FTSize::FTSize()
: ftFace(0),
ftSize(0),
size(0),
err(0)
{}
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;
}
int FTSize::Ascender() const
{
return ftSize->metrics.ascender >> 6;
}
int FTSize::Descender() const
{
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
}
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;
}
}
int FTSize::Underline() const
{
return 0;
}

View File

@ -1,120 +0,0 @@
#ifndef __FTSize__
#define __FTSize__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
/**
* FTSize class provides an abstraction layer for the Freetype Size.
*
* @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;
/**
* 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__

View File

@ -1,90 +0,0 @@
#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(),
activeTextureID(0),
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;
}
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;
numGreys = source->num_grays;
advance = glyph->advance.x >> 16;
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);
}
}
// 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);
}
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();
return advance;
}

View File

@ -1,96 +0,0 @@
#ifndef __FTTextureGlyph__
#define __FTTextureGlyph__
#include "FTGL.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
/**
* FTTextureGlyph is a specialisation of FTGlyph for creating texture
* glyphs.
*
* @see FTGlyphContainer
*
*/
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);
/**
* 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;
/**
* 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 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__

View File

@ -1,240 +0,0 @@
#include "FTVectoriser.h"
#include "FTGL.h"
FTContour::FTContour()
: kMAXPOINTS( 1000)
{
pointList.reserve( kMAXPOINTS);
}
FTContour::~FTContour()
{
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);
}
}
FTVectoriser::FTVectoriser( FT_Glyph glyph)
: contour(0),
contourFlag(0),
kBSTEPSIZE( 0.2f)
{
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
ftOutline = outline->outline;
contourList.reserve( ftOutline.n_contours);
for(int i=0;i<4;++i)
{
for(int j=0;j<4;++j)
{
bValues[i][j][0]=0.0f;
bValues[i][j][1]=0.0f;
}
ctrlPtArray[i][0]=0.0f;
ctrlPtArray[i][1]=0.0f;
}
}
FTVectoriser::~FTVectoriser()
{
for( int c = 0; c < contours(); ++c)
{
delete contourList[c];
}
contourList.clear();
}
int FTVectoriser::points()
{
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];
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 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;
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;
}
// De Casteljau algorithm contributed by Jed Soane
void FTVectoriser::deCasteljau( const float t, const int n)
{
//Calculating successive b(i)'s using de Casteljau algorithm.
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];
}
//Specify next vertex to be included on curve
contour->AddPoint( bValues[n][0][0], bValues[n][0][1]);
}
// De Casteljau algorithm contributed by Jed Soane
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];
}
float t; //parameter for curve point calc. [0.0, 1.0]
for( int m = 0; m <= ( 1 / kBSTEPSIZE); m++)
{
t = m * kBSTEPSIZE;
deCasteljau( t, n); //calls to evaluate point on curve att.
}
}
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;
}
}
}

View File

@ -1,273 +0,0 @@
#ifndef __FTVectoriser__
#define __FTVectoriser__
#include "FTGL.h"
#include <osg/Referenced>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include "FTGlyph.h"
using namespace std;
/**
* ftPoint class is a basic 3 dimensional point for holding outline font
* point data.
*
* @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));
}
/**
* 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:
};
/**
* FTContour class is a container of points that describe an outline
* point data.
*
* @see FTOutlineGlyph
* @see FTPolyGlyph
* @see ftPoint
*
*/
class FTGL_EXPORT 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();}
/**
* 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;
};
/**
* 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
*
*/
class FTGL_EXPORT FTVectoriser : public osg::Referenced
{
public:
/**
* Constructor
*
* @param glyph The freetype glyph to be processed
*/
FTVectoriser( FT_Glyph glyph);
/**
* Destructor
*/
virtual ~FTVectoriser();
/**
* 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);
/**
* 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 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);
/**
* 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
*/
void evaluateCurve( const int n);
/**
* 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 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__

View File

@ -1,393 +1,282 @@
/* --------------------------------------------------------------------------
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* openscenegraph textLib / FTGL
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* ----------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgText/Font>
#include <osgText/EncodedText>
#include <osg/State>
#include <osg/Notify>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osg/GLU>
#include "FTFace.h"
#include "FTGLBitmapFont.h"
#include "FTGLPixmapFont.h"
#include "FTGLOutlineFont.h"
#include "FTGLPolygonFont.h"
#include "FTGLTextureFont.h"
using namespace osg;
using namespace osgText;
std::string findFontFile(const std::string& str)
osgText::Font* osgText::readFontFile(const std::string& filename)
{
// try looking in OSGFILEPATH etc first for fonts.
std::string filename = osgDB::findDataFile(str);
if (!filename.empty()) return std::string(filename);
osg::Object* object = osgDB::readObjectFile(filename);
// if the object is a font then return it.
osgText::Font* font = dynamic_cast<osgText::Font*>(object);
if (font) return font;
// otherwise if the object has zero references then delete it by doing another unref().
if (object && object->referenceCount()==0) object->unref();
return 0;
}
static osgDB::FilePathList s_FontFilePath;
static bool initialized = false;
if (!initialized)
Font::Font():
_width(16),
_height(16)
{
}
Font::~Font()
{
}
void Font::addGlyph(unsigned int charcode, Glyph* glyph)
{
_glyphMap[charcode]=glyph;
int posX=0,posY=0;
GlyphTexture* glyphTexture = 0;
for(GlyphTextureList::iterator itr=_glyphTextureList.begin();
itr!=_glyphTextureList.end() && !glyphTexture;
++itr)
{
initialized = true;
#if defined(WIN32)
osgDB::Registry::convertStringPathIntoFilePathList(
".;C:/winnt/fonts;C:/windows/fonts",
s_FontFilePath);
char *ptr;
if ((ptr = getenv( "windir" )))
{
s_FontFilePath.push_back(ptr);
}
#else
osgDB::Registry::convertStringPathIntoFilePathList(
".:/usr/share/fonts/ttf:/usr/share/fonts/ttf/western:/usr/share/fonts/ttf/decoratives",
s_FontFilePath);
#endif
if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get();
}
filename = osgDB::findFileInPath(str,s_FontFilePath);
if (!filename.empty()) return filename;
osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;
return std::string();
}
///////////////////////////////////////////////////////////////////////////////
// Font
Font::
Font()
{
_init=false;
_font=NULL;
_created=false;
_pointSize=14;
_textureSize=0;
_res=72;
}
bool Font::
init(const std::string& font)
{
_font=NULL;
_created=false;
open(font);
if(_font!=NULL)
return true;
else
return false;
}
Font::
~Font()
{
clear();
}
void Font::copyAndInvalidate(Font &dest)
{
// delete destination's font object
delete dest._font;
// copy local data to destination object
dest._init = _init;
dest._created = _created;
dest._font = _font;
dest._fontName = _fontName;
dest._pointSize = _pointSize;
dest._res = _res;
dest._textureSize = _textureSize;
// invalidate this object
_init = false;
_created = false;
_font = 0;
_fontName = std::string();
}
bool Font::
open(const std::string& font)
{
clear();
std::string filename = findFontFile(font);
if (filename.empty()) return false;
_font=createFontObj();
if( _font!=NULL && _font->Open(filename.c_str()) )
if (!glyphTexture)
{
_init=true;
_fontName=font;
//std::cout<<"Creating new GlyphTexture & StateSet"<<std::endl;
osg::StateSet* stateset = new osg::StateSet;
_stateSetList.push_back(stateset);
glyphTexture = new GlyphTexture;
// reserve enough space for the glyphs.
glyphTexture->setTextureSize(256,256);
//glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
glyphTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR);
//glyphTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);
//glyphTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
glyphTexture->setMaxAnisotropy(8);
_glyphTextureList.push_back(glyphTexture);
glyphTexture->setStateSet(stateset);
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(0,glyphTexture,osg::StateAttribute::ON);
if (!glyphTexture->getSpaceForGlyph(glyph,posX,posY))
{
osg::notify(osg::WARN)<<"Warning: unable to allocate texture big enough for glyph"<<std::endl;
return;
}
}
// add the glyph into the texture.
glyphTexture->addGlyph(glyph,posX,posY);
}
Font::GlyphTexture::GlyphTexture():
_stateset(0),
_usedY(0),
_partUsedX(0),
_partUsedY(0)
{
}
Font::GlyphTexture::~GlyphTexture()
{
}
bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
{
int margin = 2;
int width = glyph->s()+2*margin;
int height = glyph->t()+2*margin;
// first check box (_partUsedX,_usedY) to (width,height)
if (width <= (getTextureWidth()-_partUsedX) &&
height <= (getTextureHeight()-_usedY))
{
// can fit in existing row.
// record the position in which the texture will be stored.
posX = _partUsedX+margin;
posY = _usedY+margin;
// move used markers on.
_partUsedX += width;
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height;
return true;
}
else
return false;
}
bool Font::open(const char* font)
{
return open(std::string(font));
}
bool Font::
create(osg::State& state,int pointSize,unsigned int res)
{
_pointSize=pointSize;
_res=res;
return create(state);
}
bool Font::create(osg::State& state)
{
if(_init)
// start an new row.
if (width <= getTextureWidth() &&
height <= (getTextureHeight()-_partUsedY))
{
if(_font->Created(state.getContextID()))
return true;
// can fit next row.
_partUsedX = 0;
_usedY = _partUsedY;
if(_font->FaceSize(_pointSize,_res,state.getContextID()))
posX = _partUsedX+margin;
posY = _usedY+margin;
// move used markers on.
_partUsedX += width;
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height;
return true;
}
// doesn't fit into glyph.
return false;
}
void Font::GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
{
_glyphs.push_back(glyph);
for(unsigned int i=0;i<_glyphsToSubload.size();++i)
{
_glyphsToSubload[i].push_back(glyph);
}
// set up the details of where to place glyph's image in the texture.
glyph->setTexture(this);
glyph->setTexturePosition(posX,posY);
glyph->setMinTexCoord(osg::Vec2((float)posX/((float)getTextureWidth()-1.0f),(float)posY/((float)getTextureHeight()-1.0f)));
glyph->setMaxTexCoord(osg::Vec2((float)(posX+glyph->s())/((float)getTextureWidth()-1.0f),(float)(posY+glyph->t())/((float)getTextureHeight()-1.0f)));
}
void Font::GlyphTexture::apply(osg::State& state) const
{
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
const unsigned int contextID = state.getContextID();
if (contextID>=_glyphsToSubload.size())
{
// graphics context is beyond the number of glyphsToSubloads, so
// we must now copy the glyph list across, this is a potential
// threading issue though is multiple applies are happening the
// same time on this object - to avoid this condition number of
// graphics contexts should be set before create text.
for(unsigned int i=_glyphsToSubload.size();i<=contextID;++i)
{
_created=true;
return true;
_glyphsToSubload[i] = _glyphs;
}
else
return false;
}
// get the globj for the current contextID.
GLuint& handle = getTextureObject(contextID);
if (handle == 0)
{
// being bound for the first time, need to allocate the texture
glGenTextures( 1L, (GLuint *)&handle );
glBindTexture( GL_TEXTURE_2D, handle );
applyTexParameters(GL_TEXTURE_2D,state);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
// allocate the texture memory.
glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
getTextureWidth(), getTextureHeight(), 0,
GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE,
0 );
}
else
return false;
}
{
// reuse texture by binding.
glBindTexture( GL_TEXTURE_2D, handle );
if (getTextureParameterDirty(contextID))
applyTexParameters(GL_TEXTURE_2D,state);
void Font::output(osg::State& state, const EncodedText* text) const
{
if(_created)
_font->render(text->begin(),text->end(),state.getContextID());
}
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS,GL_TRUE);
// now subload the glyphs that are outstanding for this graphics context.
GlyphList& glyphsWereSubloading = _glyphsToSubload[contextID];
if (!glyphsWereSubloading.empty())
{
for(GlyphList::iterator itr=glyphsWereSubloading.begin();
itr!=glyphsWereSubloading.end();
++itr)
{
(*itr)->subload();
}
// clear the list since we have now subloaded them.
glyphsWereSubloading.clear();
}
else
{
// ahhhh, this is bit doddy, the draw is potentially
// modifying the text object, this isn't thread safe.
Font* this_non_const = const_cast<Font*>(this);
this_non_const->create(state,_pointSize);
//std::cout << "no need to subload "<<std::endl;
}
}
void Font::clear()
Font::Glyph::Glyph() {}
Font::Glyph::~Glyph() {}
void Font::Glyph::subload()
{
_init=false;
if(_font)
GLenum errorNo = glGetError();
if (errorNo!=GL_NO_ERROR)
{
delete _font;
_font=NULL;
osg::notify(osg::WARN)<<"before: detected OpenGL error '"<<gluErrorString(errorNo)<<std::endl;
}
_fontName="";
}
float Font::
getWidth(const EncodedText* text) const
{
if(_init && _created && text)
return _font->Advance(text->begin(),text->end());
else
return -1;
}
int Font::
getHeight() const
{
if(_init && _created)
return _pointSize;
else
return -1;
}
glPixelStorei(GL_UNPACK_ALIGNMENT,getPacking());
int Font::
getDescender() const
{
if(_init && _created)
return _font->Descender();
else
return -1;
}
int Font::
getAscender() const
{
if(_init && _created)
return _font->Ascender();
else
return -1;
}
// Font
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// BitmapFont
BitmapFont::
BitmapFont(const std::string& font,
int point_size):
RasterFont()
{
if(init(font))
glTexSubImage2D(GL_TEXTURE_2D,0,
_texturePosX,_texturePosY,
s(),t(),
(GLenum)getPixelFormat(),
(GLenum)getDataType(),
data());
errorNo = glGetError();
if (errorNo!=GL_NO_ERROR)
{
}
_pointSize=point_size;
std::cout << " "<<GL_TEXTURE_2D<<"\t"<<0<<"\t"<<
_texturePosX<<"\t"<<_texturePosY<<"\t"<<
s()<<"\t"<<t()<<"\t"<<
(GLenum)getPixelFormat()<<"\t"<<
(GLenum)getDataType()<<"\t"<<
(int)(*data())<<std::endl;
osg::notify(osg::WARN)<<"after: detected OpenGL error '"<<gluErrorString(errorNo)<<std::endl;
}
}
FTFont* BitmapFont::
createFontObj(void)
{
return (FTFont*)(new FTGLBitmapFont);
}
// BitmapFont
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PixmapFont
PixmapFont::
PixmapFont(const std::string& font,
int point_size):
RasterFont(font)
{
if(init(font))
{
}
_pointSize=point_size;
}
FTFont* PixmapFont::
createFontObj(void)
{
return (FTFont*)(new FTGLPixmapFont);
}
// PixmapFont
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// TextureFont
TextureFont::
TextureFont(const std::string& font,
int point_size):
RasterFont(font)
{
_textureSize=0;
if(init(font))
{
}
_pointSize=point_size;
}
TextureFont::
TextureFont(const std::string& font,
int point_size,
int textureSize ):
RasterFont(font)
{
_textureSize=textureSize;
if(init(font))
{
}
_pointSize=point_size;
}
FTFont* TextureFont::
createFontObj(void)
{
return (FTFont*)(new FTGLTextureFont(_textureSize));
}
// TextureFont
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// _FTGLOutlineFont
OutlineFont::
OutlineFont(const std::string& font,
int point_size,
double precision):
VectorFont(font)
{
if(init(font))
{
}
_pointSize=point_size;
_precision=precision;
}
FTFont* OutlineFont::
createFontObj(void)
{
return (FTFont*)(new FTGLOutlineFont);
}
// _FTGLOutlineFont
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// PolygonFont
PolygonFont::
PolygonFont(const std::string& font,
int point_size,
double precision):
VectorFont(font)
{
if(init(font))
{
}
_pointSize=point_size;
_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)
{
return (FTFont*)(new FTGLPolygonFont);
}
// PolygonFont
///////////////////////////////////////////////////////////////////////////////

View File

@ -1,50 +1,16 @@
TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
FTBitmapGlyph.cpp \
FTCharmap.cpp \
FTFace.cpp \
FTFont.cpp \
FTGLBitmapFont.cpp \
FTGLOutlineFont.cpp \
FTGLPixmapFont.cpp \
FTGLPolygonFont.cpp \
FTGLTextureFont.cpp \
FTGlyphContainer.cpp \
FTGlyph.cpp \
FTLibrary.cpp \
FTOutlineGlyph.cpp \
FTPixmapGlyph.cpp \
FTPolyGlyph.cpp \
FTSize.cpp \
FTTextureGlyph.cpp \
FTVectoriser.cpp \
EncodedText.cpp \
Font.cpp \
Paragraph.cpp \
Text.cpp \
Version.cpp
CXXFILES = \
DefaultFont.cpp\
Font.cpp\
Text.cpp\
Version.cpp\
DEF += -DOSGTEXT_LIBRARY
LIBS += $(OSG_LIBS) $(GL_LIBS) $(FREETYPE_LIB) $(OTHER_LIBS)
DEF += -DOSGTEXT_LIBRARY
ifneq ($(OS),HP-UX)
INC += -I$(OSGHOME)/include \
-I/usr/include/freetype2 \
-I/usr/local/include \
-I/usr/local/include/freetype2 \
-I/usr/freeware/include \
-I/usr/freeware/include/freetype2
LINKARGS += -L/usr/local/lib\
-L/usr/freeware/lib$(ARCH)
else
INC += $(FREETYPE_INCLUDE)
endif
LIBS += -losg -losgUtil $(GL_LIBS) $(OTHER_LIBS)
TARGET_BASENAME = osgText
LIB = $(LIB_PREFIX)$(TARGET_BASENAME).$(LIB_EXT)

View File

@ -1,187 +0,0 @@
#include <osgText/Paragraph>
using namespace osgText;
Paragraph::Paragraph()
: osg::Geode()
{
_alignment = osgText::Text::LEFT_TOP;
_maxCharsPerLine = 80;
}
Paragraph::Paragraph(const Paragraph& paragraph,const osg::CopyOp& copyop):
osg::Geode(paragraph,copyop),
_position(paragraph._position),
_text(paragraph._text),
_font(dynamic_cast<Font*>(copyop(paragraph._font.get()))),
_alignment(paragraph._alignment),
_maxCharsPerLine(paragraph._maxCharsPerLine)
{
}
Paragraph::Paragraph(const osg::Vec3& position,const std::string& text,osgText::Font* font)
: osg::Geode()
{
_maxCharsPerLine = 80;
_position = position;
_font = font;
setText(text);
}
void Paragraph::setPosition(const osg::Vec3& position)
{
if (_position==position) return;
osg::Vec3 delta = position-_position;
_position = position;
for(osg::Geode::DrawableList::iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
osgText::Text* text = dynamic_cast<osgText::Text*>(itr->get());
if (text) text->setPosition(text->getPosition()+delta);
}
}
void Paragraph::setFont(osgText::Font* font)
{
if (_font==font) return;
_font = font;
for(osg::Geode::DrawableList::iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
osgText::Text* text = dynamic_cast<osgText::Text*>(itr->get());
if (text) text->setFont(font);
}
}
void Paragraph::setMaximumNoCharactersPerLine(unsigned int maxCharsPerLine)
{
if (_maxCharsPerLine==maxCharsPerLine) return;
if (maxCharsPerLine<1) maxCharsPerLine=1;
else _maxCharsPerLine=maxCharsPerLine;
createDrawables();
}
void Paragraph::setAlignment(int alignment)
{
if (_alignment==alignment) return;
_alignment=alignment;
for(osg::Geode::DrawableList::iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
osgText::Text* text = dynamic_cast<osgText::Text*>(itr->get());
if (text) text->setAlignment(_alignment);
}
}
void Paragraph::setText(const std::string& text)
{
if (text==_text) return;
_text = text;
createDrawables();
}
float Paragraph::getHeight() const
{
if (_font.valid()) return (_font->getPointSize()+1)*getNumDrawables();
else return 0;
}
void Paragraph::createDrawables()
{
_drawables.clear();
osg::Vec3 pos = _position;
typedef std::vector<std::string> TextList;
TextList formatedText;
createFormatedText(_maxCharsPerLine,_text,formatedText);
// now create the text drawables from the formate text list.
for(TextList::iterator itr=formatedText.begin();
itr!=formatedText.end();
++itr)
{
osgText::Text* textDrawable = new osgText::Text(_font.get());
textDrawable->setAlignment(_alignment);
textDrawable->setPosition(pos);
textDrawable->setText(*itr);
// textDrawable->setDrawMode( osgText::Text::TEXT |
// osgText::Text::BOUNDINGBOX |
// osgText::Text::ALIGNEMENT );
addDrawable(textDrawable);
pos.y() -= (_font->getPointSize()+1);
}
}
bool Paragraph::createFormatedText(unsigned int noCharsPerLine,const std::string& str,std::vector<std::string>& formatedText)
{
if (str.empty()) return false;
std::string::size_type start = 0;
std::string::size_type last_space = 0;
std::string::size_type current_line_length = 0;
for(std::string::size_type current=0;
current<str.size();
++current)
{
const char c = str[current];
if (c==' ') last_space = current;
if (c=='\n')
{
formatedText.push_back(std::string(str,start,current-start));
start = current+1;
last_space = start;
current_line_length = 0;
}
else if (current_line_length==noCharsPerLine)
{
if (last_space>start)
{
formatedText.push_back(std::string(str,start,last_space-start));
start = last_space+1;
current_line_length = current-start;
}
else
{
formatedText.push_back(std::string(str,start,current-start));
start = current+1;
current_line_length = 0;
}
last_space = start;
}
else ++current_line_length;
}
if (start<str.size())
{
formatedText.push_back(std::string(str,start,str.size()-start));
}
return true;
}

View File

@ -1,559 +1,407 @@
/* --------------------------------------------------------------------------
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* ----------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osg/GL>
#include <osgText/Text>
#include <osgDB/FileUtils>
#include "DefaultFont.h"
#include "FTFace.h"
#include "FTGLBitmapFont.h"
#include "FTGLPixmapFont.h"
#include "FTGLOutlineFont.h"
#include "FTGLPolygonFont.h"
#include "FTGLTextureFont.h"
//#define BUILD_NO_TEXT
using namespace osg;
using namespace osgText;
///////////////////////////////////////////////////////////////////////////////
// Text
Text::Text()
Text::Text():
_fontWidth(32),
_fontHeight(32),
_characterHeight(32),
_characterAspectRatio(1.0f),
_alignment(BASE_LINE),
_axisAlignment(XY_PLANE),
_rotation(),
_layout(LEFT_TO_RIGHT),
_color(1.0f,1.0f,1.0f,1.0f),
_drawMode(TEXT)
{
setDefaults();
setUseDisplayList(false);
}
Text::Text(const Text& text,const osg::CopyOp& copyop):
Drawable(text,copyop),
_font(dynamic_cast<Font*>(copyop(text._font.get()))),
_init(text._init),
_initAlignment(text._initAlignment),
_text(text._text),
_fontType(text._fontType),
_alignment(text._alignment),
_drawMode(text._drawMode),
_boundingBoxType(text._boundingBoxType),
_axisAlignment(text._axisAlignment),
_encodedText(text._encodedText),
_pos(text._pos),
_alignmentPos(text._alignmentPos),
_color(text._color)
Drawable(text,copyop),
_font(text._font),
_fontWidth(text._fontWidth),
_fontHeight(text._fontHeight),
_characterHeight(text._characterHeight),
_characterAspectRatio(text._characterAspectRatio),
_text(text._text),
_position(text._position),
_alignment(text._alignment),
_axisAlignment(text._axisAlignment),
_rotation(text._rotation),
_layout(text._layout),
_color(text._color),
_drawMode(text._drawMode)
{
}
Text::Text(Font* font)
{
setDefaults();
if(font && font->isOk())
{
_init=true;
_font=font;
if(dynamic_cast<PolygonFont*>(_font.get()))
_fontType=POLYGON;
else if(dynamic_cast<BitmapFont*>(_font.get()))
_fontType=BITMAP;
else if(dynamic_cast<PixmapFont*>(_font.get()))
_fontType=PIXMAP;
else if(dynamic_cast<TextureFont*>(_font.get()))
_fontType=TEXTURE;
else if(dynamic_cast<OutlineFont*>(_font.get()))
_fontType=OUTLINE;
}
}
Text::~Text()
{
}
void Text::setFont(Font* font)
{
if (_font==font) return;
if(font && font->isOk())
{
_init=true;
_font=font;
if(dynamic_cast<PolygonFont*>(_font.get()))
_fontType=POLYGON;
else if(dynamic_cast<BitmapFont*>(_font.get()))
_fontType=BITMAP;
else if(dynamic_cast<PixmapFont*>(_font.get()))
_fontType=PIXMAP;
else if(dynamic_cast<TextureFont*>(_font.get()))
_fontType=TEXTURE;
else if(dynamic_cast<OutlineFont*>(_font.get()))
_fontType=OUTLINE;
_initAlignment = false;
dirtyBound();
}
_font = font;
computeGlyphRepresentation();
}
void Text::
setDefaults()
void Text::setFont(const std::string& fontfile)
{
_init=false;
_pos.set(0,0,0);
_alignmentPos.set(0,0,0);
_color.set(1.0f,1.0f,1.0f,1.0f);
_fontType=UNDEF;
_alignment=LEFT_BOTTOM;
_drawMode=DEFAULT;
setFont(readFontFile(fontfile));
}
_boundingBoxType=GLYPH;
_boundingBoxType=GEOMETRY;
void Text::setFontSize(unsigned int width, unsigned int height)
{
_fontWidth = width;
_fontHeight = height;
computeGlyphRepresentation();
}
_axisAlignment = XY_PLANE;
_initAlignment=false;
void Text::setCharacterSize(float height,float ascpectRatio=1.0f)
{
_characterHeight = height;
_characterAspectRatio = ascpectRatio;
computeGlyphRepresentation();
}
_useDisplayList=false;
_encodedText = new EncodedText();
void Text::setText(const TextString& text)
{
_text = text;
computeGlyphRepresentation();
}
void Text::setText(const std::string& text)
{
_text.clear();
_text.insert(_text.end(),text.begin(),text.end());
computeGlyphRepresentation();
}
void Text::setText(const wchar_t* text)
{
_text.clear();
if (text)
{
// find the end of wchar_t string
const wchar_t* endOfText = text;
while (*endOfText) ++endOfText;
// pass it to the _text field.
_text.insert(_text.end(),text,endOfText);
}
computeGlyphRepresentation();
}
void Text::setPosition(const osg::Vec3& pos)
{
_position = pos;
}
void Text::setAlignment(AlignmentType alignment)
{
_alignment = alignment;
}
void Text::setAxisAlignment(AxisAlignment axis)
{
_axisAlignment = axis;
}
void Text::setRotation(const osg::Quat& quat)
{
_rotation = quat;
}
void Text::setLayout(Layout layout)
{
_layout = layout;
computeGlyphRepresentation();
}
void Text::setColor(const osg::Vec4& color)
{
_color = color;
}
bool Text::computeBound() const
{
#ifndef BUILD_NO_TEXT
if(!_init)
{
_bbox_computed=false;
return true;
}
// culling
if(_font->isCreated())
{ // ready to get the siz
_bbox.init();
Vec3 min,max;
calcBounds(&min,&max);
_bbox.expandBy(min);
_bbox.expandBy(max);
_bbox_computed=true;
}
else
{ // have to wait for the init.
_bbox.init();
// to be sure that the obj isn't culled
// _bbox.expandBy(_pos);
_bbox.expandBy(_pos + Vec3(-100,-100,-100));
_bbox.expandBy(_pos + Vec3(100,100,100));
/*
_bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX));
_bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX));
*/
_bbox_computed=true;
}
#else
_bbox.init();
_bbox_computed=true;
#endif
_textBB.init();
osg::Matrix matrix;
matrix.makeTranslate(_position);
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
++titr)
{
const GlyphQuads& glyphquad = titr->second;
for(GlyphQuads::Coords::const_iterator citr = glyphquad._coords.begin();
citr != glyphquad._coords.end();
++citr)
{
_textBB.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f));
_bbox.expandBy(osg::Vec3(citr->x(),citr->y(),0.0f)*matrix);
}
}
_bbox_computed = true;
return true;
}
bool Text::supports(PrimitiveFunctor&) const
Font* Text::getActiveFont()
{
return true;
return _font.valid() ? _font.get() : DefaultFont::instance();
}
void Text::accept(PrimitiveFunctor& functor) const
const Font* Text::getActiveFont() const
{
#ifndef BUILD_NO_TEXT
Vec3 boundingVertices[4];
boundingVertices[0].set(_bbox._min._v[0],_bbox._max._v[1],_bbox._min._v[2]);
boundingVertices[1] = _bbox._min;
boundingVertices[2].set(_bbox._max._v[0],_bbox._min._v[1],_bbox._max._v[2]);
boundingVertices[3] = _bbox._max;
functor.setVertexArray(4,boundingVertices);
functor.drawArrays( GL_QUADS, 0, 4);
#endif
return _font.valid() ? _font.get() : DefaultFont::instance();
}
void Text::compile(State& state) const
void Text::computeGlyphRepresentation()
{
#ifndef BUILD_NO_TEXT
// ahhhh, this is bit doddy, the draw is potentially
// modifying the text object, this isn't thread safe.
Text* this_non_const = const_cast<Text*>(this);
Font* activefont = getActiveFont();
if (!activefont) return;
if(!_font->isCreated() || !(this_non_const->_font->getFont()->Created(state.getContextID())))
{
this_non_const->_font->create(state);
this_non_const->dirtyBound();
}
if(!_initAlignment)
{
this_non_const->initAlignment();
}
#endif
}
void Text::drawImplementation(State& state) const
{
#ifndef BUILD_NO_TEXT
if(!_init)
return;
_textureGlyphQuadMap.clear();
// ahhhh, this is bit doddy, the draw is potentially
// modifying the text object, this isn't thread safe.
Text* this_non_const = const_cast<Text*>(this);
osg::Vec2 cursor(0.0f,0.0f);
osg::Vec2 local(0.0f,0.0f);
if(!_font->isCreated() || !(this_non_const->_font->getFont()->Created(state.getContextID())))
{
this_non_const->_font->create(state);
this_non_const->dirtyBound();
}
unsigned int previous_charcode = 0;
bool horizontal = _layout!=VERTICAL;
bool kerning = true;
if(!_initAlignment)
{
this_non_const->initAlignment();
}
// we must disable all the vertex arrays to prevent any state
// propagating into text.
state.disableAllVertexArrays();
state.setActiveTextureUnit(0);
activefont->setSize(_fontWidth,_fontHeight);
// draw boundingBox
if(_drawMode & BOUNDINGBOX)
drawBoundingBox();
// draw alignment
if(_drawMode & ALIGNMENT)
drawAlignment();
float hr = _characterHeight/(float)activefont->getHeight();
float wr = hr/_characterAspectRatio;
// draw boundingBox
if(_drawMode & TEXT)
for(TextString::iterator itr=_text.begin();
itr!=_text.end();
++itr)
{
glColor3fv(_color.ptr());
unsigned int charcode = *itr;
Font::Glyph* glyph = activefont->getGlyph(charcode);
if (glyph)
{
Vec3 drawPos(_pos+_alignmentPos);
glPushMatrix();
switch(_fontType)
float width = (float)glyph->s() * wr;
float height = (float)glyph->t() * hr;
if (_layout==RIGHT_TO_LEFT)
{
case POLYGON:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,getEncodedText());
cursor.x() -= glyph->getHorizontalAdvance() * wr;
}
// adjust cursor position w.r.t any kerning.
if (kerning && previous_charcode)
{
switch(_layout)
{
case LEFT_TO_RIGHT:
{
osg::Vec2 delta(activefont->getKerning(previous_charcode,charcode));
cursor.x() += delta.x() * wr;
cursor.y() += delta.y() * hr;
break;
case OUTLINE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,getEncodedText());
}
case RIGHT_TO_LEFT:
{
osg::Vec2 delta(activefont->getKerning(charcode,previous_charcode));
cursor.x() -= delta.x() * wr;
cursor.y() -= delta.y() * hr;
break;
case BITMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(state,getEncodedText());
break;
case PIXMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(state,getEncodedText());
break;
case TEXTURE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,getEncodedText());
break;
};
glPopMatrix();
}
#endif
}
void Text::drawBoundingBox(void) const
{
if(!_init)
return;
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT );
glDisable(GL_TEXTURE_2D);
glColor3f(0,1,0);
glBegin(GL_LINE_LOOP);
glVertex3f(_bbox.xMin(),_bbox.yMin(),_bbox.zMin());
glVertex3f(_bbox.xMax(),_bbox.yMin(),_bbox.zMin());
glVertex3f(_bbox.xMax(),_bbox.yMax(),_bbox.zMin());
glVertex3f(_bbox.xMin(),_bbox.yMax(),_bbox.zMin());
glEnd();
glPopAttrib();
}
void Text::drawAlignment(void) const
{
if(!_init)
return;
double size=_font->getPointSize()/4;
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT );
glDisable(GL_TEXTURE_2D);
glColor3f(1,0,0);
glBegin(GL_LINES);
glVertex3f(_pos.x() - size,_pos.y(),_pos.z());
glVertex3f(_pos.x() + size,_pos.y(),_pos.z());
}
case VERTICAL:
break; // no kerning when vertical.
}
}
local = cursor;
osg::Vec2 bearing(horizontal?glyph->getHorizontalBearing():glyph->getVerticalBearing());
local.x() += bearing.x() * wr;
local.y() += bearing.y() * hr;
glVertex3f(_pos.x(),_pos.y() - size,_pos.z());
glVertex3f(_pos.x(),_pos.y() + size,_pos.z());
GlyphQuads& glyphquad = _textureGlyphQuadMap[glyph->getTexture()->getStateSet()];
// set up the coords of the quad
glyphquad._coords.push_back(local+osg::Vec2(0.0f,height));
glyphquad._coords.push_back(local+osg::Vec2(0.0f,0.0f));
glyphquad._coords.push_back(local+osg::Vec2(width,0.0f));
glyphquad._coords.push_back(local+osg::Vec2(width,height));
// set up the tex coords of the quad
const osg::Vec2& mintc = glyph->getMinTexCoord();
const osg::Vec2& maxtc = glyph->getMaxTexCoord();
glyphquad._texcoords.push_back(osg::Vec2(mintc.x(),maxtc.y()));
glyphquad._texcoords.push_back(osg::Vec2(mintc.x(),mintc.y()));
glyphquad._texcoords.push_back(osg::Vec2(maxtc.x(),mintc.y()));
glyphquad._texcoords.push_back(osg::Vec2(maxtc.x(),maxtc.y()));
// move the cursor onto the next character.
switch(_layout)
{
case LEFT_TO_RIGHT: cursor.x() += glyph->getHorizontalAdvance() * wr; break;
case VERTICAL: cursor.y() -= glyph->getVerticalAdvance() *hr; break;
case RIGHT_TO_LEFT: break; // nop.
}
}
previous_charcode = charcode;
}
if (!_textureGlyphQuadMap.empty())
{
setStateSet(const_cast<osg::StateSet*>((*_textureGlyphQuadMap.begin()).first.get()));
}
dirtyBound();
}
void Text::drawImplementation(osg::State& state) const
{
osg::Vec3 offset;
switch(_alignment)
{
case LEFT_TOP: offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break;
case LEFT_CENTER: offset.set(_textBB.xMin(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case LEFT_BOTTOM: offset.set(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()); break;
case CENTER_TOP: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMax(),_textBB.zMin()); break;
case CENTER_CENTER: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case CENTER_BOTTOM: offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMin(),_textBB.zMin()); break;
case RIGHT_TOP: offset.set(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); break;
case RIGHT_CENTER: offset.set(_textBB.xMax(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin()); break;
case RIGHT_BOTTOM: offset.set(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()); break;
case BASE_LINE: offset.set(0.0f,0.0f,0.0f);
}
glPushMatrix();
glTranslatef(_position.x(),_position.y(),_position.z());
glTranslatef(-offset.x(),-offset.y(),-offset.z());
switch(_axisAlignment)
{
case XZ_PLANE: glRotatef(90.0f,1.0f,0.0f,0.0f); break;
case YZ_PLANE: glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f); break;
case XY_PLANE: break; // nop - already on XY plane.
case SCREEN:
{
osg::Matrix mv = state.getModelViewMatrix();
mv.setTrans(0.0f,0.0f,0.0f);
osg::Matrix mat3x3;
mat3x3.invert(mv);
glMultMatrixf(mat3x3.ptr());
}
break;
}
if (!_rotation.zeroRotation())
{
osg::Matrix matrix;
_rotation.get(matrix);
glMultMatrixf(matrix.ptr());
}
glNormal3f(0.0f,0.0,1.0f);
glColor4fv(_color.ptr());
if (_drawMode & TEXT)
{
bool first = true;
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
++titr)
{
// need to set the texture here...
if (!first)
{
state.apply(titr->first.get());
}
const GlyphQuads& glyphquad = titr->second;
state.setVertexPointer( 2, GL_FLOAT, 0, &(glyphquad._coords.front()));
state.setTexCoordPointer( 0, 2, GL_FLOAT, 0, &(glyphquad._texcoords.front()));
glDrawArrays(GL_QUADS,0,glyphquad._coords.size());
first = false;
}
}
if (_drawMode & BOUNDINGBOX)
{
if (_textBB.valid())
{
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
glColor4f(1.0f,1.0f,0.0f,1.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(_textBB.xMin(),_textBB.yMin(),_textBB.zMin());
glVertex3f(_textBB.xMax(),_textBB.yMin(),_textBB.zMin());
glVertex3f(_textBB.xMax(),_textBB.yMax(),_textBB.zMin());
glVertex3f(_textBB.xMin(),_textBB.yMax(),_textBB.zMin());
glEnd();
}
}
if (_drawMode & ALIGNMENT)
{
glColor4f(1.0f,0.0f,1.0f,1.0f);
glTranslatef(offset.x(),offset.y(),offset.z());
state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);
float cursorsize = _characterHeight*0.5f;
glBegin(GL_LINES);
glVertex3f(-cursorsize,0.0f,0.0f);
glVertex3f(cursorsize,0.0f,0.0f);
glVertex3f(0.0f,-cursorsize,0.0f);
glVertex3f(0.0f,cursorsize,0.0f);
glEnd();
glPopAttrib();
}
void Text::
setPosition(const Vec3& pos)
{
_pos=pos;
dirtyBound();
}
glPopMatrix();
}
void Text::
setPosition(const Vec2& pos)
{
setPosition(Vec3(pos.x(),pos.y(),0));
}
void Text::
calcBounds(Vec3* min,Vec3* max) const
{
if(!_init)
return;
float h=_font->getHeight();
float w=_font->getWidth(getEncodedText());
float descender=_font->getDescender();
min->set(0,descender,0);
max->set(w,h + descender ,0);
}
bool Text::
initAlignment(void)
{
#ifndef BUILD_NO_TEXT
if(!_init)
return false;
// culling
if(_font->isCreated())
{ // ready to get the siz
_bbox.init();
Vec3 min,max;
initAlignment(&min,&max);
_bbox.expandBy(min);
_bbox.expandBy(max);
_bbox_computed=true;
_initAlignment=true;
}
else
{ // have to wait for the init.
_bbox.init();
// to be sure that the obj isn't culled
_bbox.expandBy(Vec3(-FLT_MAX,-FLT_MAX,-FLT_MAX));
_bbox.expandBy(Vec3(FLT_MAX,FLT_MAX,FLT_MAX));
_bbox_computed=true;
}
#endif
return true;
}
void Text::
initAlignment(Vec3* min,Vec3* max)
{
#ifndef BUILD_NO_TEXT
if(!_init)
return;
float h=_font->getHeight();
float w=_font->getWidth(getEncodedText());
float descender=_font->getDescender();
min->set(0,descender,0);
max->set(w,h + descender ,0);
switch(_boundingBoxType)
{
case GLYPH:
h+=descender;
switch(_alignment)
{
case LEFT_TOP:
_alignmentPos.set(0.0,h,0.0);
break;
case LEFT_CENTER:
_alignmentPos.set(0.0,h/2.0,0.0);
break;
case LEFT_BOTTOM:
_alignmentPos.set(0.0,0.0,0.0);
break;
case CENTER_TOP:
_alignmentPos.set(w/2.0,h,0.0);
break;
case CENTER_CENTER:
_alignmentPos.set(w/2.0,h/2.0,0.0);
break;
case CENTER_BOTTOM:
_alignmentPos.set(w/2.0,0.0,0.0);
break;
case RIGHT_TOP:
_alignmentPos.set(w,h,0.0);
break;
case RIGHT_CENTER:
_alignmentPos.set(w,h/2.0,0.0);
break;
case RIGHT_BOTTOM:
_alignmentPos.set(w,0.0,0.0);
break;
};
_alignmentPos=-_alignmentPos;
*min+=_pos+_alignmentPos;
*max+=_pos+_alignmentPos;
break;
case GEOMETRY:
switch(_alignment)
{
case LEFT_TOP:
_alignmentPos.set(0.0,h + descender,0.0);
break;
case LEFT_CENTER:
_alignmentPos.set(0.0,(max->y()-min->y()) /2.0 + descender,0.0);
break;
case LEFT_BOTTOM:
_alignmentPos.set(0.0,descender,0.0);
break;
case CENTER_TOP:
_alignmentPos.set(w/2.0,h + descender,0.0);
break;
case CENTER_CENTER:
_alignmentPos.set(w/2.0,(max->y()-min->y()) /2.0 + descender,0.0);
break;
case CENTER_BOTTOM:
_alignmentPos.set(w/2.0,descender,0.0);
break;
case RIGHT_TOP:
_alignmentPos.set(w,h + descender,0.0);
break;
case RIGHT_CENTER:
_alignmentPos.set(w,(max->y()-min->y()) /2.0 + descender,0.0);
break;
case RIGHT_BOTTOM:
_alignmentPos.set(w,descender,0.0);
break;
};
_alignmentPos=-_alignmentPos;
*min+=_pos+_alignmentPos;
*max+=_pos+_alignmentPos;
break;
};
switch(_fontType)
{
case BITMAP:
break;
case PIXMAP:
break;
};
#endif
}
void Text::
setAlignment(int alignment)
{
_alignment=alignment;
if(!_init || !_font->isCreated())
return;
initAlignment();
}
void Text::
setBoundingBox(int mode)
{
_boundingBoxType=mode;
if(!_init || !_font->isCreated())
return;
initAlignment();
}
void Text::
setText(const char* text)
{
_text=text;
_initAlignment=false;
_encodedText->setText((const unsigned char*)text);
}
void Text::
setText(const std::string& text)
{
_text=text;
_initAlignment=false;
_encodedText->setText((const unsigned char*)_text.data(),_text.size());
}
void Text::
setText(const wchar_t* text)
{
_encodedText->setOverrideEncoding(EncodedText::ENCODING_UTF8);
_text=_encodedText->convertWideString(text);
_initAlignment=false;
_encodedText->setText((const unsigned char*)_text.data(),_text.size());
}
// Text
///////////////////////////////////////////////////////////////////////////////