Reorganised the managment of margins around glyphs so that is done entirely

with src/osgText/Font.cpp rather than the font plugins or Text.cpp
This commit is contained in:
Robert Osfield 2007-05-04 12:05:29 +00:00
parent 0ad6aae023
commit dadb92ea64
7 changed files with 176 additions and 45 deletions

View File

@ -113,10 +113,17 @@ public:
/** 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.*/
* Default margin is 1 texels.*/
void setGlyphImageMargin(unsigned int margin);
unsigned int getGlyphImageMargin() const;
/** Set the margin ratio around each glyph, relative to the glyph's size.
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
* Default margin is 0.05.*/
void setGlyphImageMarginRatio(float margin);
float getGlyphImageMarginRatio() const;
/** 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);
@ -176,6 +183,7 @@ protected:
unsigned int _width;
unsigned int _height;
unsigned int _margin;
float _marginRatio;
unsigned int _textureWidthHint;
unsigned int _textureHeightHint;
@ -233,6 +241,9 @@ public:
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
unsigned int getGlyphImageMargin() const { return _margin; }
void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; }
float getGlyphImageMarginRatio() const { return _marginRatio; }
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
void addGlyph(Glyph* glyph,int posX, int posY);
@ -252,6 +263,7 @@ public:
// parameter used to compute the size and position of empty space
// in the texture which could accomodate new glyphs.
int _margin;
float _marginRatio;
int _usedY;
int _partUsedX;
int _partUsedY;

View File

@ -58,13 +58,16 @@ FreeTypeFont::~FreeTypeFont()
void FreeTypeFont::setFontResolution(unsigned int width, unsigned int height)
{
if (width+2*_facade->getGlyphImageMargin()>_facade->getTextureWidthHint() ||
height+2*_facade->getGlyphImageMargin()>_facade->getTextureHeightHint())
int maxAxis = std::max(width, height);
int margin = _facade->getGlyphImageMargin() + (int)((float)maxAxis * _facade->getGlyphImageMarginRatio());
if (width+2*margin>_facade->getTextureWidthHint() ||
width+2*margin>_facade->getTextureHeightHint())
{
osg::notify(osg::WARN)<<"Warning: FreeTypeFont::setSize("<<width<<","<<height<<") sizes too large,"<<std::endl;
width = _facade->getTextureWidthHint()-2*_facade->getGlyphImageMargin();
height = _facade->getTextureHeightHint()-2*_facade->getGlyphImageMargin();
width = _facade->getTextureWidthHint()-2*margin;
height = _facade->getTextureHeightHint()-2*margin;
osg::notify(osg::WARN)<<" sizes capped ("<<width<<","<<height<<") to fit int current glyph texture size."<<std::endl;
}
@ -118,9 +121,8 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode)
unsigned int sourceWidth = glyphslot->bitmap.width;;
unsigned int sourceHeight = glyphslot->bitmap.rows;
unsigned int margin = _facade->getGlyphImageMargin();
unsigned int width = sourceWidth+2*margin;
unsigned int height = sourceHeight+2*margin;
unsigned int width = sourceWidth;
unsigned int height = sourceHeight;
osg::ref_ptr<osgText::Font::Glyph> glyph = new osgText::Font::Glyph;
@ -140,20 +142,14 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(unsigned int charcode)
glyph->setInternalTextureFormat(GL_ALPHA);
// skip the top margin
data += (margin*width);
// copy image across to osgText::Glyph image.
for(int r=sourceHeight-1;r>=0;--r)
{
data+=margin; // skip the left margin
unsigned char* ptr = buffer+r*pitch;
for(unsigned int c=0;c<sourceWidth;++c,++ptr)
{
(*data++)=*ptr;
}
data+=margin; // skip the right margin.
}

View File

@ -242,9 +242,8 @@ TXFFont::loadFont(std::istream& stream)
unsigned sourceWidth = glyphs[i].width;
unsigned sourceHeight = glyphs[i].height;
unsigned margin = _facade->getGlyphImageMargin();
unsigned width = sourceWidth + 2*margin;
unsigned height = sourceHeight + 2*margin;
unsigned width = sourceWidth;
unsigned height = sourceHeight;
glyph->allocateImage(width, height, 1, GL_ALPHA, GL_UNSIGNED_BYTE);
glyph->setInternalTextureFormat(GL_ALPHA);
@ -261,7 +260,7 @@ TXFFont::loadFont(std::istream& stream)
{
for (unsigned l = 0; l < glyphs[i].height; ++l)
{
*glyph->data(margin + k, margin + l) = *image->data(glyphs[i].x + k, glyphs[i].y + l);
*glyph->data(k, l) = *image->data(glyphs[i].x + k, glyphs[i].y + l);
}
}
@ -281,9 +280,8 @@ TXFFont::loadFont(std::istream& stream)
// insert a trivial blank character
osgText::Font::Glyph* glyph = new osgText::Font::Glyph;
unsigned margin = _facade->getGlyphImageMargin();
unsigned width = 1 + 2*margin;
unsigned height = 1 + 2*margin;
unsigned width = 1;
unsigned height = 1;
glyph->allocateImage(width, height, 1, GL_ALPHA, GL_UNSIGNED_BYTE);
glyph->setInternalTextureFormat(GL_ALPHA);

View File

@ -133,9 +133,10 @@ osgText::Font* osgText::readFontStream(std::istream& stream)
Font::Font(FontImplementation* implementation):
_width(16),
_height(16),
_margin(2),
_textureWidthHint(512),
_textureHeightHint(512),
_margin(1),
_marginRatio(0.05),
_textureWidthHint(1024),
_textureHeightHint(1024),
_minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR),
_magFilterHint(osg::Texture::LINEAR)
{
@ -199,6 +200,16 @@ unsigned int Font::getGlyphImageMargin() const
return _margin;
}
void Font::setGlyphImageMarginRatio(float ratio)
{
_marginRatio = ratio;
}
float Font::getGlyphImageMarginRatio() const
{
return _marginRatio;
}
void Font::setTextureSizeHint(unsigned int width,unsigned int height)
{
_textureWidthHint = width;
@ -340,6 +351,7 @@ void Font::addGlyph(unsigned int width, unsigned int height, unsigned int charco
// reserve enough space for the glyphs.
glyphTexture->setGlyphImageMargin(_margin);
glyphTexture->setGlyphImageMarginRatio(_marginRatio);
glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint);
glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint);
glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint);
@ -362,7 +374,8 @@ void Font::addGlyph(unsigned int width, unsigned int height, unsigned int charco
Font::GlyphTexture::GlyphTexture():
_margin(2),
_margin(1),
_marginRatio(0.05f),
_usedY(0),
_partUsedX(0),
_partUsedY(0)
@ -384,9 +397,11 @@ int Font::GlyphTexture::compare(const osg::StateAttribute& rhs) const
bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
{
int width = glyph->s()+2*_margin;
int height = glyph->t()+2*_margin;
int maxAxis = std::max(glyph->s(), glyph->t());
int margin = _margin + (int)((float)maxAxis * _marginRatio);
int width = glyph->s()+2*margin;
int height = glyph->t()+2*margin;
// first check box (_partUsedX,_usedY) to (width,height)
if (width <= (getTextureWidth()-_partUsedX) &&
@ -395,8 +410,8 @@ bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
// can fit in existing row.
// record the position in which the texture will be stored.
posX = _partUsedX+_margin;
posY = _usedY+_margin;
posX = _partUsedX+margin;
posY = _usedY+margin;
// move used markers on.
_partUsedX += width;
@ -413,8 +428,8 @@ bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
_partUsedX = 0;
_usedY = _partUsedY;
posX = _partUsedX+_margin;
posY = _usedY+_margin;
posX = _partUsedX+margin;
posY = _usedY+margin;
// move used markers on.
_partUsedX += width;
@ -439,9 +454,9 @@ void Font::GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
// set up the details of where to place glyph's image in the texture.
glyph->setTexture(this);
glyph->setTexturePosition(posX,posY);
unsigned int sizeAdjustment = 0; // was 1.
glyph->setMinTexCoord(osg::Vec2((float)(posX+_margin)/(float)(getTextureWidth()-sizeAdjustment),(float)(posY+_margin)/(float)(getTextureHeight()-sizeAdjustment)));
glyph->setMaxTexCoord(osg::Vec2((float)(posX+glyph->s()-_margin)/(float)(getTextureWidth()-sizeAdjustment),(float)(posY+glyph->t()-_margin)/(float)(getTextureHeight()-sizeAdjustment)));
unsigned int sizeAdjustment = 1;
glyph->setMinTexCoord(osg::Vec2((float)(posX)/(float)(getTextureWidth()-sizeAdjustment),(float)(posY)/(float)(getTextureHeight()-sizeAdjustment)));
glyph->setMaxTexCoord(osg::Vec2((float)(posX+glyph->s())/(float)(getTextureWidth()-sizeAdjustment),(float)(posY+glyph->t())/(float)(getTextureHeight()-sizeAdjustment)));
}
void Font::GlyphTexture::apply(osg::State& state) const

View File

@ -338,8 +338,8 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite
if (glyph)
{
float width = (float)(glyph->s()-2*activefont->getGlyphImageMargin()) * wr;
//float height = (float)(glyph->t()-2*activefont->getGlyphImageMargin()) * hr;
float width = (float)(glyph->s()) * wr;
//float height = (float)(glyph->t()) * hr;
#ifdef TREES_CODE_FOR_MAKING_SPACES_EDITABLE
if (width == 0.0f) width = glyph->getHorizontalAdvance() * wr;
//if (height == 0.0f) height = glyph->getVerticalAdvance() * hr;
@ -598,9 +598,9 @@ void Text::computeGlyphRepresentation()
Font::Glyph* glyph = activefont->getGlyph(charcode);
if (glyph)
{
float width = (float)(glyph->s()) * wr;
float height = (float)(glyph->t()) * hr;
float width = (float)(glyph->s()-2*activefont->getGlyphImageMargin()) * wr;
float height = (float)(glyph->t()-2*activefont->getGlyphImageMargin()) * hr;
#ifdef TREES_CODE_FOR_MAKING_SPACES_EDITABLE
if (width == 0.0f) width = glyph->getHorizontalAdvance() * wr;
if (height == 0.0f) height = glyph->getVerticalAdvance() * hr;
@ -1465,7 +1465,11 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie
unsigned int contextID = state.getContextID();
state.applyMode(GL_BLEND,true);
#if 1
state.applyTextureMode(0,GL_TEXTURE_2D,true);
#else
state.applyTextureMode(0,GL_TEXTURE_2D,false);
#endif
state.applyTextureAttribute(0,getActiveFont()->getTexEnv());
if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)

View File

@ -24,15 +24,95 @@
#undef OUT
#endif
BEGIN_OBJECT_REFLECTOR(osgTerrain::EllipsoidLocator)
BEGIN_OBJECT_REFLECTOR(osgTerrain::CartizianLocator)
I_BaseType(osgTerrain::Locator);
I_ConstructorWithDefaults5(IN, double, longitude, , IN, double, latitude, , IN, double, deltaLongitude, , IN, double, deltaLatitude, , IN, double, height, 0.0,
____EllipsoidLocator__double__double__double__double__double,
I_ConstructorWithDefaults6(IN, double, originX, , IN, double, originY, , IN, double, lengthX, , IN, double, lengthY, , IN, double, height, 0.0f, IN, double, heightScale, 1.0f,
____CartizianLocator__double__double__double__double__double__double,
"",
"");
I_MethodWithDefaults5(void, setExtents, IN, double, longitude, , IN, double, latitude, , IN, double, deltaLongitude, , IN, double, deltaLatitude, , IN, double, height, 0.0,
I_MethodWithDefaults6(void, setExtents, IN, double, originX, , IN, double, originY, , IN, double, lengthX, , IN, double, lengthY, , IN, double, height, 0.0f, IN, double, heightScale, 1.0f,
Properties::NON_VIRTUAL,
__void__setExtents__double__double__double__double__double,
__void__setExtents__double__double__double__double__double__double,
"",
"");
I_Method1(void, setOriginX, IN, double, x,
Properties::NON_VIRTUAL,
__void__setOriginX__double,
"",
"");
I_Method0(double, getOriginX,
Properties::NON_VIRTUAL,
__double__getOriginX,
"",
"");
I_Method1(void, setOriginY, IN, double, y,
Properties::NON_VIRTUAL,
__void__setOriginY__double,
"",
"");
I_Method0(double, getOriginY,
Properties::NON_VIRTUAL,
__double__getOriginY,
"",
"");
I_Method1(void, setLengthX, IN, double, x,
Properties::NON_VIRTUAL,
__void__setLengthX__double,
"",
"");
I_Method0(double, getLengthX,
Properties::NON_VIRTUAL,
__double__getLengthX,
"",
"");
I_Method1(void, setLengthY, IN, double, y,
Properties::NON_VIRTUAL,
__void__setLengthY__double,
"",
"");
I_Method0(double, getLengthY,
Properties::NON_VIRTUAL,
__double__getLengthY,
"",
"");
I_Method0(bool, orientationOpenGL,
Properties::VIRTUAL,
__bool__orientationOpenGL,
"",
"");
I_Method2(bool, convertLocalToModel, IN, const osg::Vec3d &, local, IN, osg::Vec3d &, world,
Properties::VIRTUAL,
__bool__convertLocalToModel__C5_osg_Vec3d_R1__osg_Vec3d_R1,
"",
"");
I_Method2(bool, convertModelToLocal, IN, const osg::Vec3d &, world, IN, osg::Vec3d &, local,
Properties::VIRTUAL,
__bool__convertModelToLocal__C5_osg_Vec3d_R1__osg_Vec3d_R1,
"",
"");
I_SimpleProperty(double, LengthX,
__double__getLengthX,
__void__setLengthX__double);
I_SimpleProperty(double, LengthY,
__double__getLengthY,
__void__setLengthY__double);
I_SimpleProperty(double, OriginX,
__double__getOriginX,
__void__setOriginX__double);
I_SimpleProperty(double, OriginY,
__double__getOriginY,
__void__setOriginY__double);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::EllipsoidLocator)
I_BaseType(osgTerrain::Locator);
I_ConstructorWithDefaults6(IN, double, longitude, , IN, double, latitude, , IN, double, deltaLongitude, , IN, double, deltaLatitude, , IN, double, height, 0.0, IN, double, heightScale, 1.0f,
____EllipsoidLocator__double__double__double__double__double__double,
"",
"");
I_MethodWithDefaults6(void, setExtents, IN, double, longitude, , IN, double, latitude, , IN, double, deltaLongitude, , IN, double, deltaLatitude, , IN, double, height, 0.0, IN, double, heightScale, 1.0f,
Properties::NON_VIRTUAL,
__void__setExtents__double__double__double__double__double__double,
"",
"");
I_Method0(double, getLongitude,

View File

@ -129,12 +129,22 @@ BEGIN_OBJECT_REFLECTOR(osgText::Font)
Properties::NON_VIRTUAL,
__void__setGlyphImageMargin__unsigned_int,
"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. ");
"Default margin is 1 texels. ");
I_Method0(unsigned int, getGlyphImageMargin,
Properties::NON_VIRTUAL,
__unsigned_int__getGlyphImageMargin,
"",
"");
I_Method1(void, setGlyphImageMarginRatio, IN, float, margin,
Properties::NON_VIRTUAL,
__void__setGlyphImageMarginRatio__float,
"Set the margin ratio around each glyph, relative to the glyph's size. ",
"to ensure that texture filtering doesn't bleed adjacent glyph's into each other. Default margin is 0.05. ");
I_Method0(float, getGlyphImageMarginRatio,
Properties::NON_VIRTUAL,
__float__getGlyphImageMarginRatio,
"",
"");
I_Method2(void, setTextureSizeHint, IN, unsigned int, width, IN, unsigned int, height,
Properties::NON_VIRTUAL,
__void__setTextureSizeHint__unsigned_int__unsigned_int,
@ -218,6 +228,9 @@ BEGIN_OBJECT_REFLECTOR(osgText::Font)
I_SimpleProperty(unsigned int, GlyphImageMargin,
__unsigned_int__getGlyphImageMargin,
__void__setGlyphImageMargin__unsigned_int);
I_SimpleProperty(float, GlyphImageMarginRatio,
__float__getGlyphImageMarginRatio,
__void__setGlyphImageMarginRatio__float);
I_SimpleProperty(osgText::Font::FontImplementation *, Implementation,
__FontImplementation_P1__getImplementation,
__void__setImplementation__FontImplementation_P1);
@ -468,6 +481,16 @@ BEGIN_OBJECT_REFLECTOR(osgText::Font::GlyphTexture)
__unsigned_int__getGlyphImageMargin,
"",
"");
I_Method1(void, setGlyphImageMarginRatio, IN, float, margin,
Properties::NON_VIRTUAL,
__void__setGlyphImageMarginRatio__float,
"",
"");
I_Method0(float, getGlyphImageMarginRatio,
Properties::NON_VIRTUAL,
__float__getGlyphImageMarginRatio,
"",
"");
I_Method3(bool, getSpaceForGlyph, IN, osgText::Font::Glyph *, glyph, IN, int &, posX, IN, int &, posY,
Properties::NON_VIRTUAL,
__bool__getSpaceForGlyph__Glyph_P1__int_R1__int_R1,
@ -496,6 +519,9 @@ BEGIN_OBJECT_REFLECTOR(osgText::Font::GlyphTexture)
I_SimpleProperty(unsigned int, GlyphImageMargin,
__unsigned_int__getGlyphImageMargin,
__void__setGlyphImageMargin__unsigned_int);
I_SimpleProperty(float, GlyphImageMarginRatio,
__float__getGlyphImageMarginRatio,
__void__setGlyphImageMarginRatio__float);
I_SimpleProperty(bool, ThreadSafeRefUnref,
0,
__void__setThreadSafeRefUnref__bool);