From Tree, support for encoded text added into osgText.

This commit is contained in:
Robert Osfield
2003-01-08 15:22:17 +00:00
parent ba34880464
commit c5d3c860d8
14 changed files with 495 additions and 98 deletions

View File

@@ -131,6 +131,9 @@ Alberto Barbati <abarbati@iaanus.com>
Gideon May <gideon@computer.org>
- fixed spacing in osgText.
Tree <tree@stain.org>
- support for encoded text types in osgText.
Indirect Contributors
---------------------

2
NEWS
View File

@@ -33,6 +33,8 @@ OSG News (most significant items from ChangeLog)
fields.
Improvements to the GEO loaders.
Support for encoded text types in osgText.
13th November 2002 - OpenSceneGraph-0.9.2.tar.gz

View File

@@ -169,6 +169,10 @@ SOURCE=..\..\src\osgText\FTVectoriser.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\EncodedText.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgText\Paragraph.cpp
# End Source File
# Begin Source File
@@ -269,6 +273,10 @@ SOURCE=..\..\src\osgText\FTVectoriser.h
# End Source File
# Begin Source File
SOURCE=..\..\include\osgText\EncodedText
# End Source File
# Begin Source File
SOURCE=..\..\include\osgText\Paragraph
# End Source File
# Begin Source File

View File

@@ -0,0 +1,75 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
/* --------------------------------------------------------------------------
*
* openscenegraph textLib / FTGL wrapper (http://homepages.paradise.net.nz/henryj/code/)
*
* --------------------------------------------------------------------------
*
* prog: max rheiner;mrn@paus.ch
* date: 4/25/2001 (m/d/y)
*
* --------------------------------------------------------------------------
*
* --------------------------------------------------------------------------
*/
#ifndef OSGTEXT_ENCODEDTEXT
#define OSGTEXT_ENCODEDTEXT 1
#include <osg/Referenced>
#include <vector>
#include <osgText/Export>
namespace osgText {
class OSGTEXT_EXPORT EncodedText : public osg::Referenced
{
public:
/**
* Types of string encodings supported
*/
enum Encoding
{
ENCODING_UNDEFINED, /// not using Unicode
ENCODING_ASCII = ENCODING_UNDEFINED,/// unsigned char ASCII
ENCODING_UTF8, /// 8-bit unicode transformation format
ENCODING_UTF16, /// 16-bit signature
ENCODING_UTF16_BE, /// 16-bit big-endian
ENCODING_UTF16_LE, /// 16-bit little-endian
ENCODING_UTF32, /// 32-bit signature
ENCODING_UTF32_BE, /// 32-bit big-endian
ENCODING_UTF32_LE, /// 32-bit little-endian
ENCODING_SIGNATURE, /// detect encoding from signature
};
EncodedText();
void setOverrideEncoding(Encoding encoding);
Encoding getOverrideEncoding() const { return _overrideEncoding; }
Encoding getEncoding() const { return _encoding; }
void setText(const unsigned char* text);
std::vector<int>::const_iterator getUnicodeText() const { return _unicodeText.begin(); }
protected:
int getNextCharacter(const unsigned char*& charString) const;
/// This method will extract any ZWNBSP signature at the start of the string
Encoding findEncoding(const unsigned char*& charString) const;
Encoding _encoding;
Encoding _overrideEncoding;
std::vector<int> _unicodeText;
};
}
#endif // OSGTEXT_TEXT

View File

