First cut of new osgText implementation.
This commit is contained in:
parent
a826f5ee31
commit
fbe674b321
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -104,7 +104,6 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor
|
||||
|
||||
protected:
|
||||
|
||||
/** \internal JAVA: SUPPRESS UNBRIDGABLE :JAVA */
|
||||
class IntersectState : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
126
src/osgPlugins/freetype/FreeTypeFont.cpp
Normal file
126
src/osgPlugins/freetype/FreeTypeFont.cpp
Normal 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);
|
||||
}
|
46
src/osgPlugins/freetype/FreeTypeFont.h
Normal file
46
src/osgPlugins/freetype/FreeTypeFont.h
Normal 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
|
57
src/osgPlugins/freetype/FreeTypeLibrary.cpp
Normal file
57
src/osgPlugins/freetype/FreeTypeLibrary.cpp
Normal 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);
|
||||
|
||||
}
|
42
src/osgPlugins/freetype/FreeTypeLibrary.h
Normal file
42
src/osgPlugins/freetype/FreeTypeLibrary.h
Normal 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
|
29
src/osgPlugins/freetype/Makefile
Normal file
29
src/osgPlugins/freetype/Makefile
Normal 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
|
37
src/osgPlugins/freetype/ReaderWriterFreeType.cpp
Normal file
37
src/osgPlugins/freetype/ReaderWriterFreeType.cpp
Normal 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;
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
215
src/osgText/DefaultFont.cpp
Normal 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
54
src/osgText/DefaultFont.h
Normal 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
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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__
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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__
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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__
|
@ -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();
|
||||
}
|
@ -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__
|
@ -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();
|
||||
|
||||
}
|
@ -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__
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
@ -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__
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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__
|
||||
|
||||
|
@ -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()
|
||||
{}
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
@ -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__
|
@ -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;
|
||||
}
|
@ -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__
|
@ -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;
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
@ -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__
|
@ -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;
|
||||
}
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
@ -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__
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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__
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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__
|
@ -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
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user