Files
OpenSceneGraph/include/osgText/Font
Robert Osfield fab6f24f4e Changed the osgText::Font implementation so it used a facade us abstract away
the actual implemention. This has been done so that when a freetype font is
created the implementation can unloaded when the freetype plugin is unloaded
without breaking the main font.

Also add image margin around founds to prevent any image boundaries appearing.
2003-03-06 17:11:24 +00:00

282 lines
9.8 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGTEXT_FONT
#define OSGTEXT_FONT 1
#include <osg/Vec2>
#include <osg/Image>
#include <osg/Texture2D>
#include <osg/StateSet>
#include <osg/buffered_value>
#include <osgText/Export>
#include <string>
#include <set>
namespace osgText {
class Font;
class Text;
/** read a font from specified file.*/
extern OSGTEXT_EXPORT Font* readFontFile(const std::string& filename);
/** Pure virtual base class for fonts.
* Concrete implementation are the DefaultFont found in src/osgText/DefaultFont.cpp
* and FreeTypeFont found in src/osgPlugins/freetype/FreeTypeFont.cpp*/
class OSGTEXT_EXPORT Font : public osg::Object
{
// declare the interface to a font.
public:
// forward declare nested classes.
class Glyph;
class GlyphTexture;
class FontImplementation;
Font(FontImplementation* implementation=0);
virtual osg::Object* cloneType() const { return 0; } // cloneType() not appropriate
virtual osg::Object* clone(const osg::CopyOp&) const { return 0; } // clone() not appropriate
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Font*>(obj)!=NULL; }
virtual const char* className() const { return "Font"; }
virtual const char* libraryName() const { return "osgText"; }
virtual std::string getFileName() const;
/** Set the pixel width and height hint.*/
virtual void setSize(unsigned int width, unsigned int height);
unsigned int getWidth() { return _width; }
unsigned int getHeight() { return _height; }
/** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
virtual Glyph* getGlyph(unsigned int charcode);
/** 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);
/** Return true if this font provides vertical alignments and spacing or glyphs.*/
virtual bool hasVertical() const;
/** Set the margin around each glyph,
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
* Default margin is 2 texels.*/
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
unsigned int getGlyphImageMargin() const { return _margin; }
/** Set the size of texture to create to store the glyph images when rendering.
* Note, this doesn't affect already created Texture Glhph's.*/
void setTextureSizeHint(unsigned int width,unsigned int height);
unsigned int getTextureWidthHint() const { return _textureWidthHint; }
unsigned int getTextureHeightHint() const { return _textureWidthHint; }
/** Set the minification texture filter to use when creating the texture to store the glyph images when rendering.
* Note, this doesn't affect already created Texture Glhph's.*/
void setMinFilterHint(osg::Texture::FilterMode mode);
osg::Texture::FilterMode getMinFilterHint() const { return _minFilterHint; }
/** Set the magnification texture filter to use when creating the texture to store the glyph images when rendering.
* Note, this doesn't affect already created Texture Glhph's.*/
void setMagFilterHint(osg::Texture::FilterMode mode);
osg::Texture::FilterMode getMagFilterHint() const { return _magFilterHint; }
// make Text a friend to allow it add and remove its entry in the Font's _textList.
friend class FontImplementation;
void setImplementation(FontImplementation* implementation);
FontImplementation* getImplementation() { return _implementation.get(); }
const FontImplementation* getImplementation() const { return _implementation.get(); }
protected:
virtual ~Font();
void addGlyph(unsigned int width, unsigned int height, 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::pair< unsigned int, unsigned int > SizePair;
typedef std::map< SizePair, GlyphMap > SizeGlyphMap;
typedef std::set< Text* > TextList;
SizeGlyphMap _sizeGlyphMap;
GlyphTextureList _glyphTextureList;
StateSetList _stateSetList;
// current active size of font
unsigned int _width;
unsigned int _height;
unsigned int _margin;
unsigned int _textureWidthHint;
unsigned int _textureHeightHint;
osg::Texture::FilterMode _minFilterHint;
osg::Texture::FilterMode _magFilterHint;
osg::ref_ptr<FontImplementation> _implementation;
// declare the nested classes.
public:
class OSGTEXT_EXPORT FontImplementation : public osg::Referenced
{
public:
virtual std::string getFileName() const = 0;
/** Set the pixel width and height hint.*/
virtual void setSize(unsigned int width, unsigned int height) = 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;
/** 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) = 0;
/** Return true if this font provides vertical alignments and spacing or glyphs.*/
virtual bool hasVertical() const = 0;
void setWidth(unsigned int width) { _facade->_width = width; }
void setHeight(unsigned int height) { _facade->_height = height; }
void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph)
{
_facade->addGlyph(width, height, charcode, glyph);
}
Font* _facade;
};
class OSGTEXT_EXPORT GlyphTexture : public osg::Texture2D
{
public:
GlyphTexture();
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset; }
const osg::StateSet* getStateSet() const { return _stateset; }
/** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
unsigned int getGlyphImageMargin() const { return _margin; }
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
void addGlyph(Glyph* glyph,int posX, int posY);
virtual void apply(osg::State& state) const;
protected:
virtual ~GlyphTexture();
osg::StateSet* _stateset;
// parameter used to compute the size and position of empty space
// in the texture which could accomodate new glyphs.
int _margin;
int _usedY;
int _partUsedX;
int _partUsedY;
typedef std::vector< osg::ref_ptr<Glyph> > GlyphRefList;
typedef std::vector< const Glyph* > GlyphPtrList;
typedef osg::buffered_object< GlyphPtrList > GlyphBuffer;
GlyphRefList _glyphs;
mutable GlyphBuffer _glyphsToSubload;
};
class OSGTEXT_EXPORT Glyph : public osg::Image
{
public:
Glyph();
virtual ~Glyph();
unsigned int getGlyphCode() const;
void setHorizontalBearing(const osg::Vec2& bearing);
const osg::Vec2& getHorizontalBearing() const;
void setHorizontalAdvance(float advance);
float getHorizontalAdvance() const;
void setVerticalBearing(const osg::Vec2& bearing);
const osg::Vec2& getVerticalBearing() const;
void setVerticalAdvance(float advance);
float getVerticalAdvance() const;
void setTexture(GlyphTexture* texture);
GlyphTexture* getTexture();
const GlyphTexture* getTexture() const;
osg::StateSet* getStateSet();
const osg::StateSet* getStateSet() const;
void setTexturePosition(int posX,int posY);
int getTexturePositionX() const;
int getTexturePositionY() const;
void setMinTexCoord(const osg::Vec2& coord);
const osg::Vec2& getMinTexCoord() const;
void setMaxTexCoord(const osg::Vec2& coord);
const osg::Vec2& getMaxTexCoord() const;
void subload() const;
protected:
Font* _font;
unsigned int _glyphCode;
osg::Vec2 _horizontalBearing;
float _horizontalAdvance;
osg::Vec2 _verticalBearing;
float _verticalAdvance;
GlyphTexture* _texture;
int _texturePosX;
int _texturePosY;
osg::Vec2 _minTexCoord;
osg::Vec2 _maxTexCoord;
};
};
}
#endif