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.
This commit is contained in:
Robert Osfield 2007-12-23 18:15:54 +00:00
parent f290b75bc9
commit ce5388a8bc
13 changed files with 87 additions and 121 deletions

View File

@ -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<GlyphTexture> > GlyphTextureList;
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap;
typedef std::map< FontSizePair, GlyphMap > FontSizeGlyphMap;
typedef std::map< FontResolution, GlyphMap > FontSizeGlyphMap;
osg::ref_ptr<osg::TexEnv> _texenv;
osg::ref_ptr<osg::StateSet> _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;

View File

@ -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;

View File

@ -17,7 +17,7 @@
namespace osgText
{
typedef std::pair< unsigned int, unsigned int > FontSizePair;
typedef std::pair< unsigned int, unsigned int > FontResolution;
enum KerningType
{

View File

@ -239,7 +239,7 @@ protected:
// members which have public access.
FontSizePair _fontSize;
FontResolution _fontSize;
float _characterHeight;
float _characterAspectRatio;
CharacterSizeMode _characterSizeMode;

View File

@ -18,6 +18,7 @@
#include <osgDB/WriteFile>
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<OpenThreads::Mutex> 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="<<this<<" "<<_filename<<" facade="<<_facade<<endl;
@ -192,10 +199,14 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode)
}
osg::Vec2 FreeTypeFont::getKerning(unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType)
osg::Vec2 FreeTypeFont::getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!FT_HAS_KERNING(_face) || (kerningType == osgText::KERNING_NONE)) return osg::Vec2(0.0f,0.0f);
setFontResolution(fontRes);
FT_Kerning_Mode mode = (kerningType==osgText::KERNING_DEFAULT) ? ft_kerning_default : ft_kerning_unfitted;
// convert character code to glyph index

View File

@ -31,16 +31,19 @@ public:
virtual std::string getFileName() const { return _filename; }
virtual void setFontResolution(const osgText::FontSizePair& fontSize);
virtual osgText::Font::Glyph* getGlyph(const osgText::FontResolution& fontRes,unsigned int charcode);
virtual osgText::Font::Glyph* getGlyph(unsigned int charcode);
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);
virtual bool hasVertical() const;
protected:
void setFontResolution(const osgText::FontResolution& fontSize);
OpenThreads::Mutex _mutex;
osgText::FontResolution _currentRes;
std::string _filename;
FT_Byte* _buffer;
FT_Face _face;

View File

@ -81,14 +81,8 @@ TXFFont::getFileName() const
return _filename;
}
void
TXFFont::setFontResolution(const osgText::FontSizePair&)
{
osg::notify(osg::INFO) << "TXFFont::setFontResolution(,) call is ignored." << std::endl;
}
osgText::Font::Glyph*
TXFFont::getGlyph(unsigned int charcode)
TXFFont::getGlyph(const osgText::FontResolution&, unsigned int charcode)
{
GlyphMap::iterator i = _chars.find(charcode);
if (i != _chars.end())
@ -102,7 +96,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();
}
}
@ -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);
}
@ -160,6 +154,8 @@ TXFFont::loadFont(std::istream& stream)
unsigned w = texwidth;
unsigned h = texheight;
osgText::FontResolution fontResolution(maxheight, maxheight);
std::vector<GlyphData> 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<osg::Image> 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;
}

View File

@ -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);

View File

@ -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<mindeviation)
{
mindeviation = deviation;
@ -84,7 +84,7 @@ Font::Glyph* DefaultFont::getGlyph(unsigned int charcode)
}
osg::Vec2 DefaultFont::getKerning(unsigned int,unsigned int, KerningType)
osg::Vec2 DefaultFont::getKerning(const FontResolution&, unsigned int,unsigned int, KerningType)
{
// no kerning on default font.
return osg::Vec2(0.0f,0.0f);
@ -199,21 +199,20 @@ void DefaultFont::constructGlyphs()
unsigned int sourceWidth = 8;
unsigned int sourceHeight = 12;
_width = sourceWidth;
_height = sourceHeight;
FontResolution fontRes(sourceWidth,sourceHeight);
// populate the glyph mp
for(unsigned int i=32;i<127;i++)
{
osg::ref_ptr<Glyph> 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;p<data+dataSize;) { *p++ = 0; }
glyph->setImage(_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());
}
}

View File

@ -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;

View File

@ -207,8 +207,6 @@ osg::ref_ptr<Font> 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<Font*>(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;

View File

@ -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<Font::FontMutex> lock(*(activefont->getSerializeFontCallsMutex()));
//OpenThreads::ScopedLock<Font::FontMutex> 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;

View File

@ -80,7 +80,7 @@ TextBase::~TextBase()
void TextBase::setFontResolution(unsigned int width, unsigned int height)
{
_fontSize = FontSizePair(width,height);
_fontSize = FontResolution(width,height);
computeGlyphRepresentation();
}