First past integrat of Max Rhiener work on wrapping FTGL to create osgText
library and demo.
This commit is contained in:
parent
63bb05e6fd
commit
8e1b1bcfc1
102
VisualStudio/Demos/osgTextDemo/osgTextDemo.dsp
Normal file
102
VisualStudio/Demos/osgTextDemo/osgTextDemo.dsp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="osgTextDemo" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||||
|
|
||||||
|
CFG=osgTextDemo - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "osgTextDemo.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "osgTextDemo.mak" CFG="osgTextDemo - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "osgTextDemo - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "osgTextDemo - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "osgTextDemo - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD BASE RSC /l 0x807 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x807 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||||
|
# ADD LINK32 osgText.lib osgGlut.lib glut32.lib osgUtil.lib osgDB.lib osg.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../../../osgDev/bin/osgTextDemo.exe"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "osgTextDemo - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
||||||
|
# ADD BASE RSC /l 0x807 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x807 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 osgTextd.lib osgGlutd.lib glut32.lib osgUtild.lib osgDBd.lib osgd.lib opengl32.lib glu32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../../osgDev/bin/osgTextDemoD.exe" /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "osgTextDemo - Win32 Release"
|
||||||
|
# Name "osgTextDemo - Win32 Debug"
|
||||||
|
# Begin Group "Quellcodedateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\src\Demos\osgText\main.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header-Dateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Ressourcendateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
115
VisualStudio/osgText/osgText.dsp
Normal file
115
VisualStudio/osgText/osgText.dsp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="osgText" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=osgText - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "osgText.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "osgText.mak" CFG="osgText - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "osgText - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "osgText - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "osgText - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "../../lib"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OSGTEXT_EXPORTS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OSGTEXT_LIBRARY" /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x807 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x807 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# ADD LINK32 ftglDllD.lib glu32.lib opengl32.lib osg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"../../../../osgDev/bin/osgText.dll"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "osgText - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "../../lib"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OSGTEXT_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "OSGTEXT_LIBRARY" /FR /YX /FD /GZ /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x807 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x807 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 ftglDllD.lib glu32.lib opengl32.lib osgd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\development\osgDev\osgDev\bin\osgTextD.dll" /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "osgText - Win32 Release"
|
||||||
|
# Name "osgText - Win32 Debug"
|
||||||
|
# Begin Group "Quellcodedateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\src\osgText\Text.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header-Dateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\include\osgText\Export
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\include\osgText\Text.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Ressourcendateien"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
25
include/osgText/Export
Normal file
25
include/osgText/Export
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 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
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning( disable : 4251 )
|
||||||
|
#pragma warning( disable : 4275 )
|
||||||
|
#pragma warning( disable : 4786 )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
# ifdef OSGTEXT_LIBRARY
|
||||||
|
# define OSGTEXT_EXPORT __declspec(dllexport)
|
||||||
|
# else
|
||||||
|
# define OSGTEXT_EXPORT __declspec(dllimport)
|
||||||
|
# endif /* OSGTEXT_LIBRARY */
|
||||||
|
#else
|
||||||
|
# define OSGTEXT_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
345
include/osgText/Text
Normal file
345
include/osgText/Text
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 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_TEXT
|
||||||
|
#define OSGTEXT_TEXT 1
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <osg/GL>
|
||||||
|
#include <osg/Object>
|
||||||
|
#include <osg/Drawable>
|
||||||
|
#include <osg/Vec3>
|
||||||
|
#include <osg/Vec2>
|
||||||
|
|
||||||
|
// http://homepages.paradise.net.nz/henryj/code/
|
||||||
|
/*
|
||||||
|
#include <FTFace.h>
|
||||||
|
#include <FTGLBitmapFont.h>
|
||||||
|
#include <FTGLPixmapFont.h>
|
||||||
|
#include <FTGLOutlineFont.h>
|
||||||
|
#include <FTGLPolygonFont.h>
|
||||||
|
#include <FTGLTextureFont.h>
|
||||||
|
*/
|
||||||
|
#include <osgText/Export>
|
||||||
|
|
||||||
|
class FTFont;
|
||||||
|
|
||||||
|
namespace osgText {
|
||||||
|
|
||||||
|
using namespace osg;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Font - FontBaseClass
|
||||||
|
class OSGTEXT_EXPORT Font:public Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
Font();
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool open(const std::string& font);
|
||||||
|
|
||||||
|
virtual bool create(int pointSize, const unsigned int res = 72 );
|
||||||
|
virtual bool create();
|
||||||
|
virtual void output(const char* text);
|
||||||
|
|
||||||
|
virtual bool isOk(void) const { return _init; }
|
||||||
|
virtual bool isCreated(void) const { return isOk() && _created; }
|
||||||
|
|
||||||
|
virtual float getWidth(const char* text) const;
|
||||||
|
virtual int getHeight() const;
|
||||||
|
virtual int getDescender() const;
|
||||||
|
virtual int getAscender() const;
|
||||||
|
|
||||||
|
int getPointSize(void) const { return _pointSize; }
|
||||||
|
const std::string& getFontName();
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
// Font
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// RasterFont
|
||||||
|
class OSGTEXT_EXPORT RasterFont:public Font
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RasterFont():Font(){;}
|
||||||
|
RasterFont(const std::string& font):Font(){;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// RasterFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VectorFont
|
||||||
|
class OSGTEXT_EXPORT VectorFont:public Font
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VectorFont():Font(){;}
|
||||||
|
VectorFont(const std::string& font):Font(){;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double _precision;
|
||||||
|
};
|
||||||
|
|
||||||
|
// VectorFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// BitmapFont
|
||||||
|
class OSGTEXT_EXPORT BitmapFont:public RasterFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
BitmapFont() {;}
|
||||||
|
|
||||||
|
BitmapFont(const std::string& font,
|
||||||
|
int point_size);
|
||||||
|
|
||||||
|
META_Object(BitmapFont);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
|
||||||
|
virtual FTFont* createFontObj(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
// BitmapFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PixmapFont
|
||||||
|
class OSGTEXT_EXPORT PixmapFont:public RasterFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PixmapFont() {;}
|
||||||
|
|
||||||
|
PixmapFont(const std::string& font,
|
||||||
|
int point_size);
|
||||||
|
|
||||||
|
META_Object(PixmapFont);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual FTFont* createFontObj(void);
|
||||||
|
|
||||||
|
};
|
||||||
|
// PixmapFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TextureFont
|
||||||
|
|
||||||
|
class OSGTEXT_EXPORT TextureFont:public RasterFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
TextureFont() {;}
|
||||||
|
|
||||||
|
TextureFont(const std::string& font,
|
||||||
|
int point_size);
|
||||||
|
|
||||||
|
META_Object(TextureFont);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual FTFont* createFontObj(void);
|
||||||
|
|
||||||
|
};
|
||||||
|
// PixmapFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// OutlineFont
|
||||||
|
class OSGTEXT_EXPORT OutlineFont:public VectorFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
OutlineFont() {;}
|
||||||
|
|
||||||
|
OutlineFont(const std::string& font,
|
||||||
|
int point_size,
|
||||||
|
double precision);
|
||||||
|
|
||||||
|
META_Object(OutlineFont);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual FTFont* createFontObj(void);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
// OutlineFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PolygonFont
|
||||||
|
class OSGTEXT_EXPORT PolygonFont:public VectorFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
PolygonFont() {;}
|
||||||
|
|
||||||
|
PolygonFont(const std::string& font,
|
||||||
|
int point_size,
|
||||||
|
double precision);
|
||||||
|
|
||||||
|
META_Object(PolygonFont);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual FTFont* createFontObj(void);
|
||||||
|
|
||||||
|
};
|
||||||
|
// PolygonFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Text
|
||||||
|
class OSGTEXT_EXPORT Text:public Drawable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum AlignmentType
|
||||||
|
{ // from left to right, top to bottom
|
||||||
|
LEFT_TOP,
|
||||||
|
LEFT_CENTER,
|
||||||
|
LEFT_BOTTOM,
|
||||||
|
|
||||||
|
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,
|
||||||
|
ALIGNEMENT = 1<<2,
|
||||||
|
DEFAULT = TEXT,
|
||||||
|
};
|
||||||
|
|
||||||
|
Text();
|
||||||
|
Text(Font* font);
|
||||||
|
|
||||||
|
META_Object(Text);
|
||||||
|
|
||||||
|
void setPosition(const Vec3& pos);
|
||||||
|
void setPosition(const Vec2& pos);
|
||||||
|
|
||||||
|
void setDrawMode(int mode) { _drawMode=mode; }
|
||||||
|
int getDrawMode(void) { return _drawMode; }
|
||||||
|
|
||||||
|
void setBoundingBox(int mode);
|
||||||
|
int getBoundingBox(void) { return _boundingBoxType; }
|
||||||
|
|
||||||
|
void setAlignement(int alignement);
|
||||||
|
int getAlignement(void) { return _alignement; }
|
||||||
|
|
||||||
|
void setFont(Font* font);
|
||||||
|
Font* getFont(void);
|
||||||
|
|
||||||
|
void setText(const char* text) { _text=text; }
|
||||||
|
void setText(std::string& text) { _text=text; }
|
||||||
|
const std::string& getText() const { return _text; }
|
||||||
|
|
||||||
|
virtual void drawImmediateMode(State& state);
|
||||||
|
virtual void drawBoundingBox(void);
|
||||||
|
virtual void drawAlignement(void);
|
||||||
|
|
||||||
|
const Vec3& getPosition() { return _pos; }
|
||||||
|
const Vec3& getAlignementPos() { return _alignementPos; };
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum FontType
|
||||||
|
{
|
||||||
|
UNDEF,
|
||||||
|
BITMAP,
|
||||||
|
PIXMAP,
|
||||||
|
OUTLINE,
|
||||||
|
POLYGON,
|
||||||
|
TEXTURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~Text();
|
||||||
|
|
||||||
|
virtual void setDefaults(void);
|
||||||
|
virtual const bool computeBound(void) const;
|
||||||
|
virtual void calcBounds(Vec3* min,Vec3* max) const;
|
||||||
|
void initAlignement(Vec3* min,Vec3* max);
|
||||||
|
bool initAlignement(void);
|
||||||
|
|
||||||
|
ref_ptr<Font> _font;
|
||||||
|
|
||||||
|
bool _init;
|
||||||
|
bool _initAlignement;
|
||||||
|
std::string _text;
|
||||||
|
int _fontType;
|
||||||
|
int _alignement;
|
||||||
|
int _drawMode;
|
||||||
|
int _boundingBoxType;
|
||||||
|
|
||||||
|
Vec3 _pos;
|
||||||
|
Vec3 _alignementPos;
|
||||||
|
};
|
||||||
|
// Text
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _OSG_TEXT_H
|
588
src/Demos/osgtext/main.cpp
Normal file
588
src/Demos/osgtext/main.cpp
Normal file
@ -0,0 +1,588 @@
|
|||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* osgText demo
|
||||||
|
*
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* prog: max rheiner;mrn@paus.ch
|
||||||
|
* date: 4/26/2001 (m/d/y)
|
||||||
|
*
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <osg/Node>
|
||||||
|
#include <osg/StateSet>
|
||||||
|
#include <osg/GeoSet>
|
||||||
|
#include <osg/Material>
|
||||||
|
#include <osg/Transparency>
|
||||||
|
#include <osg/Transform>
|
||||||
|
#include <osg/PolygonMode>
|
||||||
|
#include <osg/Notify>
|
||||||
|
|
||||||
|
#include <osgUtil/TrackballManipulator>
|
||||||
|
#include <osgUtil/FlightManipulator>
|
||||||
|
#include <osgUtil/DriveManipulator>
|
||||||
|
|
||||||
|
#include <osgGLUT/Viewer>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
|
||||||
|
#include <osgText/text.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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/verdana.ttf");
|
||||||
|
|
||||||
|
int gFontSize=18;
|
||||||
|
int gFontSize1=24;
|
||||||
|
std::vector<osg::ref_ptr<osgText::Text > > gTextList;
|
||||||
|
osgText::Text::AlignmentType gAlignement=osgText::Text::AlignmentType::LEFT_BOTTOM;
|
||||||
|
|
||||||
|
|
||||||
|
void set2dScene(osg::Group* rootNode)
|
||||||
|
{
|
||||||
|
osgText::Text* text;
|
||||||
|
osg::Geode* geode;
|
||||||
|
osg::Material* textMaterial;
|
||||||
|
osg::Vec4 textColor;
|
||||||
|
osg::StateSet* textState;
|
||||||
|
double xOffset=250;
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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::Transparency *transp=new osg::Transparency();
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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::Transparency();
|
||||||
|
transp->setFunction(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
textState = new osg::StateSet();
|
||||||
|
textState->setAttribute(textMaterial );
|
||||||
|
textState->setAttribute(transp);
|
||||||
|
|
||||||
|
textState->setMode(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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScene(osg::Group* rootNode)
|
||||||
|
{
|
||||||
|
osgText::Text* text;
|
||||||
|
osg::Geode* geode;
|
||||||
|
osg::Material* textMaterial;
|
||||||
|
osg::Vec4 textColor;
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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_3D);
|
||||||
|
textState = new osg::StateSet();
|
||||||
|
textState->setAttribute(textMaterial );
|
||||||
|
geode->setStateSet( textState );
|
||||||
|
|
||||||
|
rootNode->addChild(geode);
|
||||||
|
|
||||||
|
yOffset+=gFontSize+5;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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_3D);
|
||||||
|
// to get antiaA pixmapFonts we have to draw them with blending
|
||||||
|
osg::Transparency *transp=new osg::Transparency();
|
||||||
|
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);
|
||||||
|
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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_3D);
|
||||||
|
// to get antiaA pixmapFonts we have to draw them with blending
|
||||||
|
transp=new osg::Transparency();
|
||||||
|
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->setMode(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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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::DrawModeType::TEXT |
|
||||||
|
osgText::Text::DrawModeType::BOUNDINGBOX |
|
||||||
|
osgText::Text::DrawModeType::ALIGNEMENT );
|
||||||
|
text->setAlignement(gAlignement);
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TextViewer: public osgGLUT::Viewer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual float app(unsigned int viewport)
|
||||||
|
{
|
||||||
|
float ret;
|
||||||
|
ret=Viewer::app(viewport);
|
||||||
|
if(_hudSceneView.valid() && viewport>=_viewportList.size()-1)
|
||||||
|
{
|
||||||
|
_hudSceneView->app();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual float cull(unsigned int viewport)
|
||||||
|
{
|
||||||
|
float ret;
|
||||||
|
ret=Viewer::cull(viewport);
|
||||||
|
if(_hudSceneView.valid() && viewport>=_viewportList.size()-1)
|
||||||
|
_hudSceneView->cull();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual float draw(unsigned int viewport)
|
||||||
|
{
|
||||||
|
float ret;
|
||||||
|
ret=Viewer::draw(viewport);
|
||||||
|
if(_hudSceneView.valid() && viewport>=_viewportList.size()-1)
|
||||||
|
_hudSceneView->draw();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addHUD(osg::Node* rootnode)
|
||||||
|
{
|
||||||
|
_hudSceneView = new osgUtil::SceneView;
|
||||||
|
_hudSceneView->setDefaults();
|
||||||
|
_hudSceneView->setSceneData(rootnode);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reshape(GLint w, GLint h)
|
||||||
|
{
|
||||||
|
Viewer::reshape(w,h);
|
||||||
|
|
||||||
|
if(_hudSceneView.valid())
|
||||||
|
{
|
||||||
|
_hudSceneView->setViewport(0,0,w,h);
|
||||||
|
_hudCam->setOrtho2D(0,w,0,h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool open()
|
||||||
|
{
|
||||||
|
bool ret=Viewer::open();
|
||||||
|
|
||||||
|
// set the clear flag / after the visualReq.Visitor
|
||||||
|
if(_hudSceneView.valid())
|
||||||
|
{
|
||||||
|
_hudSceneView->getRenderStage()->setClearMask(0);
|
||||||
|
_hudSceneView->getCullVisitor()->setCullingMode(osgUtil::CullViewState::NO_CULLING);
|
||||||
|
_hudSceneView->setCalcNearFar(false);
|
||||||
|
|
||||||
|
_hudCam=new osg::Camera;
|
||||||
|
|
||||||
|
// leftBottom
|
||||||
|
_hudSceneView->setCamera(_hudCam.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Camera> _hudCam;
|
||||||
|
osg::ref_ptr<osgUtil::SceneView> _hudSceneView;
|
||||||
|
|
||||||
|
virtual void keyboard(unsigned char key, int x, int y)
|
||||||
|
{
|
||||||
|
switch(key)
|
||||||
|
{
|
||||||
|
case '1':
|
||||||
|
{ // change DrawMode
|
||||||
|
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
|
||||||
|
for(;itr!=gTextList.end();itr++)
|
||||||
|
(*itr)->setDrawMode(osgText::Text::DrawModeType::TEXT ^ (*itr)->getDrawMode());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case '2':
|
||||||
|
{ // change DrawMode
|
||||||
|
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
|
||||||
|
for(;itr!=gTextList.end();itr++)
|
||||||
|
(*itr)->setDrawMode(osgText::Text::DrawModeType::BOUNDINGBOX ^ (*itr)->getDrawMode());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case '3':
|
||||||
|
{ // change DrawMode
|
||||||
|
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
|
||||||
|
for(;itr!=gTextList.end();itr++)
|
||||||
|
(*itr)->setDrawMode(osgText::Text::DrawModeType::ALIGNEMENT ^ (*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::BoundingBoxType::GLYPH ?
|
||||||
|
osgText::Text::BoundingBoxType::GEOMETRY :
|
||||||
|
osgText::Text::BoundingBoxType::GLYPH;
|
||||||
|
for(;itr!=gTextList.end();itr++)
|
||||||
|
(*itr)->setBoundingBox(type);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
///////////////////////////////////////////////////////////////////
|
||||||
|
case '5':
|
||||||
|
{ // change the textAlignement
|
||||||
|
gAlignement=(osgText::Text::AlignmentType)((int)gAlignement+1);
|
||||||
|
if(gAlignement>osgText::Text::AlignmentType::RIGHT_BOTTOM)
|
||||||
|
gAlignement=osgText::Text::AlignmentType::LEFT_TOP;
|
||||||
|
|
||||||
|
std::vector<osg::ref_ptr<osgText::Text> >::iterator itr=gTextList.begin();
|
||||||
|
for(;itr!=gTextList.end();itr++)
|
||||||
|
(*itr)->setAlignement(gAlignement);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
Viewer::keyboard(key,x,y);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
// initialize the GLUT
|
||||||
|
glutInit( &argc, argv );
|
||||||
|
|
||||||
|
// get the fontName
|
||||||
|
if(argc > 1)
|
||||||
|
ttfPath=argv[1];
|
||||||
|
if(argc > 2)
|
||||||
|
ttfPath1=argv[2];
|
||||||
|
if(argc > 3)
|
||||||
|
{
|
||||||
|
gFontSize=atoi(argv[3]);
|
||||||
|
if(gFontSize<=4)
|
||||||
|
gFontSize=8;
|
||||||
|
}
|
||||||
|
if(argc > 4)
|
||||||
|
{
|
||||||
|
gFontSize1=atoi(argv[3]);
|
||||||
|
if(gFontSize1<=4)
|
||||||
|
gFontSize1=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Group* rootNode = new osg::Group;
|
||||||
|
osg::Group* scene2d = new osg::Group;
|
||||||
|
osg::Transform* textGroup = new osg::Transform;
|
||||||
|
|
||||||
|
// set the name for the hole group
|
||||||
|
rootNode->setName("sceneGroup");
|
||||||
|
|
||||||
|
// turn off the culling
|
||||||
|
// turn off the light
|
||||||
|
osg::StateSet* gstate = new osg::StateSet;
|
||||||
|
gstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
|
||||||
|
gstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
|
||||||
|
gstate->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
|
||||||
|
rootNode->setStateSet(gstate);
|
||||||
|
scene2d->setStateSet(gstate);
|
||||||
|
|
||||||
|
// setup the sceneData
|
||||||
|
setScene(textGroup);
|
||||||
|
textGroup->preRotate(-90,1,0,0);
|
||||||
|
rootNode->addChild(textGroup);
|
||||||
|
|
||||||
|
// setup the 2dNode
|
||||||
|
set2dScene(scene2d);
|
||||||
|
|
||||||
|
// initialize the viewer.
|
||||||
|
TextViewer viewer;
|
||||||
|
/*
|
||||||
|
viewer.addViewport( rootNode );
|
||||||
|
viewer.getViewportSceneView(0)->setBackgroundColor(osg::Vec4(.2,.2,.2,1));
|
||||||
|
*/
|
||||||
|
viewer.addViewport( rootNode,0.0,0.0,0.5,0.5);
|
||||||
|
viewer.addViewport( rootNode,0.5,0.0,0.5,0.5);
|
||||||
|
viewer.addViewport( rootNode,0.0,0.5,1.0,0.5);
|
||||||
|
viewer.addHUD(scene2d);
|
||||||
|
|
||||||
|
// register trackball, flight and drive.
|
||||||
|
viewer.registerCameraManipulator(new osgUtil::TrackballManipulator);
|
||||||
|
viewer.registerCameraManipulator(new osgUtil::FlightManipulator);
|
||||||
|
viewer.registerCameraManipulator(new osgUtil::DriveManipulator);
|
||||||
|
|
||||||
|
viewer.open();
|
||||||
|
viewer.run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
76
src/osgText/FTBitmapGlyph.cc
Normal file
76
src/osgText/FTBitmapGlyph.cc
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTBitmapGlyph.h"
|
||||||
|
#include "FTGL.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;}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
advance = glyph->advance.x >> 16;
|
||||||
|
|
||||||
|
pos.x = bitmap->left;
|
||||||
|
pos.y = srcHeight - bitmap->top;
|
||||||
|
|
||||||
|
// FIXME What about dest alignment?
|
||||||
|
destWidth = srcWidth;
|
||||||
|
destHeight = srcHeight;
|
||||||
|
|
||||||
|
data = new unsigned char[srcPitch * destHeight];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
48
src/osgText/FTBitmapGlyph.h
Normal file
48
src/osgText/FTBitmapGlyph.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifndef __FTBitmapGlyph__
|
||||||
|
#define __FTBitmapGlyph__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FTBitmapGlyph : public FTGlyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param
|
||||||
|
*/
|
||||||
|
FTBitmapGlyph( FT_Glyph glyph);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual ~FTBitmapGlyph();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param pen
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual float Render( const FT_Vector& pen);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
int destWidth;
|
||||||
|
int destHeight;
|
||||||
|
|
||||||
|
unsigned char* data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTBitmapGlyph__
|
91
src/osgText/FTCharmap.cc
Normal file
91
src/osgText/FTCharmap.cc
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "FTCharmap.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTCharmap::FTCharmap( FT_Face face)
|
||||||
|
: err(0),
|
||||||
|
ftFace( face)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
109
src/osgText/FTCharmap.h
Normal file
109
src/osgText/FTCharmap.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#ifndef __FTCharmap__
|
||||||
|
#define __FTCharmap__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
//#include "FTGL.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTCharmap
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class 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;
|
||||||
|
|
||||||
|
FT_Face ftFace;
|
||||||
|
|
||||||
|
typedef map< unsigned long, unsigned long> CharacterMap;
|
||||||
|
CharacterMap charMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current error code. Zero means no error.
|
||||||
|
*/
|
||||||
|
FT_Error err;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTCharmap__
|
110
src/osgText/FTFace.cc
Normal file
110
src/osgText/FTFace.cc
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include "FTFace.h"
|
||||||
|
#include "FTLibrary.h"
|
||||||
|
#include "FTCharmap.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTFace::FTFace()
|
||||||
|
: ftFace(0),
|
||||||
|
numCharMaps(0),
|
||||||
|
charMap(0),
|
||||||
|
numGlyphs(0),
|
||||||
|
err(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
144
src/osgText/FTFace.h
Normal file
144
src/osgText/FTFace.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#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 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.
|
||||||
|
*
|
||||||
|
* @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__
|
148
src/osgText/FTFont.cc
Normal file
148
src/osgText/FTFont.cc
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#include "FTFace.h"
|
||||||
|
#include "FTFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTFont::FTFont()
|
||||||
|
: numFaces(0),
|
||||||
|
glyphList(0),
|
||||||
|
err(0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTFont::Close()
|
||||||
|
{
|
||||||
|
delete glyphList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FTFont::FaceSize( const unsigned int size, const unsigned int res )
|
||||||
|
{
|
||||||
|
charSize = face.Size( size, res);
|
||||||
|
|
||||||
|
if( glyphList)
|
||||||
|
delete glyphList;
|
||||||
|
|
||||||
|
glyphList = new FTGlyphContainer( &face, numGlyphs);
|
||||||
|
|
||||||
|
if( MakeGlyphList())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float FTFont::Advance( const wchar_t* string)
|
||||||
|
{
|
||||||
|
const wchar_t* c = string; // wchar_t IS unsigned?
|
||||||
|
float width = 0;
|
||||||
|
|
||||||
|
while( *c)
|
||||||
|
{
|
||||||
|
width += glyphList->Advance( *c, *(c + 1));
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float FTFont::Advance( const char* string)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTFont::render( const char* string )
|
||||||
|
{
|
||||||
|
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
|
||||||
|
FT_Vector kernAdvance;
|
||||||
|
pen.x = 0; pen.y = 0;
|
||||||
|
|
||||||
|
while( *c)
|
||||||
|
{
|
||||||
|
kernAdvance = glyphList->render( *c, *(c + 1), pen);
|
||||||
|
|
||||||
|
pen.x += kernAdvance.x;
|
||||||
|
pen.y += kernAdvance.y;
|
||||||
|
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTFont::render( const wchar_t* string )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
179
src/osgText/FTFont.h
Normal file
179
src/osgText/FTFont.h
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#ifndef __FTFont__
|
||||||
|
#define __FTFont__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
#include "FTFace.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
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 FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Default Constructor
|
||||||
|
*/
|
||||||
|
FTFont();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~FTFont();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens and reads a font file.
|
||||||
|
*
|
||||||
|
* @param fontname font file name.
|
||||||
|
* @return <code>true</code> if file has opened
|
||||||
|
* successfully.
|
||||||
|
*/
|
||||||
|
virtual bool Open( const char* fontname );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the font
|
||||||
|
*/
|
||||||
|
virtual void Close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the char size for the current face.
|
||||||
|
*
|
||||||
|
* @param size the face size in points (1/72 inch)
|
||||||
|
* @param res the resolution of the target device.
|
||||||
|
* @return <code>true</code> if size was set correctly
|
||||||
|
*/
|
||||||
|
virtual bool FaceSize( const unsigned int size, const unsigned int res = 72 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the character map for the face.
|
||||||
|
*
|
||||||
|
* @param encoding Freetype enumerate for char map code.
|
||||||
|
* @return <code>true</code> if charmap was valid and
|
||||||
|
* set correctly
|
||||||
|
*/
|
||||||
|
virtual bool CharMap( FT_Encoding encoding );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the global ascender height for the face.
|
||||||
|
*
|
||||||
|
* @return Ascender height
|
||||||
|
*/
|
||||||
|
virtual int Ascender() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the global descender height for the face.
|
||||||
|
*
|
||||||
|
* @return Descender height
|
||||||
|
*/
|
||||||
|
virtual int Descender() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the advance width for a string.
|
||||||
|
*
|
||||||
|
* param string a wchar_t string
|
||||||
|
* @return advance width
|
||||||
|
*/
|
||||||
|
float Advance( const wchar_t* string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the advance width for a string.
|
||||||
|
*
|
||||||
|
* param string a char string
|
||||||
|
* @return advance width
|
||||||
|
*/
|
||||||
|
float Advance( const char* string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a string of characters
|
||||||
|
*
|
||||||
|
* @param string 'C' style string to be output.
|
||||||
|
*/
|
||||||
|
virtual void render( const char* string );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a string of characters
|
||||||
|
*
|
||||||
|
* @param string wchar_t string to be output.
|
||||||
|
*/
|
||||||
|
virtual void render( const wchar_t* string );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the Font for errors.
|
||||||
|
*
|
||||||
|
* @return The current error code.
|
||||||
|
*/
|
||||||
|
virtual FT_Error Error() const { return err;}
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Constructs the internal glyph cache.
|
||||||
|
*
|
||||||
|
* This a list of glyphs processed for openGL rendering NOT
|
||||||
|
* freetype glyphs
|
||||||
|
*/
|
||||||
|
virtual bool MakeGlyphList() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current face object
|
||||||
|
*/
|
||||||
|
FTFace face;
|
||||||
|
/**
|
||||||
|
* Number of faces in this font
|
||||||
|
*/
|
||||||
|
int numFaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size object
|
||||||
|
*/
|
||||||
|
FTSize charSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object that holds a list of glyphs
|
||||||
|
*/
|
||||||
|
FTGlyphContainer* glyphList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of glyphs in this font
|
||||||
|
*/
|
||||||
|
int numGlyphs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current pen or cursor position;
|
||||||
|
*/
|
||||||
|
FT_Vector pen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current error code. Zero means no error.
|
||||||
|
*/
|
||||||
|
FT_Error err;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTFont__
|
7
src/osgText/FTGL.h
Normal file
7
src/osgText/FTGL.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef __FTGL__
|
||||||
|
#define __FTGL__
|
||||||
|
|
||||||
|
// For Future?
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTGL__
|
70
src/osgText/FTGLBitmapFont.cc
Normal file
70
src/osgText/FTGLBitmapFont.cc
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTGLBitmapFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTBitmapGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTGLBitmapFont::FTGLBitmapFont()
|
||||||
|
: tempGlyph(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLBitmapFont::~FTGLBitmapFont()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
|
||||||
|
bool FTGLBitmapFont::MakeGlyphList()
|
||||||
|
{
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
tempGlyph = new FTBitmapGlyph( *ftGlyph);
|
||||||
|
glyphList->Add( tempGlyph);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = face.Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLBitmapFont::render( const char* string)
|
||||||
|
{
|
||||||
|
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
|
||||||
|
|
||||||
|
// doing this every frame is a bad?
|
||||||
|
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||||
|
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopClientAttrib();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLBitmapFont::render( const wchar_t* string)
|
||||||
|
{
|
||||||
|
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT);
|
||||||
|
|
||||||
|
// doing this every frame is a bad?
|
||||||
|
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE);
|
||||||
|
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopClientAttrib();
|
||||||
|
|
||||||
|
}
|
59
src/osgText/FTGLBitmapFont.h
Normal file
59
src/osgText/FTGLBitmapFont.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef __FTGLBitmapFont__
|
||||||
|
#define __FTGLBitmapFont__
|
||||||
|
|
||||||
|
|
||||||
|
#include "FTFont.h"
|
||||||
|
|
||||||
|
class FTBitmapGlyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGLBitmapFont is a specialisation of the FTFont class for handling
|
||||||
|
* Bitmap fonts
|
||||||
|
*
|
||||||
|
* @see FTFont
|
||||||
|
*/
|
||||||
|
class FTGLBitmapFont : public FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
FTGLBitmapFont();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~FTGLBitmapFont();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a string of characters
|
||||||
|
*
|
||||||
|
* @param string 'C' style string to be output.
|
||||||
|
*/
|
||||||
|
void render( const char* string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a string of characters
|
||||||
|
*
|
||||||
|
* @param string 'C' style string to be output.
|
||||||
|
*/
|
||||||
|
void render( const wchar_t* string);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Constructs the internal glyph cache.
|
||||||
|
*
|
||||||
|
* This a list of glyphs processed for openGL rendering NOT
|
||||||
|
* freetype glyphs
|
||||||
|
*/
|
||||||
|
bool MakeGlyphList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temp variable for a FTBitmapGlyph
|
||||||
|
*/
|
||||||
|
FTBitmapGlyph* tempGlyph;
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // __FTGLBitmapFont__
|
68
src/osgText/FTGLOutlineFont.cc
Normal file
68
src/osgText/FTGLOutlineFont.cc
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTGLOutlineFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
#include "FTOutlineGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTGLOutlineFont::FTGLOutlineFont()
|
||||||
|
: tempGlyph(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLOutlineFont::~FTGLOutlineFont()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool FTGLOutlineFont::MakeGlyphList()
|
||||||
|
{
|
||||||
|
for( unsigned int n = 0; n < numGlyphs; ++n)
|
||||||
|
{
|
||||||
|
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
|
||||||
|
|
||||||
|
if( ftGlyph)
|
||||||
|
{
|
||||||
|
tempGlyph = new FTOutlineGlyph( *ftGlyph);
|
||||||
|
glyphList->Add( tempGlyph);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = face.Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLOutlineFont::render( const char* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable( GL_LINE_SMOOTH);
|
||||||
|
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLOutlineFont::render( const wchar_t* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable( GL_LINE_SMOOTH);
|
||||||
|
glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
|
||||||
|
}
|
37
src/osgText/FTGLOutlineFont.h
Normal file
37
src/osgText/FTGLOutlineFont.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef __FTGLOutlineFont
|
||||||
|
#define __FTGLOutlineFont
|
||||||
|
|
||||||
|
|
||||||
|
#include "FTFont.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FTOutlineGlyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGLOutlineFont is a specialisation of the FTFont class for handling
|
||||||
|
* Vector Outline fonts
|
||||||
|
*
|
||||||
|
* @see FTFont
|
||||||
|
*/
|
||||||
|
class FTGLOutlineFont : public FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTGLOutlineFont();
|
||||||
|
~FTGLOutlineFont();
|
||||||
|
|
||||||
|
void render( const char* string);
|
||||||
|
void render( const wchar_t* string);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
bool MakeGlyphList();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
FTOutlineGlyph* tempGlyph;
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
66
src/osgText/FTGLPixmapFont.cc
Normal file
66
src/osgText/FTGLPixmapFont.cc
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTGLPixmapFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTPixmapGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTGLPixmapFont::FTGLPixmapFont()
|
||||||
|
: tempGlyph(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLPixmapFont::~FTGLPixmapFont()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// OPSignature: bool FTGlyphContainer:MakeGlyphList()
|
||||||
|
bool FTGLPixmapFont::MakeGlyphList()
|
||||||
|
{
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
tempGlyph = new FTPixmapGlyph( *ftGlyph);
|
||||||
|
glyphList->Add( tempGlyph);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = face.Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLPixmapFont::render( const char* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLPixmapFont::render( const wchar_t* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
FTFont::render( string);
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
|
||||||
|
}
|
36
src/osgText/FTGLPixmapFont.h
Normal file
36
src/osgText/FTGLPixmapFont.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __FTGLPixmapFont__
|
||||||
|
#define __FTGLPixmapFont__
|
||||||
|
|
||||||
|
|
||||||
|
#include "FTFont.h"
|
||||||
|
|
||||||
|
class FTPixmapGlyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGLPixmapFont is a specialisation of the FTFont class for handling
|
||||||
|
* Pixmap (Grey Scale) fonts
|
||||||
|
*
|
||||||
|
* @see FTFont
|
||||||
|
*/
|
||||||
|
class FTGLPixmapFont : public FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTGLPixmapFont();
|
||||||
|
~FTGLPixmapFont();
|
||||||
|
|
||||||
|
void render( const char* string);
|
||||||
|
void render( const wchar_t* string);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
bool MakeGlyphList();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
FTPixmapGlyph* tempGlyph;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTGLPixmapFont__
|
35
src/osgText/FTGLPolygonFont.cc
Normal file
35
src/osgText/FTGLPolygonFont.cc
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "FTGLPolygonFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
#include "FTPolyGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FTGLPolygonFont::FTGLPolygonFont()
|
||||||
|
: tempGlyph(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLPolygonFont::~FTGLPolygonFont()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool FTGLPolygonFont::MakeGlyphList()
|
||||||
|
{
|
||||||
|
for( unsigned int n = 0; n < numGlyphs; ++n)
|
||||||
|
{
|
||||||
|
FT_Glyph* ftGlyph = face.Glyph( n, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP);
|
||||||
|
|
||||||
|
if( ftGlyph)
|
||||||
|
{
|
||||||
|
tempGlyph = new FTPolyGlyph( *ftGlyph);
|
||||||
|
glyphList->Add( tempGlyph);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = face.Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !err;
|
||||||
|
}
|
35
src/osgText/FTGLPolygonFont.h
Normal file
35
src/osgText/FTGLPolygonFont.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __FTGLPolygonFont__
|
||||||
|
#define __FTGLPolygonFont__
|
||||||
|
|
||||||
|
#include "FTFont.h"
|
||||||
|
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FTPolyGlyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGLPolygonFont is a specialisation of the FTFont class for handling
|
||||||
|
* tesselated Polygon Mesh fonts
|
||||||
|
*
|
||||||
|
* @see FTFont
|
||||||
|
*/
|
||||||
|
class FTGLPolygonFont : public FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTGLPolygonFont();
|
||||||
|
~FTGLPolygonFont();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
bool MakeGlyphList();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
FTPolyGlyph* tempGlyph;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // __FTGLPolygonFont__
|
210
src/osgText/FTGLTextureFont.cc
Normal file
210
src/osgText/FTGLTextureFont.cc
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTGLTextureFont.h"
|
||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
#include "FTTextureGlyph.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef unsigned long UInt32; // a mac thing?
|
||||||
|
|
||||||
|
inline UInt32 NextPowerOf2( UInt32 in)
|
||||||
|
{
|
||||||
|
in -= 1;
|
||||||
|
|
||||||
|
in |= in >> 16;
|
||||||
|
in |= in >> 8;
|
||||||
|
in |= in >> 4;
|
||||||
|
in |= in >> 2;
|
||||||
|
in |= in >> 1;
|
||||||
|
|
||||||
|
return in + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLTextureFont::FTGLTextureFont()
|
||||||
|
: numTextures(1),
|
||||||
|
textMem(0),
|
||||||
|
padding(1),
|
||||||
|
tempGlyph(0),
|
||||||
|
maxTextSize(0),
|
||||||
|
textureWidth(0),
|
||||||
|
textureHeight(0),
|
||||||
|
glyphHeight(0),
|
||||||
|
glyphWidth(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
FTGLTextureFont::~FTGLTextureFont()
|
||||||
|
{
|
||||||
|
glDeleteTextures( numTextures, (const GLuint*)glTextureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FTGLTextureFont::MakeGlyphList()
|
||||||
|
{
|
||||||
|
if( !maxTextSize)
|
||||||
|
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*)&maxTextSize);
|
||||||
|
|
||||||
|
glyphHeight = ( charSize.Height()) + padding;
|
||||||
|
glyphWidth = ( charSize.Width()) + padding;
|
||||||
|
|
||||||
|
GetSize();
|
||||||
|
int totalMem;
|
||||||
|
|
||||||
|
if( textureHeight > maxTextSize)
|
||||||
|
{
|
||||||
|
numTextures = static_cast<int>( textureHeight / maxTextSize) + 1;
|
||||||
|
if( numTextures > 15) // FIXME
|
||||||
|
numTextures = 15;
|
||||||
|
|
||||||
|
int heightRemain = NextPowerOf2( textureHeight % maxTextSize);
|
||||||
|
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);
|
||||||
|
|
||||||
|
CreateTexture( x, textureWidth, maxTextSize, currTextPtr);
|
||||||
|
|
||||||
|
currTextPtr += ( textureWidth * maxTextSize);
|
||||||
|
++glyphNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
glyphNum = FillGlyphs( glyphNum, glTextureID[numTextures - 1], textureWidth, heightRemain, currTextPtr);
|
||||||
|
CreateTexture( numTextures - 1, textureWidth, heightRemain, currTextPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureHeight = NextPowerOf2( textureHeight);
|
||||||
|
totalMem = textureWidth * textureHeight;
|
||||||
|
|
||||||
|
glGenTextures( numTextures, (GLuint*)&glTextureID[0]);
|
||||||
|
|
||||||
|
textMem = new unsigned char[totalMem]; // GL_ALPHA texture;
|
||||||
|
std::memset( textMem, 0, totalMem);
|
||||||
|
|
||||||
|
FillGlyphs( 0, glTextureID[0], textureWidth, textureHeight, textMem);
|
||||||
|
CreateTexture( 0, textureWidth, textureHeight, textMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] textMem;
|
||||||
|
return !err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int FTGLTextureFont::FillGlyphs( unsigned int glyphStart, int id, int width, int height, unsigned char* textdata)
|
||||||
|
{
|
||||||
|
int currentTextX = padding;
|
||||||
|
int currentTextY = padding;// + padding;
|
||||||
|
|
||||||
|
float currTextU = (float)padding / (float)width;
|
||||||
|
float currTextV = (float)padding / (float)height;
|
||||||
|
|
||||||
|
// numGlyphs = 256; // FIXME hack
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
if( textureWidth > maxTextSize)
|
||||||
|
{
|
||||||
|
textureWidth = maxTextSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int h = static_cast<int>( textureWidth / glyphWidth);
|
||||||
|
textureHeight = (( numGlyphs / h) + 1) * glyphHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLTextureFont::CreateTexture( int id, int width, int height, unsigned char* data)
|
||||||
|
{
|
||||||
|
glPixelStorei( GL_UNPACK_ALIGNMENT, 1); //What does this do exactly?
|
||||||
|
glBindTexture( GL_TEXTURE_2D, glTextureID[id]);
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||||
|
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf( 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLTextureFont::render( const char* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||||
|
|
||||||
|
glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);
|
||||||
|
|
||||||
|
// QUADS are faster!? Less function call overhead?
|
||||||
|
glBegin( GL_QUADS);
|
||||||
|
FTFont::render( string);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FTGLTextureFont::render( const wchar_t* string)
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT | GL_LINE_BIT | GL_PIXEL_MODE_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
|
||||||
|
|
||||||
|
glBindTexture( GL_TEXTURE_2D, (GLuint)FTTextureGlyph::activeTextureID);
|
||||||
|
|
||||||
|
// QUADS are faster!? Less function call overhead?
|
||||||
|
glBegin( GL_QUADS);
|
||||||
|
FTFont::render( string);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
54
src/osgText/FTGLTextureFont.h
Normal file
54
src/osgText/FTGLTextureFont.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef __FTGLTextureFont
|
||||||
|
#define __FTGLTextureFont
|
||||||
|
#include "FTFont.h"
|
||||||
|
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
class FTTextureGlyph;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGLTextureFont is a specialisation of the FTFont class for handling
|
||||||
|
* Texture mapped fonts
|
||||||
|
*
|
||||||
|
* @see FTFont
|
||||||
|
*/
|
||||||
|
class FTGLTextureFont : public FTFont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTGLTextureFont();
|
||||||
|
virtual ~FTGLTextureFont();
|
||||||
|
|
||||||
|
virtual int TextureWidth() const { return textureWidth;}
|
||||||
|
virtual int TextureHeight() const { return textureHeight;}
|
||||||
|
|
||||||
|
virtual void render( const char* string);
|
||||||
|
virtual void render( const wchar_t* string);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
// attributes
|
||||||
|
FTTextureGlyph* tempGlyph;
|
||||||
|
|
||||||
|
long maxTextSize;
|
||||||
|
int textureWidth;
|
||||||
|
int textureHeight;
|
||||||
|
|
||||||
|
unsigned long glTextureID[16];
|
||||||
|
int numTextures;
|
||||||
|
unsigned char* textMem;
|
||||||
|
|
||||||
|
int glyphHeight;
|
||||||
|
int glyphWidth;
|
||||||
|
|
||||||
|
int padding;
|
||||||
|
|
||||||
|
// methods
|
||||||
|
bool MakeGlyphList();
|
||||||
|
void CreateTexture( int id, int width, int height, unsigned char* data);
|
||||||
|
void GetSize();
|
||||||
|
unsigned int FillGlyphs( unsigned int glyphStart, int textID, int textureWidth, int textureHeight, unsigned char* textMem);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
14
src/osgText/FTGlyph.cc
Normal file
14
src/osgText/FTGlyph.cc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTGlyph::FTGlyph()
|
||||||
|
: advance(0),
|
||||||
|
err(0)
|
||||||
|
{
|
||||||
|
pos.x = 0;
|
||||||
|
pos.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FTGlyph::~FTGlyph()
|
||||||
|
{}
|
76
src/osgText/FTGlyph.h
Normal file
76
src/osgText/FTGlyph.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#ifndef __FTGlyph__
|
||||||
|
#define __FTGlyph__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
//#include "FTGL.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGlyph is the base clas 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 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__
|
66
src/osgText/FTGlyphContainer.cc
Normal file
66
src/osgText/FTGlyphContainer.cc
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "FTGlyphContainer.h"
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
#include "FTFace.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTGlyphContainer::FTGlyphContainer( FTFace* f, 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;
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
advance = glyphs[left]->Render( pen);
|
||||||
|
}
|
||||||
|
|
||||||
|
kernAdvance.x = advance + kernAdvance.x; // FIXME float to long
|
||||||
|
// kernAdvance.y = advance.y + kernAdvance.y;
|
||||||
|
return kernAdvance;
|
||||||
|
}
|
100
src/osgText/FTGlyphContainer.h
Normal file
100
src/osgText/FTGlyphContainer.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#ifndef __FTGlyphContainer__
|
||||||
|
#define __FTGlyphContainer__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
//#include "FTGL.h"
|
||||||
|
class FTFace;
|
||||||
|
class FTGlyph;
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTGlyphContainer
|
||||||
|
*
|
||||||
|
* @see FTGlyph
|
||||||
|
*/
|
||||||
|
class FTGlyphContainer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
FTGlyphContainer( FTFace* face, int numGlyphs, bool p = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~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
|
||||||
|
*/
|
||||||
|
FT_Vector& render( unsigned int index, unsigned int next, FT_Vector pen);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FT_Error err;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool preCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int numGlyphs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FTFace* face;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
FT_Vector kernAdvance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
float advance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
vector<FTGlyph*> glyphs;
|
||||||
|
// typedef pair<int, FTGlyph*> CHARREF; // glyphIndex, glyph
|
||||||
|
// vector<CHARREF> glyphs;
|
||||||
|
// map< int, FTGlyph*> CHARREF; // charCode, glyph
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTGlyphContainer__
|
65
src/osgText/FTLibrary.cc
Normal file
65
src/osgText/FTLibrary.cc
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include "FTLibrary.h"
|
||||||
|
#include "FTGL.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;
|
||||||
|
}
|
102
src/osgText/FTLibrary.h
Normal file
102
src/osgText/FTLibrary.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#ifndef __FTLibrary__
|
||||||
|
#define __FTLibrary__
|
||||||
|
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
//#include FT_CACHE_H
|
||||||
|
|
||||||
|
#include "FTGL.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 FTLibrary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
/**
|
||||||
|
* Default constructors.
|
||||||
|
*
|
||||||
|
* Made private to stop clients creating there own FTLibrary
|
||||||
|
* objects.
|
||||||
|
*/
|
||||||
|
FTLibrary();
|
||||||
|
FTLibrary( const FT_Library&){}
|
||||||
|
FTLibrary& operator=( const FT_Library&){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
/**
|
||||||
|
* Freetype library handle.
|
||||||
|
*/
|
||||||
|
FT_Library* lib;
|
||||||
|
// FTC_Manager* manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current error code. Zero means no error.
|
||||||
|
*/
|
||||||
|
FT_Error err;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // __FTLibrary__
|
83
src/osgText/FTOutlineGlyph.cc
Normal file
83
src/osgText/FTOutlineGlyph.cc
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTOutlineGlyph.h"
|
||||||
|
#include "FTVectoriser.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FTOutlineGlyph::FTOutlineGlyph( FT_Glyph glyph)
|
||||||
|
: FTGlyph(),
|
||||||
|
vectoriser(0),
|
||||||
|
numPoints(0),
|
||||||
|
numContours(0),
|
||||||
|
contourLength(0),
|
||||||
|
data(0),
|
||||||
|
glList(0)
|
||||||
|
{
|
||||||
|
if( ft_glyph_format_outline != glyph->format)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vectoriser = new FTVectoriser( glyph);
|
||||||
|
|
||||||
|
vectoriser->Ingest();
|
||||||
|
numContours = vectoriser->contours();
|
||||||
|
contourLength = new int[ numContours];
|
||||||
|
|
||||||
|
for( int cn = 0; cn < numContours; ++cn)
|
||||||
|
{
|
||||||
|
contourLength[cn] = vectoriser->contourSize( cn);
|
||||||
|
}
|
||||||
|
|
||||||
|
numPoints = vectoriser->points();
|
||||||
|
data = new double[ numPoints * 3];
|
||||||
|
vectoriser->Output( data);
|
||||||
|
|
||||||
|
advance = glyph->advance.x >> 16;
|
||||||
|
|
||||||
|
delete vectoriser;
|
||||||
|
|
||||||
|
if ( ( numContours < 1) || ( numPoints < 3))
|
||||||
|
return;
|
||||||
|
|
||||||
|
glList = glGenLists(1);
|
||||||
|
int d = 0;
|
||||||
|
|
||||||
|
glNewList( glList, GL_COMPILE);
|
||||||
|
for( int c = 0; c < numContours; ++c)
|
||||||
|
{
|
||||||
|
glBegin( GL_LINE_LOOP);
|
||||||
|
for( int p = 0; p < ( contourLength[c]); ++p)
|
||||||
|
{
|
||||||
|
glVertex2dv( data + d);
|
||||||
|
d += 3;
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
36
src/osgText/FTOutlineGlyph.h
Normal file
36
src/osgText/FTOutlineGlyph.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef __FTOutlineGlyph__
|
||||||
|
#define __FTOutlineGlyph__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
class FTVectoriser;
|
||||||
|
|
||||||
|
class FTOutlineGlyph : public FTGlyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTOutlineGlyph( FT_Glyph glyph);
|
||||||
|
virtual ~FTOutlineGlyph();
|
||||||
|
virtual float Render( const FT_Vector& pen);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
FTVectoriser* vectoriser;
|
||||||
|
int numPoints;
|
||||||
|
int numContours;
|
||||||
|
int* contourLength;
|
||||||
|
double* data;
|
||||||
|
int glList;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTOutlineGlyph__
|
94
src/osgText/FTPixmapGlyph.cc
Normal file
94
src/osgText/FTPixmapGlyph.cc
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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];
|
||||||
|
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;
|
||||||
|
}
|
35
src/osgText/FTPixmapGlyph.h
Normal file
35
src/osgText/FTPixmapGlyph.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __FTPixmapGlyph__
|
||||||
|
#define __FTPixmapGlyph__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FTPixmapGlyph : public FTGlyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTPixmapGlyph( FT_Glyph glyph);
|
||||||
|
virtual ~FTPixmapGlyph();
|
||||||
|
virtual float Render( const FT_Vector& pen);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
int destWidth;
|
||||||
|
int destHeight;
|
||||||
|
|
||||||
|
int numGreys;
|
||||||
|
|
||||||
|
unsigned char* data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTPixmapGlyph__
|
156
src/osgText/FTPolyGlyph.cc
Normal file
156
src/osgText/FTPolyGlyph.cc
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
#include "GL/glu.h"
|
||||||
|
|
||||||
|
#include "FTPolyGlyph.h"
|
||||||
|
#include "FTVectoriser.h"
|
||||||
|
#include "FTGL.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CALLBACK ftglCombine( GLdouble coords[3], void* vertex_data[4], GLfloat weight[4], void** outData)
|
||||||
|
{
|
||||||
|
double* vertex = new double[3]; // FIXME MEM LEAK
|
||||||
|
|
||||||
|
vertex[0] = coords[0];
|
||||||
|
vertex[1] = coords[1];
|
||||||
|
vertex[2] = coords[2];
|
||||||
|
|
||||||
|
*outData = vertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FTPolyGlyph::FTPolyGlyph( FT_Glyph glyph)
|
||||||
|
: FTGlyph(),
|
||||||
|
vectoriser(0),
|
||||||
|
numPoints(0),
|
||||||
|
numContours(0),
|
||||||
|
contourLength(0),
|
||||||
|
data(0),
|
||||||
|
glList(0)
|
||||||
|
{
|
||||||
|
if( ft_glyph_format_outline != glyph->format)
|
||||||
|
{ return;}
|
||||||
|
|
||||||
|
vectoriser = new FTVectoriser( glyph);
|
||||||
|
|
||||||
|
vectoriser->Ingest();
|
||||||
|
numContours = vectoriser->contours();
|
||||||
|
contourLength = new int[ numContours];
|
||||||
|
|
||||||
|
for( int c = 0; c < numContours; ++c)
|
||||||
|
{
|
||||||
|
contourLength[c] = vectoriser->contourSize( c);
|
||||||
|
}
|
||||||
|
|
||||||
|
numPoints = vectoriser->points();
|
||||||
|
data = new double[ numPoints * 3];
|
||||||
|
vectoriser->Output( data);
|
||||||
|
|
||||||
|
contourFlag = vectoriser->ContourFlag();
|
||||||
|
advance = glyph->advance.x >> 16;
|
||||||
|
|
||||||
|
delete vectoriser;
|
||||||
|
|
||||||
|
if ( ( numContours < 1) || ( numPoints < 3))
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
38
src/osgText/FTPolyGlyph.h
Normal file
38
src/osgText/FTPolyGlyph.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef __FTPolyGlyph__
|
||||||
|
#define __FTPolyGlyph__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
class FTVectoriser;
|
||||||
|
|
||||||
|
class FTPolyGlyph : public FTGlyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTPolyGlyph( FT_Glyph glyph);
|
||||||
|
virtual ~FTPolyGlyph();
|
||||||
|
virtual float Render( const FT_Vector& pen);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
void Tesselate();
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
FTVectoriser* vectoriser;
|
||||||
|
int numPoints;
|
||||||
|
int numContours;
|
||||||
|
int contourFlag;
|
||||||
|
int* contourLength;
|
||||||
|
double* data;
|
||||||
|
int glList;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTPolyGlyph__
|
91
src/osgText/FTSize.cc
Normal file
91
src/osgText/FTSize.cc
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "FTSize.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
FTSize::FTSize()
|
||||||
|
: size(0),
|
||||||
|
ftFace(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;
|
||||||
|
}
|
118
src/osgText/FTSize.h
Normal file
118
src/osgText/FTSize.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#ifndef __FTSize__
|
||||||
|
#define __FTSize__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FTSize class provides an abstraction layer for the Freetype Size.
|
||||||
|
*
|
||||||
|
* @see "Freetype 2 Documentation - 2.0.4"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class 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__
|
92
src/osgText/FTTextureGlyph.cc
Normal file
92
src/osgText/FTTextureGlyph.cc
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "GL/gl.h"
|
||||||
|
|
||||||
|
#include "FTTextureGlyph.h"
|
||||||
|
#include "FTGL.h"
|
||||||
|
|
||||||
|
|
||||||
|
int FTTextureGlyph::activeTextureID = 0;
|
||||||
|
|
||||||
|
FTTextureGlyph::FTTextureGlyph( FT_Glyph glyph, int id, unsigned char* data, int stride, int height, float u, float v)
|
||||||
|
: FTGlyph(),
|
||||||
|
destWidth(0),
|
||||||
|
destHeight(0),
|
||||||
|
numGreys(0),
|
||||||
|
glTextureID(id)
|
||||||
|
{
|
||||||
|
// This function will always fail if the glyph's format isn't scalable????
|
||||||
|
err = FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1);
|
||||||
|
if( err || glyph->format != ft_glyph_format_bitmap)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// This could be really ugly!!
|
||||||
|
if( activeTextureID != glTextureID)
|
||||||
|
{
|
||||||
|
glEnd();
|
||||||
|
glBindTexture( GL_TEXTURE_2D, (GLuint)glTextureID);
|
||||||
|
activeTextureID = 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);
|
||||||
|
|
||||||
|
return advance;
|
||||||
|
}
|
40
src/osgText/FTTextureGlyph.h
Normal file
40
src/osgText/FTTextureGlyph.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef __FTTextureGlyph__
|
||||||
|
#define __FTTextureGlyph__
|
||||||
|
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FTTextureGlyph : public FTGlyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTTextureGlyph( FT_Glyph glyph, int id, unsigned char* data, int stride, int height, float u, float v);
|
||||||
|
virtual ~FTTextureGlyph();
|
||||||
|
virtual float Render( const FT_Vector& pen);
|
||||||
|
|
||||||
|
static int activeTextureID;
|
||||||
|
private:
|
||||||
|
// attributes
|
||||||
|
// What about the other point class in vectoriser?
|
||||||
|
struct FTPoint
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
int destWidth;
|
||||||
|
int destHeight;
|
||||||
|
|
||||||
|
int numGreys;
|
||||||
|
|
||||||
|
FTPoint uv[2];
|
||||||
|
int glTextureID;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FTTextureGlyph__
|
227
src/osgText/FTVectoriser.cc
Normal file
227
src/osgText/FTVectoriser.cc
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
#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( const FT_Glyph glyph)
|
||||||
|
: contourFlag(0),
|
||||||
|
contour(0),
|
||||||
|
kBSTEPSIZE( 0.2)
|
||||||
|
{
|
||||||
|
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
|
||||||
|
ftOutline = outline->outline;
|
||||||
|
|
||||||
|
contourList.reserve( ftOutline.n_contours);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FTVectoriser::~FTVectoriser()
|
||||||
|
{
|
||||||
|
for( int c = 0; c < contours(); ++c)
|
||||||
|
{
|
||||||
|
delete contourList[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
contourList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FTVectoriser::points()
|
||||||
|
{
|
||||||
|
int s = 0;
|
||||||
|
for( int c = 0; c < contours(); ++c)
|
||||||
|
{
|
||||||
|
s += contourList[c]->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FTVectoriser::Ingest()
|
||||||
|
{
|
||||||
|
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::Output( 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
src/osgText/FTVectoriser.h
Normal file
104
src/osgText/FTVectoriser.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#ifndef __FTVectoriser__
|
||||||
|
#define __FTVectoriser__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include "FTGlyph.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class ftPoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ftPoint()
|
||||||
|
: x(0), y(0), z(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ftPoint( const float X, const float Y, const float Z)
|
||||||
|
: x(X), y(Y), z(Z)
|
||||||
|
{}
|
||||||
|
|
||||||
|
friend bool operator == ( const ftPoint &a, const ftPoint &b)
|
||||||
|
{
|
||||||
|
return((a.x == b.x) && (a.y == b.y) && (a.z == b.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator != ( const ftPoint &a, const ftPoint &b)
|
||||||
|
{
|
||||||
|
return((a.x != b.x) || (a.y != b.y) || (a.z != b.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
float x, y, z; // FIXME make private
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FTContour
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTContour();
|
||||||
|
~FTContour();
|
||||||
|
|
||||||
|
void AddPoint( const float x, const float y);
|
||||||
|
|
||||||
|
int size() const { return pointList.size();}
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
vector< ftPoint> pointList;
|
||||||
|
float ctrlPtArray[4][2];
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
const unsigned int kMAXPOINTS;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FTVectoriser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// methods
|
||||||
|
FTVectoriser( FT_Glyph glyph);
|
||||||
|
virtual ~FTVectoriser();
|
||||||
|
|
||||||
|
bool Ingest();
|
||||||
|
void Output( double* d);
|
||||||
|
int points();
|
||||||
|
int contours() const { return contourList.size();}
|
||||||
|
int contourSize( int c) const { return contourList[c]->size();}
|
||||||
|
int ContourFlag() const { return contourFlag;}
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
|
||||||
|
private:
|
||||||
|
// methods
|
||||||
|
int Conic( const int index, const int first, const int last);
|
||||||
|
int Cubic( const int index, const int first, const int last);
|
||||||
|
void deCasteljau( const float t, const int n);
|
||||||
|
void evaluateCurve( const int n);
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
vector< const FTContour*> contourList;
|
||||||
|
|
||||||
|
FTContour* contour;
|
||||||
|
int contourFlag;
|
||||||
|
|
||||||
|
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__
|
29
src/osgText/Makefile
Normal file
29
src/osgText/Makefile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!smake
|
||||||
|
include ../../Make/makedefs
|
||||||
|
|
||||||
|
C++FILES = \
|
||||||
|
GLUTEventAdapter.cpp\
|
||||||
|
Version.cpp\
|
||||||
|
Window.cpp\
|
||||||
|
Viewer.cpp\
|
||||||
|
|
||||||
|
TARGET_BASENAME = osgGLUT
|
||||||
|
|
||||||
|
|
||||||
|
LIBS = -L../../lib -losgDB -losgUtil -losg $(GLUTLIB) -lGLU -lGL -lm
|
||||||
|
|
||||||
|
LIB = ../../lib/lib$(TARGET_BASENAME).so
|
||||||
|
#LIB = ../../lib/lib$(TARGET_BASENAME).a
|
||||||
|
|
||||||
|
TARGET_LIB_FILES = lib$(TARGET_BASENAME).so
|
||||||
|
TARGET_INCLUDE_FILES = \
|
||||||
|
osgGLUT/Export\
|
||||||
|
osgGLUT/GLUTEventAdapter\
|
||||||
|
osgGLUT/Version\
|
||||||
|
osgGLUT/Window\
|
||||||
|
osgGLUT/Viewer\
|
||||||
|
|
||||||
|
C++FLAGS += -I ../../include
|
||||||
|
|
||||||
|
include ../../Make/makerules
|
||||||
|
|
665
src/osgText/Text.cpp
Normal file
665
src/osgText/Text.cpp
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* openscenegraph textLib / FTGL
|
||||||
|
*
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* prog: max rheiner;mrn@paus.ch
|
||||||
|
* date: 4/25/2001 (m/d/y)
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <osgText/Text.h>
|
||||||
|
|
||||||
|
using namespace osgText;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Font
|
||||||
|
Font::
|
||||||
|
Font()
|
||||||
|
{
|
||||||
|
_init=false;
|
||||||
|
_font=NULL;
|
||||||
|
_created=false;
|
||||||
|
|
||||||
|
_pointSize=14;
|
||||||
|
_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();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::
|
||||||
|
open(const std::string& font)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
_font=createFontObj();
|
||||||
|
if( _font!=NULL && _font->Open(font.c_str()) )
|
||||||
|
{
|
||||||
|
_init=true;
|
||||||
|
_fontName=font;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::
|
||||||
|
create(int pointSize,const unsigned int res)
|
||||||
|
{
|
||||||
|
_pointSize=pointSize;
|
||||||
|
_res=res;
|
||||||
|
|
||||||
|
return create();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Font::
|
||||||
|
create()
|
||||||
|
{
|
||||||
|
if(_init)
|
||||||
|
{
|
||||||
|
if(_font->FaceSize(_pointSize,_res))
|
||||||
|
{
|
||||||
|
_created=true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::
|
||||||
|
output(const char* text)
|
||||||
|
{
|
||||||
|
if(_created)
|
||||||
|
_font->render(text);
|
||||||
|
else
|
||||||
|
create(_pointSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
_init=false;
|
||||||
|
|
||||||
|
if(_font)
|
||||||
|
{
|
||||||
|
delete _font;
|
||||||
|
_font=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fontName="";
|
||||||
|
}
|
||||||
|
|
||||||
|
float Font::
|
||||||
|
getWidth(const char* text) const
|
||||||
|
{
|
||||||
|
if(_init && _created)
|
||||||
|
return _font->Advance(text);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Font::
|
||||||
|
getHeight() const
|
||||||
|
{
|
||||||
|
if(_init && _created)
|
||||||
|
return _pointSize;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
_pointSize=point_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PixmapFont
|
||||||
|
|
||||||
|
TextureFont::
|
||||||
|
TextureFont(const std::string& font,
|
||||||
|
int point_size):
|
||||||
|
RasterFont(font)
|
||||||
|
{
|
||||||
|
if(init(font))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
_pointSize=point_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FTFont* TextureFont::
|
||||||
|
createFontObj(void)
|
||||||
|
{
|
||||||
|
return (FTFont*)(new FTGLTextureFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PixmapFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// _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;
|
||||||
|
}
|
||||||
|
|
||||||
|
FTFont* PolygonFont::
|
||||||
|
createFontObj(void)
|
||||||
|
{
|
||||||
|
return (FTFont*)(new FTGLPolygonFont);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// PolygonFont
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Text
|
||||||
|
Text::
|
||||||
|
Text()
|
||||||
|
{
|
||||||
|
setDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
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::
|
||||||
|
setDefaults()
|
||||||
|
{
|
||||||
|
_init=false;
|
||||||
|
|
||||||
|
_pos.set(0,0,0);
|
||||||
|
_alignementPos.set(0,0,0);
|
||||||
|
|
||||||
|
_fontType=UNDEF;
|
||||||
|
_alignement=LEFT_BOTTOM;
|
||||||
|
_drawMode=DrawModeType::DEFAULT;
|
||||||
|
|
||||||
|
_boundingBoxType=GLYPH;
|
||||||
|
_boundingBoxType=GEOMETRY;
|
||||||
|
|
||||||
|
_initAlignement=false;
|
||||||
|
|
||||||
|
_useDisplayList=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool Text::
|
||||||
|
computeBound() const
|
||||||
|
{
|
||||||
|
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 + 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
drawImmediateMode(State& state)
|
||||||
|
{
|
||||||
|
if(!_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!_font->isCreated())
|
||||||
|
{
|
||||||
|
_font->create();
|
||||||
|
dirtyBound();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_initAlignement)
|
||||||
|
initAlignement();
|
||||||
|
|
||||||
|
// draw boundingBox
|
||||||
|
if(_drawMode & BOUNDINGBOX)
|
||||||
|
drawBoundingBox();
|
||||||
|
// draw alignement
|
||||||
|
if(_drawMode & ALIGNEMENT)
|
||||||
|
drawAlignement();
|
||||||
|
|
||||||
|
// draw boundingBox
|
||||||
|
if(_drawMode & TEXT)
|
||||||
|
{
|
||||||
|
Vec3 drawPos(_pos+_alignementPos);
|
||||||
|
glPushMatrix();
|
||||||
|
switch(_fontType)
|
||||||
|
{
|
||||||
|
case POLYGON:
|
||||||
|
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
|
||||||
|
_font->output(_text.c_str());
|
||||||
|
break;
|
||||||
|
case OUTLINE:
|
||||||
|
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
|
||||||
|
_font->output(_text.c_str());
|
||||||
|
break;
|
||||||
|
case BITMAP:
|
||||||
|
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
|
||||||
|
_font->output(_text.c_str());
|
||||||
|
break;
|
||||||
|
case PIXMAP:
|
||||||
|
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
|
||||||
|
_font->output(_text.c_str());
|
||||||
|
break;
|
||||||
|
case TEXTURE:
|
||||||
|
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
|
||||||
|
_font->output(_text.c_str());
|
||||||
|
break;
|
||||||
|
|
||||||
|
};
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
drawBoundingBox(void)
|
||||||
|
{
|
||||||
|
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::
|
||||||
|
drawAlignement(void)
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
|
||||||
|
glVertex3f(_pos.x(),_pos.y() - size,_pos.z());
|
||||||
|
glVertex3f(_pos.x(),_pos.y() + size,_pos.z());
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
setPosition(const Vec3& pos)
|
||||||
|
{
|
||||||
|
_pos=pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
setPosition(const Vec2& pos)
|
||||||
|
{
|
||||||
|
setPosition(Vec3(pos.x(),pos.y(),0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
calcBounds(Vec3* min,Vec3* max) const
|
||||||
|
{
|
||||||
|
if(!_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int h=_font->getHeight();
|
||||||
|
int w=_font->getWidth(_text.c_str());
|
||||||
|
int descender=_font->getDescender();
|
||||||
|
|
||||||
|
min->set(0,descender,0);
|
||||||
|
max->set(w,h + descender ,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Text::
|
||||||
|
initAlignement(void)
|
||||||
|
{
|
||||||
|
if(!_init)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// culling
|
||||||
|
if(_font->isCreated())
|
||||||
|
{ // ready to get the siz
|
||||||
|
_bbox.init();
|
||||||
|
|
||||||
|
Vec3 min,max;
|
||||||
|
initAlignement(&min,&max);
|
||||||
|
|
||||||
|
_bbox.expandBy(min);
|
||||||
|
_bbox.expandBy(max);
|
||||||
|
|
||||||
|
_bbox_computed=true;
|
||||||
|
|
||||||
|
_initAlignement=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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
initAlignement(Vec3* min,Vec3* max)
|
||||||
|
{
|
||||||
|
if(!_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int h=_font->getHeight();
|
||||||
|
int w=_font->getWidth(_text.c_str());
|
||||||
|
int descender=_font->getDescender();
|
||||||
|
|
||||||
|
min->set(0,descender,0);
|
||||||
|
max->set(w,h + descender ,0);
|
||||||
|
|
||||||
|
switch(_boundingBoxType)
|
||||||
|
{
|
||||||
|
case GLYPH:
|
||||||
|
h+=descender;
|
||||||
|
switch(_alignement)
|
||||||
|
{
|
||||||
|
case LEFT_TOP:
|
||||||
|
_alignementPos.set(0,h,0);
|
||||||
|
break;
|
||||||
|
case LEFT_CENTER:
|
||||||
|
_alignementPos.set(0,h/2,0);
|
||||||
|
break;
|
||||||
|
case LEFT_BOTTOM:
|
||||||
|
_alignementPos.set(0,0,0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CENTER_TOP:
|
||||||
|
_alignementPos.set(w/2,h,0);
|
||||||
|
break;
|
||||||
|
case CENTER_CENTER:
|
||||||
|
_alignementPos.set(w/2,h/2,0);
|
||||||
|
break;
|
||||||
|
case CENTER_BOTTOM:
|
||||||
|
_alignementPos.set(w/2,0,0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT_TOP:
|
||||||
|
_alignementPos.set(w,h,0);
|
||||||
|
break;
|
||||||
|
case RIGHT_CENTER:
|
||||||
|
_alignementPos.set(w,h/2,0);
|
||||||
|
break;
|
||||||
|
case RIGHT_BOTTOM:
|
||||||
|
_alignementPos.set(w,0,0);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
_alignementPos=-_alignementPos;
|
||||||
|
|
||||||
|
*min+=_pos+_alignementPos;
|
||||||
|
*max+=_pos+_alignementPos;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GEOMETRY:
|
||||||
|
switch(_alignement)
|
||||||
|
{
|
||||||
|
case LEFT_TOP:
|
||||||
|
_alignementPos.set(0,h + descender,0);
|
||||||
|
break;
|
||||||
|
case LEFT_CENTER:
|
||||||
|
_alignementPos.set(0,(max->y()-min->y()) /2 + descender,0);
|
||||||
|
break;
|
||||||
|
case LEFT_BOTTOM:
|
||||||
|
_alignementPos.set(0,descender,0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CENTER_TOP:
|
||||||
|
_alignementPos.set(w/2,h + descender,0);
|
||||||
|
break;
|
||||||
|
case CENTER_CENTER:
|
||||||
|
_alignementPos.set(w/2,(max->y()-min->y()) /2 + descender,0);
|
||||||
|
break;
|
||||||
|
case CENTER_BOTTOM:
|
||||||
|
_alignementPos.set(w/2,descender,0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RIGHT_TOP:
|
||||||
|
_alignementPos.set(w,h + descender,0);
|
||||||
|
break;
|
||||||
|
case RIGHT_CENTER:
|
||||||
|
_alignementPos.set(w,(max->y()-min->y()) /2 + descender,0);
|
||||||
|
break;
|
||||||
|
case RIGHT_BOTTOM:
|
||||||
|
_alignementPos.set(w,descender,0);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
_alignementPos=-_alignementPos;
|
||||||
|
|
||||||
|
*min+=_pos+_alignementPos;
|
||||||
|
*max+=_pos+_alignementPos;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch(_fontType)
|
||||||
|
{
|
||||||
|
case BITMAP:
|
||||||
|
break;
|
||||||
|
case PIXMAP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
setAlignement(int alignement)
|
||||||
|
{
|
||||||
|
_alignement=alignement;
|
||||||
|
|
||||||
|
if(!_init || !_font->isCreated())
|
||||||
|
return;
|
||||||
|
|
||||||
|
initAlignement();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::
|
||||||
|
setBoundingBox(int mode)
|
||||||
|
{
|
||||||
|
_boundingBoxType=mode;
|
||||||
|
|
||||||
|
if(!_init || !_font->isCreated())
|
||||||
|
return;
|
||||||
|
|
||||||
|
initAlignement();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
Loading…
Reference in New Issue
Block a user