@@ -45,7 +45,7 @@ namespace osgText {
virtual const char* libraryName() const { return #library; } \
virtual const char* className() const { return #name; } \
class EncodedText;
class OSGTEXT_EXPORT Font : public osg::Object
{
@@ -73,12 +73,12 @@ class OSGTEXT_EXPORT Font : public osg::Object
virtual bool create(osg::State& state,int pointSize, unsigned int res = 72 );
virtual bool create(osg::State& state);
virtual void output(osg::State& state,const char* text) const;
virtual void output(osg::State& state, const EncodedText* text) const;
virtual bool isOk(void) const { return _init; }
virtual bool isCreated(void) const { return isOk() && _created; }
virtual float getWidth(const char* text) const;
virtual float getWidth(const EncodedText* text) const;
virtual int getHeight() const;
virtual int getDescender() const;
virtual int getAscender() const;

View File

@@ -26,6 +26,7 @@
#include <osg/Vec2>
#include <osgText/Font>
#include <osgText/EncodedText>
#include <string>
@@ -107,8 +108,8 @@ class OSGTEXT_EXPORT Text : public osg::Drawable
Font* getFont() { return _font.get(); }
const Font* getFont() const { return _font.get(); }
void setText(const char* text) { _text=text; _initAlignment=false; }
void setText(const std::string& text) { _text=text; _initAlignment=false; }
void setText(const char* text);
void setText(const std::string& text);
const std::string& getText() const { return _text; }
virtual bool supports(PrimitiveFunctor& pf) const;
@@ -120,6 +121,8 @@ class OSGTEXT_EXPORT Text : public osg::Drawable
const osg::Vec3& getAlignmentPos() const { return _alignmentPos; };
void setEncodedText(EncodedText* encodedText) { _encodedText = encodedText; }
const EncodedText* getEncodedText() const { return _encodedText.get(); }
protected:
@@ -152,6 +155,8 @@ class OSGTEXT_EXPORT Text : public osg::Drawable
int _boundingBoxType;
AxisAlignment _axisAlignment;
osg::ref_ptr<EncodedText> _encodedText;
osg::Vec3 _pos;
osg::Vec3 _alignmentPos;
osg::Vec4 _color;

241
src/osgText/EncodedText.cpp Normal file
View File

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

View File

@@ -105,7 +105,6 @@ int FTFont::Descender() const
return charSize.Descender();
}
// mrn@changes
float FTFont::Advance( const wchar_t* string)
{
@@ -130,7 +129,6 @@ float FTFont::Advance( const char* string)
{
// all are the same, a bit a hack
FTGlyphContainer* glyphList=_contextGlyphList[0];
const unsigned char* c = (unsigned char*)string; // This is ugly, what is the c++ way?
float width = 0;
@@ -143,6 +141,21 @@ float FTFont::Advance( const char* string)
return width;
}
float FTFont::Advance( std::vector<int>::const_iterator string)
{
// all are the same, a bit a hack
FTGlyphContainer* glyphList=_contextGlyphList[0];
std::vector<int>::const_iterator c = string;
float width = 0;
while( *c)
{
width += glyphList->Advance( *c, *(c + 1));
c++;
}
return width;
}
// mrn@changes
void FTFont::render( const char* string , unsigned int renderContext)
@@ -184,3 +197,22 @@ void FTFont::render( const wchar_t* string , unsigned int renderContext)
++c;
}
}
void FTFont::render( std::vector<int>::const_iterator string , unsigned int renderContext)
{
FTGlyphContainer* glyphList=_contextGlyphList[renderContext];
std::vector<int>::const_iterator c = string;
FT_Vector kernAdvance;
pen.x = 0; pen.y = 0;
while( *c)
{
kernAdvance = glyphList->render( *c, *(c + 1), pen);
pen.x += kernAdvance.x;
pen.y += kernAdvance.y;
c++;
}
}

View File

@@ -96,7 +96,7 @@ class FTGL_EXPORT FTFont
* @return Descender height
*/
virtual int Descender() const;
/**
* Gets the advance width for a string.
*
@@ -108,11 +108,19 @@ class FTGL_EXPORT FTFont
/**
* Gets the advance width for a string.
*
* param string a char string
* @param string a char string
* @return advance width
*/
float Advance( const char* string);
/**
* Gets the advance width for a string.
*
* @param string a pointer to an array of decoded unicode characters
* @return advance width
*/
float Advance( std::vector<int>::const_iterator string);
/**
* Renders a string of characters
*
@@ -121,6 +129,14 @@ class FTGL_EXPORT FTFont
// mrn@changes
virtual void render( const char* string , unsigned int renderContext=0);
/**
* Renders a string of characters
*
* @param string unicode string to be output.
*/
// mrn@changes
virtual void render( std::vector<int>::const_iterator string , unsigned int renderContext=0);
/**
* Renders a string of characters
*
@@ -136,7 +152,6 @@ class FTGL_EXPORT FTFont
*/
virtual FT_Error Error() const { return err;}
protected:
/**
* Constructs the internal glyph cache.

View File

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

View File

@@ -1,64 +1,64 @@
#include "FTLibrary.h"
#include "FTLibrary.h"
FTLibrary& FTLibrary::Instance()
FTLibrary& FTLibrary::Instance()
{
static FTLibrary ftlib;
return ftlib;
static FTLibrary ftlib;
return ftlib;
}
FTLibrary::~FTLibrary()
{
if( lib != 0)
{
FT_Done_FreeType( *lib);
if( lib != 0)
{
FT_Done_FreeType( *lib);
delete lib;
lib= 0;
}
delete lib;
lib= 0;
}
// if( manager != 0)
// {
// FTC_Manager_Done( manager );
// if( manager != 0)
// {
// FTC_Manager_Done( manager );
//
// delete manager;
// manager= 0;
// }
// delete manager;
// manager= 0;
// }
}
FTLibrary::FTLibrary()
: lib(0),
err(0)
: lib(0),
err(0)
{
Init();
Init();
}
bool FTLibrary::Init()
{
if( lib != 0 )
return true;
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;
// }
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;
return true;
}

View File

@@ -14,6 +14,7 @@
#include <osgText/Font>
#include <osgText/EncodedText>
#include <osg/Notify>
#include <osgDB/FileUtils>
@@ -174,10 +175,10 @@ bool Font::create(osg::State& state)
return false;
}
void Font::output(osg::State& state,const char* text) const
void Font::output(osg::State& state, const EncodedText* text) const
{
if(_created)
_font->render(text,state.getContextID());
_font->render(text->getUnicodeText(),state.getContextID());
else
{
// ahhhh, this is bit doddy, the draw is potentially
@@ -201,10 +202,10 @@ void Font::clear()
}
float Font::
getWidth(const char* text) const
getWidth(const EncodedText* text) const
{
if(_init && _created)
return _font->Advance(text);
return _font->Advance(text->getUnicodeText());
else
return -1;
}
@@ -236,7 +237,6 @@ getAscender() const
return -1;
}
// Font
///////////////////////////////////////////////////////////////////////////////

View File

@@ -2,28 +2,29 @@ TOPDIR = ../..
include $(TOPDIR)/Make/makedefs
CXXFILES =\
FTBitmapGlyph.cpp \
FTCharmap.cpp \
FTFace.cpp \
FTFont.cpp \
FTGLBitmapFont.cpp \
FTGLOutlineFont.cpp \
FTGLPixmapFont.cpp \
FTGLPolygonFont.cpp \
FTGLTextureFont.cpp \
FTGlyphContainer.cpp \
FTGlyph.cpp \
FTLibrary.cpp \
FTOutlineGlyph.cpp \
FTPixmapGlyph.cpp \
FTPolyGlyph.cpp \
FTSize.cpp \
FTTextureGlyph.cpp \
FTVectoriser.cpp \
Font.cpp \
Paragraph.cpp \
Text.cpp \
Version.cpp
FTBitmapGlyph.cpp \
FTCharmap.cpp \
FTFace.cpp \
FTFont.cpp \
FTGLBitmapFont.cpp \
FTGLOutlineFont.cpp \
FTGLPixmapFont.cpp \
FTGLPolygonFont.cpp \
FTGLTextureFont.cpp \
FTGlyphContainer.cpp \
FTGlyph.cpp \
FTLibrary.cpp \
FTOutlineGlyph.cpp \
FTPixmapGlyph.cpp \
FTPolyGlyph.cpp \
FTSize.cpp \
FTTextureGlyph.cpp \
FTVectoriser.cpp \
EncodedText.cpp \
Font.cpp \
Paragraph.cpp \
Text.cpp \
Version.cpp
@@ -33,14 +34,14 @@ DEF += -DOSGTEXT_LIBRARY
ifneq ($(OS),HP-UX)
INC += -I$(OSGHOME)/include \
-I/usr/include/freetype2 \
-I/usr/local/include \
-I/usr/local/include/freetype2 \
-I/usr/freeware/include \
-I/usr/freeware/include/freetype2
-I/usr/include/freetype2 \
-I/usr/local/include \
-I/usr/local/include/freetype2 \
-I/usr/freeware/include \
-I/usr/freeware/include/freetype2
LINKARGS += -L/usr/local/lib\
-L/usr/freeware/lib$(ARCH)
-L/usr/freeware/lib$(ARCH)
else
INC += $(FREETYPE_INCLUDE)
endif

View File

@@ -46,6 +46,7 @@ Text::Text(const Text& text,const osg::CopyOp& copyop):
_drawMode(text._drawMode),
_boundingBoxType(text._boundingBoxType),
_axisAlignment(text._axisAlignment),
_encodedText(text._encodedText),
_pos(text._pos),
_alignmentPos(text._alignmentPos),
_color(text._color)
@@ -127,8 +128,9 @@ setDefaults()
_initAlignment=false;
_useDisplayList=false;
_encodedText = new EncodedText();
}
bool Text::computeBound() const
@@ -187,8 +189,6 @@ void Text::accept(PrimitiveFunctor& functor) const
functor.setVertexArray(4,boundingVertices);
functor.drawArrays( GL_QUADS, 0, 4);
cout << "done draw arrays"<<endl;
}
void Text::drawImplementation(State& state) const
@@ -234,27 +234,27 @@ void Text::drawImplementation(State& state) const
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,_text.c_str());
_font->output(state,getEncodedText());
break;
case OUTLINE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,_text.c_str());
_font->output(state,getEncodedText());
break;
case BITMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(state,_text.c_str());
_font->output(state,getEncodedText());
break;
case PIXMAP:
glRasterPos3f(drawPos.x(),drawPos.y(),drawPos.z());
_font->output(state,_text.c_str());
_font->output(state,getEncodedText());
break;
case TEXTURE:
glTranslatef(drawPos.x(),drawPos.y(),drawPos.z());
if(_axisAlignment==XZ_PLANE) glRotatef(90.0f,1.0f,0.0f,0.0f);
else if (_axisAlignment==YZ_PLANE) { glRotatef(90.0f,0.0f,0.0f,1.0f); glRotatef(90.0f,1.0f,0.0f,0.0f);}
_font->output(state,_text.c_str());
_font->output(state,getEncodedText());
break;
};
@@ -320,7 +320,7 @@ calcBounds(Vec3* min,Vec3* max) const
return;
float h=_font->getHeight();
float w=_font->getWidth(_text.c_str());
float w=_font->getWidth(getEncodedText());
float descender=_font->getDescender();
min->set(0,descender,0);
@@ -369,7 +369,7 @@ initAlignment(Vec3* min,Vec3* max)
return;
float h=_font->getHeight();
float w=_font->getWidth(_text.c_str());
float w=_font->getWidth(getEncodedText());
float descender=_font->getDescender();
min->set(0,descender,0);
@@ -492,5 +492,20 @@ setBoundingBox(int mode)
initAlignment();
}
void Text::
setText(const char* text)
{
_text=text;
_initAlignment=false;
_encodedText->setText((const unsigned char*)text);
}
void Text::
setText(const std::string& text)
{
_text=text;
_initAlignment=false;
_encodedText->setText((const unsigned char*)_text.data());
}
// Text
///////////////////////////////////////////////////////////////////////////////