Simplified and improved the glyph margin computation and usage
This commit is contained in:
parent
beb5801eee
commit
d2fa7c4317
@ -68,9 +68,6 @@ struct TextSettings
|
|||||||
minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR),
|
minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR),
|
||||||
magFilter(osg::Texture::LINEAR),
|
magFilter(osg::Texture::LINEAR),
|
||||||
maxAnisotropy(16.0f),
|
maxAnisotropy(16.0f),
|
||||||
glyphImageMargin(1),
|
|
||||||
glyphImageMarginRatio(0.02),
|
|
||||||
glyphInterval(1),
|
|
||||||
glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE),
|
glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE),
|
||||||
textColor(1.0f, 1.0f, 1.0f, 1.0f),
|
textColor(1.0f, 1.0f, 1.0f, 1.0f),
|
||||||
backdropType(osgText::Text::NONE),
|
backdropType(osgText::Text::NONE),
|
||||||
@ -118,10 +115,6 @@ struct TextSettings
|
|||||||
|
|
||||||
if (arguments.read("--anisotropy",maxAnisotropy)) {}
|
if (arguments.read("--anisotropy",maxAnisotropy)) {}
|
||||||
|
|
||||||
if (arguments.read("--margin", glyphImageMargin)) {}
|
|
||||||
if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {}
|
|
||||||
if (arguments.read("--interval", glyphInterval)) {}
|
|
||||||
|
|
||||||
|
|
||||||
if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE;
|
if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE;
|
||||||
if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT;
|
if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT;
|
||||||
@ -158,12 +151,9 @@ struct TextSettings
|
|||||||
|
|
||||||
if (!font) font = osgText::Font::getDefaultFont();
|
if (!font) font = osgText::Font::getDefaultFont();
|
||||||
|
|
||||||
font->setGlyphImageMargin(glyphImageMargin);
|
|
||||||
font->setGlyphImageMarginRatio(glyphImageMarginRatio);
|
|
||||||
font->setMinFilterHint(minFilter);
|
font->setMinFilterHint(minFilter);
|
||||||
font->setMagFilterHint(magFilter);
|
font->setMagFilterHint(magFilter);
|
||||||
font->setMaxAnisotropy(maxAnisotropy);
|
font->setMaxAnisotropy(maxAnisotropy);
|
||||||
font->setGlyphInterval(glyphInterval);
|
|
||||||
font->setGyphTextureFeatures(glyphTextureFeatures);
|
font->setGyphTextureFeatures(glyphTextureFeatures);
|
||||||
|
|
||||||
text.setColor(textColor);
|
text.setColor(textColor);
|
||||||
@ -184,9 +174,6 @@ struct TextSettings
|
|||||||
osg::Texture::FilterMode minFilter;
|
osg::Texture::FilterMode minFilter;
|
||||||
osg::Texture::FilterMode magFilter;
|
osg::Texture::FilterMode magFilter;
|
||||||
float maxAnisotropy;
|
float maxAnisotropy;
|
||||||
unsigned int glyphImageMargin;
|
|
||||||
float glyphImageMarginRatio;
|
|
||||||
int glyphInterval;
|
|
||||||
osgText::GlyphTexture::Features glyphTextureFeatures;
|
osgText::GlyphTexture::Features glyphTextureFeatures;
|
||||||
|
|
||||||
osg::Vec4 textColor;
|
osg::Vec4 textColor;
|
||||||
@ -204,22 +191,18 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne
|
|||||||
|
|
||||||
settings.setText(*label);
|
settings.setText(*label);
|
||||||
|
|
||||||
|
|
||||||
if (settings.scaleFontSizeToFontResolution)
|
if (settings.scaleFontSizeToFontResolution)
|
||||||
{
|
{
|
||||||
label->setCharacterSize(size);
|
label->setCharacterSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
label->setFontResolution(size, size);
|
label->setFontResolution(size, size);
|
||||||
label->setPosition(pos);
|
label->setPosition(pos);
|
||||||
label->setAlignment(osgText::Text::LEFT_BOTTOM);
|
label->setAlignment(osgText::Text::LEFT_BOTTOM);
|
||||||
|
|
||||||
|
|
||||||
// It seems to be important we do this last to get best results?
|
// It seems to be important we do this last to get best results?
|
||||||
label->setText(l);
|
label->setText(l);
|
||||||
|
|
||||||
|
|
||||||
// textInfo(label);
|
// textInfo(label);
|
||||||
|
|
||||||
pos.y() += label->getCharacterHeight()*2.0;
|
pos.y() += label->getCharacterHeight()*2.0;
|
||||||
|
@ -107,23 +107,6 @@ public:
|
|||||||
* return true on success, return false when not supported.*/
|
* return true on success, return false when not supported.*/
|
||||||
virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; }
|
virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; }
|
||||||
|
|
||||||
/** Set the margin around each glyph,
|
|
||||||
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
|
|
||||||
* 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 interval that glyph positions are clamped to.
|
|
||||||
* Default interval is 1 texels.*/
|
|
||||||
void setGlyphInterval(int interval);
|
|
||||||
int getGlyphInterval() const;
|
|
||||||
|
|
||||||
|
|
||||||
void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; }
|
void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; }
|
||||||
GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; }
|
GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; }
|
||||||
@ -202,9 +185,7 @@ protected:
|
|||||||
|
|
||||||
// current active size of font
|
// current active size of font
|
||||||
FontResolution _fontSize;
|
FontResolution _fontSize;
|
||||||
unsigned int _margin;
|
|
||||||
float _marginRatio;
|
|
||||||
int _glyphInterval;
|
|
||||||
GlyphTexture::Features _glyphTextureFeatures;
|
GlyphTexture::Features _glyphTextureFeatures;
|
||||||
|
|
||||||
unsigned int _textureWidthHint;
|
unsigned int _textureWidthHint;
|
||||||
|
@ -93,6 +93,9 @@ public:
|
|||||||
void setMaxTexCoord(const osg::Vec2& coord);
|
void setMaxTexCoord(const osg::Vec2& coord);
|
||||||
const osg::Vec2& getMaxTexCoord() const;
|
const osg::Vec2& getMaxTexCoord() const;
|
||||||
|
|
||||||
|
void setTexelMargin(float margin) { _texelMargin = margin; }
|
||||||
|
float getTexelMargin() const { return _texelMargin; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual ~Glyph();
|
virtual ~Glyph();
|
||||||
@ -116,6 +119,7 @@ protected:
|
|||||||
int _texturePosY;
|
int _texturePosY;
|
||||||
osg::Vec2 _minTexCoord;
|
osg::Vec2 _minTexCoord;
|
||||||
osg::Vec2 _maxTexCoord;
|
osg::Vec2 _maxTexCoord;
|
||||||
|
float _texelMargin;
|
||||||
|
|
||||||
typedef osg::buffered_value<GLuint> GLObjectList;
|
typedef osg::buffered_value<GLuint> GLObjectList;
|
||||||
mutable GLObjectList _globjList;
|
mutable GLObjectList _globjList;
|
||||||
@ -256,16 +260,6 @@ public:
|
|||||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
|
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
|
||||||
virtual int compare(const osg::StateAttribute& rhs) const;
|
virtual int compare(const osg::StateAttribute& rhs) const;
|
||||||
|
|
||||||
/** 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; }
|
|
||||||
|
|
||||||
void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; }
|
|
||||||
float getGlyphImageMarginRatio() const { return _marginRatio; }
|
|
||||||
|
|
||||||
void setGlyphInterval(int interval) { _interval = interval; }
|
|
||||||
int getGlyphInterval() const { return _interval; }
|
|
||||||
|
|
||||||
enum Features
|
enum Features
|
||||||
{
|
{
|
||||||
GREYSCALE,
|
GREYSCALE,
|
||||||
@ -277,6 +271,10 @@ public:
|
|||||||
void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; }
|
void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; }
|
||||||
Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; }
|
Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; }
|
||||||
|
|
||||||
|
|
||||||
|
int getEffectMargin(const Glyph* glyph);
|
||||||
|
int getTexelMargin(const Glyph* glyph);
|
||||||
|
|
||||||
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
|
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
|
||||||
|
|
||||||
void addGlyph(Glyph* glyph,int posX, int posY);
|
void addGlyph(Glyph* glyph,int posX, int posY);
|
||||||
@ -296,12 +294,6 @@ protected:
|
|||||||
|
|
||||||
void copyGlyphImage(Glyph* glyph);
|
void copyGlyphImage(Glyph* glyph);
|
||||||
|
|
||||||
|
|
||||||
// parameter used to compute the size and position of empty space
|
|
||||||
// in the texture which could accommodate new glyphs.
|
|
||||||
int _margin;
|
|
||||||
float _marginRatio;
|
|
||||||
int _interval;
|
|
||||||
Features _glyphTextureFeatures;
|
Features _glyphTextureFeatures;
|
||||||
|
|
||||||
int _usedY;
|
int _usedY;
|
||||||
|
@ -278,19 +278,6 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize)
|
|||||||
|
|
||||||
int width = fontSize.first;
|
int width = fontSize.first;
|
||||||
int height = fontSize.second;
|
int height = fontSize.second;
|
||||||
int maxAxis = std::max(width, height);
|
|
||||||
int margin = _facade->getGlyphImageMargin() + (int)((float)maxAxis * _facade->getGlyphImageMarginRatio());
|
|
||||||
|
|
||||||
if ((unsigned int)(width+2*margin) > _facade->getTextureWidthHint() ||
|
|
||||||
(unsigned int)(width+2*margin) > _facade->getTextureHeightHint())
|
|
||||||
{
|
|
||||||
OSG_WARN<<"Warning: FreeTypeFont::setSize("<<width<<","<<height<<") sizes too large,"<<std::endl;
|
|
||||||
|
|
||||||
width = _facade->getTextureWidthHint()-2*margin;
|
|
||||||
height = _facade->getTextureHeightHint()-2*margin;
|
|
||||||
|
|
||||||
OSG_WARN<<" sizes capped ("<<width<<","<<height<<") to fit int current glyph texture size."<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
FT_Error error = FT_Set_Pixel_Sizes( _face, /* handle to face object */
|
FT_Error error = FT_Set_Pixel_Sizes( _face, /* handle to face object */
|
||||||
width, /* pixel_width */
|
width, /* pixel_width */
|
||||||
|
@ -29,9 +29,6 @@ DefaultFont::DefaultFont()
|
|||||||
_minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR;
|
_minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR;
|
||||||
_magFilterHint = osg::Texture::NEAREST;
|
_magFilterHint = osg::Texture::NEAREST;
|
||||||
|
|
||||||
_margin = 8;
|
|
||||||
_marginRatio = 0.0;
|
|
||||||
_glyphInterval = 16;
|
|
||||||
|
|
||||||
constructGlyphs();
|
constructGlyphs();
|
||||||
}
|
}
|
||||||
|
@ -224,9 +224,6 @@ osg::ref_ptr<Font> osgText::readRefFontStream(std::istream& stream, const osgDB:
|
|||||||
|
|
||||||
Font::Font(FontImplementation* implementation):
|
Font::Font(FontImplementation* implementation):
|
||||||
osg::Object(true),
|
osg::Object(true),
|
||||||
_margin(1),
|
|
||||||
_marginRatio(0.02),
|
|
||||||
_glyphInterval(1),
|
|
||||||
#if 0
|
#if 0
|
||||||
_glyphTextureFeatures(GlyphTexture::ALL_FEATURES),
|
_glyphTextureFeatures(GlyphTexture::ALL_FEATURES),
|
||||||
#else
|
#else
|
||||||
@ -289,32 +286,6 @@ std::string Font::getFileName() const
|
|||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::setGlyphImageMargin(unsigned int margin)
|
|
||||||
{
|
|
||||||
_margin = margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Font::getGlyphImageMargin() const
|
|
||||||
{
|
|
||||||
return _margin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setGlyphImageMarginRatio(float ratio)
|
|
||||||
{
|
|
||||||
_marginRatio = ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Font::getGlyphImageMarginRatio() const
|
|
||||||
{
|
|
||||||
return _marginRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Font::setGlyphInterval(int interval)
|
|
||||||
{
|
|
||||||
_glyphInterval = interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Font::setTextureSizeHint(unsigned int width,unsigned int height)
|
void Font::setTextureSizeHint(unsigned int width,unsigned int height)
|
||||||
{
|
{
|
||||||
_textureWidthHint = width;
|
_textureWidthHint = width;
|
||||||
@ -514,9 +485,6 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
|||||||
OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<<numberOfTexturesAllocated<<std::endl;
|
OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<<numberOfTexturesAllocated<<std::endl;
|
||||||
|
|
||||||
// reserve enough space for the glyphs.
|
// reserve enough space for the glyphs.
|
||||||
glyphTexture->setGlyphImageMargin(_margin);
|
|
||||||
glyphTexture->setGlyphImageMarginRatio(_marginRatio);
|
|
||||||
glyphTexture->setGlyphInterval(_glyphInterval);
|
|
||||||
glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures);
|
glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures);
|
||||||
glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint);
|
glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint);
|
||||||
glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint);
|
glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint);
|
||||||
|
@ -37,9 +37,6 @@ using namespace std;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
GlyphTexture::GlyphTexture():
|
GlyphTexture::GlyphTexture():
|
||||||
_margin(1),
|
|
||||||
_marginRatio(0.02f),
|
|
||||||
_interval(1),
|
|
||||||
_usedY(0),
|
_usedY(0),
|
||||||
_partUsedX(0),
|
_partUsedX(0),
|
||||||
_partUsedY(0)
|
_partUsedY(0)
|
||||||
@ -60,21 +57,39 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GlyphTexture::getEffectMargin(const Glyph* glyph)
|
||||||
|
{
|
||||||
|
if (_glyphTextureFeatures==GREYSCALE) return 0;
|
||||||
|
else return glyph->getFontResolution().second/4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GlyphTexture::getTexelMargin(const Glyph* glyph)
|
||||||
|
{
|
||||||
|
int width = glyph->s();
|
||||||
|
int height = glyph->t();
|
||||||
|
int effect_margin = getEffectMargin(glyph);
|
||||||
|
|
||||||
|
int max_dimension = std::max(width, height) + 2 * effect_margin;
|
||||||
|
int margin = osg::maximum(max_dimension/4, 2) + effect_margin;
|
||||||
|
|
||||||
|
return margin;
|
||||||
|
}
|
||||||
|
|
||||||
bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||||
{
|
{
|
||||||
int maxAxis = osg::maximum(glyph->s(), glyph->t());
|
int width = glyph->s();
|
||||||
int margin_from_ratio = (int)((float)maxAxis * _marginRatio);
|
int height = glyph->t();
|
||||||
int search_distance = glyph->getFontResolution().second/8;
|
|
||||||
|
|
||||||
int margin = _margin + osg::maximum(margin_from_ratio, search_distance);
|
int margin = getTexelMargin(glyph);
|
||||||
|
|
||||||
int width = glyph->s()+2*margin;
|
width += 2*margin;
|
||||||
int height = glyph->t()+2*margin;
|
height += 2*margin;
|
||||||
|
|
||||||
int partUsedX = ((_partUsedX % _interval) == 0) ? _partUsedX : (((_partUsedX/_interval)+1)*_interval);
|
int interval = 4;
|
||||||
int partUsedY = ((_partUsedY % _interval) == 0) ? _partUsedY : (((_partUsedY/_interval)+1)*_interval);
|
|
||||||
int usedY = ((_usedY % _interval) == 0) ? _usedY : (((_usedY/_interval)+1)*_interval);
|
int partUsedX = ((_partUsedX % interval) == 0) ? _partUsedX : (((_partUsedX/interval)+1)*interval);
|
||||||
|
int partUsedY = ((_partUsedY % interval) == 0) ? _partUsedY : (((_partUsedY/interval)+1)*interval);
|
||||||
|
int usedY = ((_usedY % interval) == 0) ? _usedY : (((_usedY/interval)+1)*interval);
|
||||||
|
|
||||||
// first check box (partUsedX, usedY) to (width,height)
|
// first check box (partUsedX, usedY) to (width,height)
|
||||||
if (width <= (getTextureWidth()-partUsedX) &&
|
if (width <= (getTextureWidth()-partUsedX) &&
|
||||||
@ -132,6 +147,9 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
|
|||||||
glyph->setMaxTexCoord( osg::Vec2( static_cast<float>(posX+glyph->s())/static_cast<float>(getTextureWidth()),
|
glyph->setMaxTexCoord( osg::Vec2( static_cast<float>(posX+glyph->s())/static_cast<float>(getTextureWidth()),
|
||||||
static_cast<float>(posY+glyph->t())/static_cast<float>(getTextureHeight()) ) );
|
static_cast<float>(posY+glyph->t())/static_cast<float>(getTextureHeight()) ) );
|
||||||
|
|
||||||
|
|
||||||
|
glyph->setTexelMargin(float(getTexelMargin(glyph)));
|
||||||
|
|
||||||
copyGlyphImage(glyph);
|
copyGlyphImage(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +174,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph)
|
|||||||
int dest_rows = _image->t();
|
int dest_rows = _image->t();
|
||||||
unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY());
|
unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY());
|
||||||
|
|
||||||
int search_distance = glyph->getFontResolution().second/4;
|
int search_distance = getEffectMargin(glyph);
|
||||||
|
|
||||||
int left = -search_distance;
|
int left = -search_distance;
|
||||||
int right = glyph->s()+search_distance;
|
int right = glyph->s()+search_distance;
|
||||||
|
@ -464,8 +464,6 @@ void Text::computeGlyphRepresentation()
|
|||||||
float hr = _characterHeight;
|
float hr = _characterHeight;
|
||||||
float wr = hr/getCharacterAspectRatio();
|
float wr = hr/getCharacterAspectRatio();
|
||||||
|
|
||||||
float texelMargin = 5.0f;
|
|
||||||
|
|
||||||
for(String::iterator itr=_text.begin();
|
for(String::iterator itr=_text.begin();
|
||||||
itr!=_text.end();
|
itr!=_text.end();
|
||||||
)
|
)
|
||||||
@ -632,6 +630,7 @@ void Text::computeGlyphRepresentation()
|
|||||||
osg::Vec2 mintc = glyph->getMinTexCoord();
|
osg::Vec2 mintc = glyph->getMinTexCoord();
|
||||||
osg::Vec2 maxtc = glyph->getMaxTexCoord();
|
osg::Vec2 maxtc = glyph->getMaxTexCoord();
|
||||||
osg::Vec2 vDiff = maxtc - mintc;
|
osg::Vec2 vDiff = maxtc - mintc;
|
||||||
|
float texelMargin = glyph->getTexelMargin();
|
||||||
|
|
||||||
float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth();
|
float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth();
|
||||||
float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight();
|
float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight();
|
||||||
|
Loading…
Reference in New Issue
Block a user