From ce5388a8bc621581d0c5c9fb9f4f8d20424e8cfe Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 23 Dec 2007 18:15:54 +0000 Subject: [PATCH] Convert osgText and freetype plugin across to keeping the font size as state that is passed into the getGlyph and getKerning methods rather than a current state of the font itself. --- include/osgText/Font | 31 +++++++----------------- include/osgText/Font3D | 6 ----- include/osgText/KerningType | 2 +- include/osgText/TextBase | 2 +- src/osgPlugins/freetype/FreeTypeFont.cpp | 23 +++++++++++++----- src/osgPlugins/freetype/FreeTypeFont.h | 19 +++++++++------ src/osgPlugins/txf/TXFFont.cpp | 31 +++++++++--------------- src/osgPlugins/txf/TXFFont.h | 6 ++--- src/osgText/DefaultFont.cpp | 29 +++++++++++----------- src/osgText/DefaultFont.h | 4 +-- src/osgText/Font.cpp | 31 ++++++------------------ src/osgText/Text.cpp | 22 ++++++++--------- src/osgText/TextBase.cpp | 2 +- 13 files changed, 87 insertions(+), 121 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index c4388a2f9..9c5b31248 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -97,17 +97,12 @@ public: osg::StateSet* getStateSet() { return _stateset.get(); } const osg::StateSet* getStateSet() const { return _stateset.get(); } - /** Set the pixel width and height hint.*/ - virtual void setFontResolution(const FontSizePair& fontSize); - unsigned int getFontWidth() const; - unsigned int getFontHeight() const; - /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/ - virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType); + virtual osg::Vec2 getKerning(const FontResolution& fontSize, unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType); /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ - virtual Glyph* getGlyph(unsigned int charcode); + virtual Glyph* getGlyph(const FontResolution& fontSize, unsigned int charcode); /** Return true if this font provides vertical alignments and spacing or glyphs.*/ virtual bool hasVertical() const; @@ -170,13 +165,13 @@ protected: virtual ~Font(); - void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph); + void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph); typedef std::vector< osg::ref_ptr > GlyphTextureList; typedef std::vector< osg::ref_ptr > StateSetList; typedef std::map< unsigned int, osg::ref_ptr > GlyphMap; - typedef std::map< FontSizePair, GlyphMap > FontSizeGlyphMap; + typedef std::map< FontResolution, GlyphMap > FontSizeGlyphMap; osg::ref_ptr _texenv; osg::ref_ptr _stateset; @@ -184,8 +179,7 @@ protected: GlyphTextureList _glyphTextureList; // current active size of font - unsigned int _width; - unsigned int _height; + FontResolution _fontSize; unsigned int _margin; float _marginRatio; @@ -210,25 +204,18 @@ public: virtual std::string getFileName() const = 0; - /** Set the pixel width and height hint.*/ - virtual void setFontResolution(const FontSizePair& fontSize) = 0; - /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ - virtual Glyph* getGlyph(unsigned int charcode) = 0; + virtual Glyph* getGlyph(const FontResolution& fontRes, unsigned int charcode) = 0; /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes, w.r.t the current font size hint.*/ - virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) = 0; + virtual osg::Vec2 getKerning(const FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) = 0; /** Return true if this font provides vertical alignments and spacing or glyphs.*/ virtual bool hasVertical() const = 0; - void setFontWidth(unsigned int width) { _facade->_width = width; } - - void setFontHeight(unsigned int height) { _facade->_height = height; } - - void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph) + void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph) { - _facade->addGlyph(width, height, charcode, glyph); + _facade->addGlyph(fontRes, charcode, glyph); } Font* _facade; diff --git a/include/osgText/Font3D b/include/osgText/Font3D index f3886480c..a53afa66f 100644 --- a/include/osgText/Font3D +++ b/include/osgText/Font3D @@ -83,9 +83,6 @@ public: virtual std::string getFileName() const; - /** Set the pixel width and height hint.*/ -// virtual void setFontResolution(unsigned int width, unsigned int height, unsigned int depth); - unsigned int getFontWidth() const { return _width; } unsigned int getFontHeight() const { return _height; } unsigned int getFontDepth() const { return _depth; } @@ -151,9 +148,6 @@ public: virtual std::string getFileName() const = 0; - /** Set the pixel width and height hint.*/ -// virtual void setFontResolution(unsigned int width, unsigned int height, unsigned int depth) = 0; - /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/ virtual Glyph3D* getGlyph(unsigned int charcode) = 0; diff --git a/include/osgText/KerningType b/include/osgText/KerningType index 2377bdc32..110df4063 100644 --- a/include/osgText/KerningType +++ b/include/osgText/KerningType @@ -17,7 +17,7 @@ namespace osgText { -typedef std::pair< unsigned int, unsigned int > FontSizePair; +typedef std::pair< unsigned int, unsigned int > FontResolution; enum KerningType { diff --git a/include/osgText/TextBase b/include/osgText/TextBase index 836c7054e..f8e25cb12 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -239,7 +239,7 @@ protected: // members which have public access. - FontSizePair _fontSize; + FontResolution _fontSize; float _characterHeight; float _characterAspectRatio; CharacterSizeMode _characterSizeMode; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index d0b1f9222..a7662fcaa 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -18,6 +18,7 @@ #include FreeTypeFont::FreeTypeFont(const std::string& filename, FT_Face face, unsigned int flags): + _currentRes(osgText::FontResolution(0,0)), _filename(filename), _buffer(0), _face(face), @@ -26,6 +27,7 @@ FreeTypeFont::FreeTypeFont(const std::string& filename, FT_Face face, unsigned i } FreeTypeFont::FreeTypeFont(FT_Byte* buffer, FT_Face face, unsigned int flags): + _currentRes(osgText::FontResolution(0,0)), _filename(""), _buffer(buffer), _face(face), @@ -58,8 +60,10 @@ FreeTypeFont::~FreeTypeFont() } } -void FreeTypeFont::setFontResolution(const osgText::FontSizePair& fontSize) +void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize) { + if (fontSize==_currentRes) return; + int width = fontSize.first; int height = fontSize.second; int maxAxis = std::max(width, height); @@ -86,14 +90,17 @@ void FreeTypeFont::setFontResolution(const osgText::FontSizePair& fontSize) } else { - setFontWidth(width); - setFontHeight(height); + _currentRes = fontSize; } } -osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode) +osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode) { + OpenThreads::ScopedLock lock(_mutex); + + setFontResolution(fontRes); + // // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct @@ -184,7 +191,7 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode) glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX/64.0f,(float)(metrics->vertBearingY-metrics->height)/64.0f)); // top middle. glyph->setVerticalAdvance((float)metrics->vertAdvance/64.0f); - addGlyph(_facade->getFontWidth(),_facade->getFontHeight(),charcode,glyph.get()); + addGlyph(fontRes,charcode,glyph.get()); // cout << " in getGlyph() implementation="<second; - addGlyph(i->second->s(), i->second->t(), charcode, i->second.get()); + addGlyph(osgText::FontResolution(i->second->s(), i->second->t()), charcode, i->second.get()); return i->second.get(); } } @@ -112,7 +106,7 @@ TXFFont::getGlyph(unsigned int charcode) if (i != _chars.end()) { _chars[charcode] = i->second; - addGlyph(i->second->s(), i->second->t(), charcode, i->second.get()); + addGlyph(osgText::FontResolution(i->second->s(), i->second->t()), charcode, i->second.get()); return i->second.get(); } } @@ -127,7 +121,7 @@ TXFFont::hasVertical() const } osg::Vec2 -TXFFont::getKerning(unsigned int, unsigned int, osgText::KerningType) +TXFFont::getKerning(const osgText::FontResolution&, unsigned int, unsigned int, osgText::KerningType) { return osg::Vec2(0, 0); } @@ -159,6 +153,8 @@ TXFFont::loadFont(std::istream& stream) unsigned w = texwidth; unsigned h = texheight; + + osgText::FontResolution fontResolution(maxheight, maxheight); std::vector glyphs; for (unsigned i = 0; i < num_glyphs; ++i) @@ -179,9 +175,6 @@ TXFFont::loadFont(std::istream& stream) glyphs.push_back(glyphData); } - setFontWidth(maxwidth); - setFontHeight(maxheight); - unsigned ntexels = w * h; osg::ref_ptr image = new osg::Image; image->allocateImage(w, h, 1, GL_ALPHA, GL_UNSIGNED_BYTE); @@ -274,7 +267,7 @@ TXFFont::loadFont(std::istream& stream) - glyphs[i].height*texToVertY)); _chars[glyphs[i].ch] = glyph; - addGlyph(width, height, glyphs[i].ch, glyph); + addGlyph(fontResolution, glyphs[i].ch, glyph); } // insert a trivial blank character @@ -294,12 +287,12 @@ TXFFont::loadFont(std::istream& stream) } } - glyph->setHorizontalAdvance(0.5f*_facade->getFontHeight()); - glyph->setHorizontalBearing(osg::Vec2(0, 0)); - glyph->setVerticalAdvance(_facade->getFontHeight()); - glyph->setVerticalBearing(osg::Vec2(0, 0)); + glyph->setHorizontalAdvance(0.5f*float(fontResolution.second)); + glyph->setHorizontalBearing(osg::Vec2(0.0f, 0.0f)); + glyph->setVerticalAdvance(float(fontResolution.second)); + glyph->setVerticalBearing(osg::Vec2(0.0f, 0.0f)); _chars[' '] = glyph; - addGlyph(width, height, ' ', glyph); + addGlyph(fontResolution, ' ', glyph); return true; } diff --git a/src/osgPlugins/txf/TXFFont.h b/src/osgPlugins/txf/TXFFont.h index 73384d5f8..d15593cca 100644 --- a/src/osgPlugins/txf/TXFFont.h +++ b/src/osgPlugins/txf/TXFFont.h @@ -28,13 +28,11 @@ public: virtual std::string getFileName() const; - virtual void setFontResolution(const osgText::FontSizePair&); - - virtual osgText::Font::Glyph* getGlyph(unsigned int charcode); + virtual osgText::Font::Glyph* getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode); virtual bool hasVertical() const; - virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType); + virtual osg::Vec2 getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType); bool loadFont(std::istream& stream); diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index ac1645beb..693ea3521 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -48,25 +48,25 @@ void DefaultFont::setSize(unsigned int, unsigned int) -Font::Glyph* DefaultFont::getGlyph(unsigned int charcode) +Font::Glyph* DefaultFont::getGlyph(const FontResolution& fontRes, unsigned int charcode) { if (_sizeGlyphMap.empty()) return 0; - FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(FontSizePair(_width,_height)); + FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes); if (itr==_sizeGlyphMap.end()) { // no font found of correct size, will need to find the nearest. itr = _sizeGlyphMap.begin(); - int mindeviation = abs((int)_width-(int)itr->first.first)+ - abs((int)_height-(int)itr->first.second); + int mindeviation = abs((int)fontRes.first-(int)itr->first.first)+ + abs((int)fontRes.second-(int)itr->first.second); FontSizeGlyphMap::iterator sitr=itr; ++sitr; for(; sitr!=_sizeGlyphMap.end(); ++sitr) { - int deviation = abs((int)_width-(int)sitr->first.first)+ - abs((int)_height-(int)sitr->first.second); + int deviation = abs((int)fontRes.first-(int)sitr->first.first)+ + abs((int)fontRes.second-(int)sitr->first.second); if (deviation glyph = new Glyph; - unsigned int dataSize = _width*_height; + unsigned int dataSize = sourceWidth*sourceHeight; unsigned char* data = new unsigned char[dataSize]; // clear the image to zeros. for(unsigned char* p=data;psetImage(_width,_height,1, + glyph->setImage(sourceWidth,sourceHeight,1, GL_ALPHA, GL_ALPHA,GL_UNSIGNED_BYTE, data, @@ -240,11 +239,11 @@ void DefaultFont::constructGlyphs() } glyph->setHorizontalBearing(osg::Vec2(0.0f,0.0f)); // bottom left. - glyph->setHorizontalAdvance((float)_width); - glyph->setVerticalBearing(osg::Vec2((float)_width*0.5f,(float)_height)); // top middle. - glyph->setVerticalAdvance((float)_height); + glyph->setHorizontalAdvance((float)sourceWidth); + glyph->setVerticalBearing(osg::Vec2((float)sourceWidth*0.5f,(float)sourceHeight)); // top middle. + glyph->setVerticalAdvance((float)sourceHeight); - addGlyph(_width,_height,i,glyph.get()); + addGlyph(fontRes,i,glyph.get()); } } diff --git a/src/osgText/DefaultFont.h b/src/osgText/DefaultFont.h index c89a3c438..d6069afe7 100644 --- a/src/osgText/DefaultFont.h +++ b/src/osgText/DefaultFont.h @@ -33,9 +33,9 @@ public: /** NOP with DefaultFont since it only supports a single fixed sized font. */ virtual void setSize(unsigned int width, unsigned int height); - virtual Font::Glyph* getGlyph(unsigned int charcode); + virtual Font::Glyph* getGlyph(const FontResolution& fontRes, unsigned int charcode); - virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType); + virtual osg::Vec2 getKerning(const FontResolution&, unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType); virtual bool hasVertical() const; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 751a30203..9ec7e7f8c 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -207,8 +207,6 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), - _width(16), - _height(16), _margin(1), _marginRatio(0.02), _textureWidthHint(1024), @@ -261,21 +259,6 @@ std::string Font::getFileName() const return ""; } -void Font::setFontResolution(const FontSizePair& fontSize) -{ - if (_implementation.valid()) _implementation->setFontResolution(fontSize); -} - -unsigned int Font::getFontWidth() const -{ - return _width; -} - -unsigned int Font::getFontHeight() const -{ - return _height; -} - void Font::setGlyphImageMargin(unsigned int margin) { _margin = margin; @@ -345,9 +328,9 @@ osg::Texture::FilterMode Font::getMagFilterHint() const } -Font::Glyph* Font::getGlyph(unsigned int charcode) +Font::Glyph* Font::getGlyph(const FontResolution& fontRes, unsigned int charcode) { - FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(FontSizePair(_width,_height)); + FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes); if (itr!=_sizeGlyphMap.end()) { GlyphMap& glyphmap = itr->second; @@ -355,7 +338,7 @@ Font::Glyph* Font::getGlyph(unsigned int charcode) if (gitr!=glyphmap.end()) return gitr->second.get(); } - if (_implementation.valid()) return _implementation->getGlyph(charcode); + if (_implementation.valid()) return _implementation->getGlyph(fontRes, charcode); else return 0; } @@ -401,9 +384,9 @@ void Font::releaseGLObjects(osg::State* state) const // const_cast(this)->_sizeGlyphMap.clear(); } -osg::Vec2 Font::getKerning(unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) +osg::Vec2 Font::getKerning(const FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType) { - if (_implementation.valid()) return _implementation->getKerning(leftcharcode,rightcharcode,kerningType); + if (_implementation.valid()) return _implementation->getKerning(fontRes, leftcharcode,rightcharcode,kerningType); else return osg::Vec2(0.0f,0.0f); } @@ -415,9 +398,9 @@ bool Font::hasVertical() const -void Font::addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph) +void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph) { - _sizeGlyphMap[FontSizePair(width,height)][charcode]=glyph; + _sizeGlyphMap[fontRes][charcode]=glyph; int posX=0,posY=0; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 6d944fcf5..e1bee2915 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -111,7 +111,7 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite Font* activefont = getActiveFont(); if (!activefont) return last; - float hr = _characterHeight/(float)activefont->getFontHeight(); + float hr = _characterHeight/getFontHeight(); float wr = hr/_characterAspectRatio; bool kerning = true; @@ -138,7 +138,7 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite return lastChar; } - Font::Glyph* glyph = activefont->getGlyph(charcode); + Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode); if (glyph) { @@ -161,14 +161,14 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite { case LEFT_TO_RIGHT: { - osg::Vec2 delta(activefont->getKerning(previous_charcode,charcode,_kerningType)); + osg::Vec2 delta(activefont->getKerning(_fontSize, previous_charcode,charcode,_kerningType)); cursor.x() += delta.x() * wr; cursor.y() += delta.y() * hr; break; } case RIGHT_TO_LEFT: { - osg::Vec2 delta(activefont->getKerning(charcode,previous_charcode,_kerningType)); + osg::Vec2 delta(activefont->getKerning(_fontSize, charcode,previous_charcode,_kerningType)); cursor.x() -= delta.x() * wr; cursor.y() -= delta.y() * hr; break; @@ -225,7 +225,7 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite --lastValidChar; // Subtract off glyphs from the cursor position (to correctly center text) - Font::Glyph* glyph = activefont->getGlyph(*lastValidChar); + Font::Glyph* glyph = activefont->getGlyph(_fontSize, *lastValidChar); if (glyph) { switch(_layout) @@ -263,7 +263,7 @@ void Text::computeGlyphRepresentation() return; } - OpenThreads::ScopedLock lock(*(activefont->getSerializeFontCallsMutex())); + //OpenThreads::ScopedLock lock(*(activefont->getSerializeFontCallsMutex())); // initialize bounding box, it will be expanded during glyph position calculation _textBB.init(); @@ -279,9 +279,7 @@ void Text::computeGlyphRepresentation() unsigned int lineNumber = 0; - activefont->setFontResolution(_fontSize); - - float hr = _characterHeight/(float)activefont->getFontHeight(); + float hr = _characterHeight/getFontHeight(); float wr = hr/_characterAspectRatio; for(String::iterator itr=_text.begin(); @@ -404,7 +402,7 @@ void Text::computeGlyphRepresentation() { unsigned int charcode = *itr; - Font::Glyph* glyph = activefont->getGlyph(charcode); + Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode); if (glyph) { float width = (float)(glyph->s()) * wr; @@ -427,14 +425,14 @@ void Text::computeGlyphRepresentation() { case LEFT_TO_RIGHT: { - osg::Vec2 delta(activefont->getKerning(previous_charcode,charcode,_kerningType)); + osg::Vec2 delta(activefont->getKerning(_fontSize, previous_charcode,charcode,_kerningType)); cursor.x() += delta.x() * wr; cursor.y() += delta.y() * hr; break; } case RIGHT_TO_LEFT: { - osg::Vec2 delta(activefont->getKerning(charcode,previous_charcode,_kerningType)); + osg::Vec2 delta(activefont->getKerning(_fontSize, charcode,previous_charcode,_kerningType)); cursor.x() -= delta.x() * wr; cursor.y() -= delta.y() * hr; break; diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index c9d00ea0e..4ded467ce 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -80,7 +80,7 @@ TextBase::~TextBase() void TextBase::setFontResolution(unsigned int width, unsigned int height) { - _fontSize = FontSizePair(width,height); + _fontSize = FontResolution(width,height); computeGlyphRepresentation(); }