diff --git a/AUTHORS b/AUTHORS index 7f6ffb2f8..017c35b6b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -131,6 +131,9 @@ Alberto Barbati Gideon May - fixed spacing in osgText. + +Tree + - support for encoded text types in osgText. Indirect Contributors --------------------- diff --git a/NEWS b/NEWS index 1bf2d6199..ef8871241 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/VisualStudio/osgText/osgText.dsp b/VisualStudio/osgText/osgText.dsp index 48374fda9..dabf18015 100644 --- a/VisualStudio/osgText/osgText.dsp +++ b/VisualStudio/osgText/osgText.dsp @@ -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 diff --git a/include/osgText/EncodedText b/include/osgText/EncodedText new file mode 100644 index 000000000..79dba6e76 --- /dev/null +++ b/include/osgText/EncodedText @@ -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 + +#include + +#include + +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::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 _unicodeText; +}; + +} + +#endif // OSGTEXT_TEXT diff --git a/include/osgText/Font b/include/osgText/Font index 9f2445b95..1eb936d10 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -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; diff --git a/include/osgText/Text b/include/osgText/Text index dd3a413e7..1eeeafef2 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -26,6 +26,7 @@ #include #include +#include #include @@ -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; + osg::Vec3 _pos; osg::Vec3 _alignmentPos; osg::Vec4 _color; diff --git a/src/osgText/EncodedText.cpp b/src/osgText/EncodedText.cpp new file mode 100644 index 000000000..ae4f5557e --- /dev/null +++ b/src/osgText/EncodedText.cpp @@ -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 + +#include + +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."<::const_iterator string) +{ + // all are the same, a bit a hack + FTGlyphContainer* glyphList=_contextGlyphList[0]; + std::vector::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::const_iterator string , unsigned int renderContext) +{ + FTGlyphContainer* glyphList=_contextGlyphList[renderContext]; + + std::vector::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++; + } +} + diff --git a/src/osgText/FTFont.h b/src/osgText/FTFont.h index 94be53639..481847887 100644 --- a/src/osgText/FTFont.h +++ b/src/osgText/FTFont.h @@ -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::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::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. diff --git a/src/osgText/FTGlyph.cpp b/src/osgText/FTGlyph.cpp index 73f9f1ccc..593fa6d29 100644 --- a/src/osgText/FTGlyph.cpp +++ b/src/osgText/FTGlyph.cpp @@ -1,20 +1,20 @@ -#include "FTGlyph.h" +#include "FTGlyph.h" #include #include FTGlyph::FTGlyph() -: advance(0), - err(0) +: advance(0), + err(0) { //cout << "**** FTGlyph() size = "< +#include #include #include @@ -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 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/osgText/Makefile b/src/osgText/Makefile index b9537b55a..ef7758d33 100644 --- a/src/osgText/Makefile +++ b/src/osgText/Makefile @@ -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 diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 0c0ca4952..a27119b95 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -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"<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 ///////////////////////////////////////////////////////////////////////////////