Refactored osgText::Font so that it now supports both 2D and 3D glyphs.
Added TextNode.h and TextNode.cpp to examples/osgtext3D in prep for introducing the new node to osgText library
This commit is contained in:
@@ -14,16 +14,178 @@
|
||||
#include "FreeTypeFont.h"
|
||||
#include "FreeTypeLibrary.h"
|
||||
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftbbox.h>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
#include <osgUtil/Tessellator>
|
||||
|
||||
namespace FreeType
|
||||
{
|
||||
|
||||
struct Char3DInfo
|
||||
{
|
||||
Char3DInfo(int numSteps):
|
||||
_verts( new osg::Vec3Array ),
|
||||
_geometry( new osg::Geometry ),
|
||||
_idx(0),
|
||||
_numSteps(numSteps),
|
||||
_maxY(-FLT_MAX),
|
||||
_maxX(-FLT_MAX),
|
||||
_minX(FLT_MAX),
|
||||
_minY(FLT_MAX)
|
||||
{
|
||||
}
|
||||
~Char3DInfo()
|
||||
{
|
||||
}
|
||||
|
||||
osg::Geometry* get()
|
||||
{
|
||||
int len = _verts->size()-_idx;
|
||||
if (len)
|
||||
{
|
||||
_geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::POLYGON, _idx, len ) );
|
||||
_idx = _verts->size();
|
||||
}
|
||||
|
||||
_geometry->setVertexArray(_verts.get());
|
||||
return _geometry.get();
|
||||
}
|
||||
|
||||
void addVertex(const osg::Vec3& pos)
|
||||
{
|
||||
if (!_verts->empty() && _verts->back()==pos)
|
||||
{
|
||||
// OSG_NOTICE<<"addVertex("<<pos<<") duplicate, ignoring"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_verts->push_back( pos );
|
||||
setMinMax(pos);
|
||||
}
|
||||
|
||||
void moveTo(const osg::Vec2& pos)
|
||||
{
|
||||
if (_verts->size())
|
||||
{
|
||||
int len = _verts->size()-_idx;
|
||||
_geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::POLYGON, _idx, len ) );
|
||||
}
|
||||
_idx = _verts->size();
|
||||
addVertex( osg::Vec3(pos.x(),pos.y(),0) );
|
||||
|
||||
}
|
||||
void lineTo(const osg::Vec2& pos)
|
||||
{
|
||||
addVertex( osg::Vec3(pos.x(),pos.y(),0) );
|
||||
}
|
||||
void conicTo(const osg::Vec2& control, const osg::Vec2& pos)
|
||||
{
|
||||
osg::Vec3 p0 = _verts->back();
|
||||
osg::Vec3 p1 = osg::Vec3(control.x(),control.y(),0);
|
||||
osg::Vec3 p2 = osg::Vec3(pos.x(),pos.y(),0);
|
||||
|
||||
double dt = 1.0/_numSteps;
|
||||
double u=0;
|
||||
for (int i=0; i<=_numSteps; ++i)
|
||||
{
|
||||
double w = 1;
|
||||
double bs = 1.0/( (1-u)*(1-u)+2*(1-u)*u*w +u*u );
|
||||
osg::Vec3 p = (p0*((1-u)*(1-u)) + p1*(2*(1-u)*u*w) + p2*(u*u))*bs;
|
||||
addVertex( p );
|
||||
|
||||
u += dt;
|
||||
}
|
||||
}
|
||||
|
||||
void cubicTo(const osg::Vec2& control1, const osg::Vec2& control2, const osg::Vec2& pos)
|
||||
{
|
||||
osg::Vec3 p0 = _verts->back();
|
||||
osg::Vec3 p1 = osg::Vec3(control1.x(),control1.y(),0);
|
||||
osg::Vec3 p2 = osg::Vec3(control2.x(),control2.y(),0);
|
||||
osg::Vec3 p3 = osg::Vec3(pos.x(),pos.y(),0);
|
||||
|
||||
double cx = 3*(p1.x() - p0.x());
|
||||
double bx = 3*(p2.x() - p1.x()) - cx;
|
||||
double ax = p3.x() - p0.x() - cx - bx;
|
||||
double cy = 3*(p1.y() - p0.y());
|
||||
double by = 3*(p2.y() - p1.y()) - cy;
|
||||
double ay = p3.y() - p0.y() - cy - by;
|
||||
|
||||
double dt = 1.0/_numSteps;
|
||||
double u=0;
|
||||
for (int i=0; i<=_numSteps; ++i)
|
||||
{
|
||||
osg::Vec3 p = osg::Vec3( ax*u*u*u + bx*u*u + cx*u + p0.x(),ay*u*u*u + by*u*u + cy*u + p0.y(),0 );
|
||||
addVertex( p );
|
||||
|
||||
u += dt;
|
||||
}
|
||||
}
|
||||
|
||||
void setMinMax(const osg::Vec3& pos)
|
||||
{
|
||||
_maxY = std::max(_maxY, (double) pos.y());
|
||||
_minY = std::min(_minY, (double) pos.y());
|
||||
_maxX = std::max(_maxX, (double) pos.x());
|
||||
_minX = std::min(_minX, (double) pos.x());
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> _verts;
|
||||
osg::ref_ptr<osg::Geometry> _geometry;
|
||||
int _idx;
|
||||
int _numSteps;
|
||||
double _maxY;
|
||||
double _maxX;
|
||||
double _minX;
|
||||
double _minY;
|
||||
};
|
||||
|
||||
|
||||
#define FT_NUM(x) (x/64.0)
|
||||
int moveTo( const FT_Vector* to, void* user )
|
||||
{
|
||||
Char3DInfo* char3d = (Char3DInfo*)user;
|
||||
char3d->moveTo( osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) );
|
||||
return 0;
|
||||
}
|
||||
int lineTo( const FT_Vector* to, void* user )
|
||||
{
|
||||
Char3DInfo* char3d = (Char3DInfo*)user;
|
||||
char3d->lineTo( osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) );
|
||||
return 0;
|
||||
}
|
||||
int conicTo( const FT_Vector* control,const FT_Vector* to, void* user )
|
||||
{
|
||||
Char3DInfo* char3d = (Char3DInfo*)user;
|
||||
char3d->conicTo( osg::Vec2(FT_NUM(control->x),FT_NUM(control->y)), osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) );
|
||||
return 0;
|
||||
}
|
||||
int cubicTo( const FT_Vector* control1,const FT_Vector* control2,const FT_Vector* to, void* user )
|
||||
{
|
||||
Char3DInfo* char3d = (Char3DInfo*)user;
|
||||
char3d->cubicTo(
|
||||
osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)),
|
||||
osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)),
|
||||
osg::Vec2(FT_NUM(to->x),FT_NUM(to->y)) );
|
||||
return 0;
|
||||
}
|
||||
#undef FT_NUM
|
||||
|
||||
}
|
||||
|
||||
FreeTypeFont::FreeTypeFont(const std::string& filename, FT_Face face, unsigned int flags):
|
||||
_currentRes(osgText::FontResolution(0,0)),
|
||||
_filename(filename),
|
||||
_buffer(0),
|
||||
_face(face),
|
||||
_flags(flags)
|
||||
_flags(flags),
|
||||
_scale(1.0f)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
FreeTypeFont::FreeTypeFont(FT_Byte* buffer, FT_Face face, unsigned int flags):
|
||||
@@ -31,8 +193,10 @@ FreeTypeFont::FreeTypeFont(FT_Byte* buffer, FT_Face face, unsigned int flags):
|
||||
_filename(""),
|
||||
_buffer(buffer),
|
||||
_face(face),
|
||||
_flags(flags)
|
||||
_flags(flags),
|
||||
_scale(1.0f)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
FreeTypeFont::~FreeTypeFont()
|
||||
@@ -60,6 +224,65 @@ FreeTypeFont::~FreeTypeFont()
|
||||
}
|
||||
}
|
||||
|
||||
void FreeTypeFont::init()
|
||||
{
|
||||
|
||||
FT_Error _error = FT_Set_Pixel_Sizes(_face, 32, 32);
|
||||
if (_error)
|
||||
{
|
||||
OSG_NOTICE << "FreeTypeFont3D: set pixel sizes failed ..." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);
|
||||
|
||||
int glyphIndex = FT_Get_Char_Index( _face, 'M' );
|
||||
_error = FT_Load_Glyph( _face, glyphIndex, FT_LOAD_DEFAULT );
|
||||
if (_error)
|
||||
{
|
||||
OSG_NOTICE << "FreeTypeFont3D: initial glyph load failed ..." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
OSG_NOTICE << "FreeTypeFont3D: not a vector font" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
FreeType::Char3DInfo char3d(10);
|
||||
|
||||
FT_Outline outline = _face->glyph->outline;
|
||||
FT_Outline_Funcs funcs;
|
||||
funcs.conic_to = (FT_Outline_ConicToFunc)&FreeType::conicTo;
|
||||
funcs.line_to = (FT_Outline_LineToFunc)&FreeType::lineTo;
|
||||
funcs.cubic_to = (FT_Outline_CubicToFunc)&FreeType::cubicTo;
|
||||
funcs.move_to = (FT_Outline_MoveToFunc)&FreeType::moveTo;
|
||||
funcs.shift = 0;
|
||||
funcs.delta = 0;
|
||||
_error = FT_Outline_Decompose(&outline,&funcs,&char3d);
|
||||
if (_error)
|
||||
{
|
||||
OSG_NOTICE << "FreeTypeFont3D: - outline decompose failed ..." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
FT_BBox bb;
|
||||
FT_Outline_Get_BBox(&outline,&bb);
|
||||
|
||||
long ymin = ft_floor( bb.yMin );
|
||||
long ymax = ft_ceiling( bb.yMax );
|
||||
double height = double(ymax - ymin)/64.0;
|
||||
|
||||
// long xmin = ft_floor( bb.xMin );
|
||||
// long xmax = ft_ceiling( bb.xMax );
|
||||
// double width = (xmax - xmin)/64.0;
|
||||
|
||||
_scale = 1.0/height;
|
||||
}
|
||||
}
|
||||
|
||||
void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize)
|
||||
{
|
||||
if (fontSize==_currentRes) return;
|
||||
@@ -95,7 +318,7 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize)
|
||||
|
||||
}
|
||||
|
||||
osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode)
|
||||
osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());
|
||||
|
||||
@@ -135,7 +358,7 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& font
|
||||
unsigned int width = sourceWidth;
|
||||
unsigned int height = sourceHeight;
|
||||
|
||||
osg::ref_ptr<osgText::Font::Glyph> glyph = new osgText::Font::Glyph(charcode);
|
||||
osg::ref_ptr<osgText::Glyph> glyph = new osgText::Glyph(charcode);
|
||||
|
||||
unsigned int dataSize = width*height;
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
@@ -191,14 +414,212 @@ osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& font
|
||||
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(fontRes,charcode,glyph.get());
|
||||
|
||||
// cout << " in getGlyph() implementation="<<this<<" "<<_filename<<" facade="<<_facade<<endl;
|
||||
|
||||
return glyph.get();
|
||||
return glyph.release();
|
||||
|
||||
}
|
||||
|
||||
osgText::Glyph3D * FreeTypeFont::getGlyph3D(unsigned int charcode)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());
|
||||
|
||||
//
|
||||
// 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
|
||||
// values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.
|
||||
// Microsoft uses a private field for its symbol fonts
|
||||
//
|
||||
unsigned int charindex = charcode;
|
||||
if (_face->charmap != NULL)
|
||||
{
|
||||
if (_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
|
||||
{
|
||||
charindex |= 0xF000;
|
||||
}
|
||||
}
|
||||
|
||||
FT_Error error = FT_Load_Char( _face, charindex, FT_LOAD_DEFAULT|_flags );
|
||||
if (error)
|
||||
{
|
||||
OSG_WARN << "FT_Load_Char(...) error 0x"<<std::hex<<error<<std::dec<<std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
OSG_WARN << "FreeTypeFont3D::getGlyph : not a vector font" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ** init FreeType to describe the glyph
|
||||
FreeType::Char3DInfo char3d(_facade->getNumberCurveSamples());
|
||||
|
||||
FT_Outline outline = _face->glyph->outline;
|
||||
FT_Outline_Funcs funcs;
|
||||
funcs.conic_to = (FT_Outline_ConicToFunc)&FreeType::conicTo;
|
||||
funcs.line_to = (FT_Outline_LineToFunc)&FreeType::lineTo;
|
||||
funcs.cubic_to = (FT_Outline_CubicToFunc)&FreeType::cubicTo;
|
||||
funcs.move_to = (FT_Outline_MoveToFunc)&FreeType::moveTo;
|
||||
funcs.shift = 0;
|
||||
funcs.delta = 0;
|
||||
|
||||
// ** record description
|
||||
FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d);
|
||||
if (_error)
|
||||
{
|
||||
OSG_WARN << "FreeTypeFont3D::getGlyph : - outline decompose failed ..." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ** create geometry for each part of the glyph
|
||||
osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry);
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> rawVertices = new osg::Vec3Array(*(char3d._verts));
|
||||
osg::Geometry::PrimitiveSetList rawPrimitives;
|
||||
for(osg::Geometry::PrimitiveSetList::iterator itr = char3d.get()->getPrimitiveSetList().begin();
|
||||
itr != char3d.get()->getPrimitiveSetList().end();
|
||||
++itr)
|
||||
{
|
||||
rawPrimitives.push_back(dynamic_cast<osg::PrimitiveSet*>((*itr)->clone(osg::CopyOp::DEEP_COPY_ALL)));
|
||||
}
|
||||
|
||||
frontGeo->setVertexArray(char3d.get()->getVertexArray());
|
||||
frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList());
|
||||
|
||||
osg::ref_ptr<osg::Geometry> wallGeo(new osg::Geometry);
|
||||
wallGeo->setVertexArray(frontGeo->getVertexArray());
|
||||
|
||||
osg::ref_ptr<osg::Geometry> backGeo(new osg::Geometry);
|
||||
backGeo->setVertexArray(frontGeo->getVertexArray());
|
||||
|
||||
|
||||
|
||||
// ** for convenience.
|
||||
osg::Vec3Array * vertices = char3d._verts.get();
|
||||
|
||||
|
||||
|
||||
// ** duplicate the vertex for the back face
|
||||
// ** with a depth equal to the font depth
|
||||
std::size_t len = vertices->size();
|
||||
std::size_t dlen = len * 2;
|
||||
|
||||
vertices->reserve(dlen);
|
||||
|
||||
osg::Vec3Array::iterator begin = vertices->begin();
|
||||
osg::Vec3Array::iterator it = vertices->begin();
|
||||
|
||||
for (std::size_t i = 0; i != len; ++i, ++it)
|
||||
vertices->push_back(*it);
|
||||
// std::copy(begin, begin + len, begin + len + 1); TOCHECK
|
||||
|
||||
|
||||
// ** and decal new vertices
|
||||
unsigned int depth = _facade->getFontDepth();
|
||||
for (std::size_t i = len; i != dlen; ++i)
|
||||
{
|
||||
(*vertices)[i].z() -= depth;
|
||||
}
|
||||
|
||||
osg::Vec3Array::iterator end;
|
||||
|
||||
// ** create wall and back face from the front polygon
|
||||
// ** then accumulate them in the appropriate geometry wallGeo and backGeo
|
||||
for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i)
|
||||
{
|
||||
// ** get the front polygon
|
||||
osg::ref_ptr<osg::DrawArrays> daFront(dynamic_cast<osg::DrawArrays*>(frontGeo->getPrimitiveSet(i)));
|
||||
unsigned int idx = daFront->getFirst();
|
||||
unsigned int cnt = daFront->getCount();
|
||||
|
||||
// ** reverse vertices to draw the front face in the CCW
|
||||
std::reverse(begin + idx, begin + idx + cnt);
|
||||
|
||||
// ** create the back polygon
|
||||
osg::ref_ptr<osg::DrawArrays> daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt));
|
||||
backGeo->addPrimitiveSet(daBack.get());
|
||||
|
||||
|
||||
// ** create the wall triangle strip
|
||||
osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));
|
||||
wallGeo->addPrimitiveSet(deWall.get());
|
||||
|
||||
// ** link triangle strip
|
||||
deWall->push_back(idx + len);
|
||||
for (unsigned int j = 1; j < cnt; ++j)
|
||||
{
|
||||
deWall->push_back(idx + cnt - j);
|
||||
deWall->push_back(idx + len + j);
|
||||
}
|
||||
deWall->push_back(idx);
|
||||
deWall->push_back(idx + len);
|
||||
deWall->push_back(idx + cnt - 1);
|
||||
}
|
||||
|
||||
// ** tesselate front and back face
|
||||
{
|
||||
osgUtil::Tessellator ts;
|
||||
ts.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE);
|
||||
ts.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY);
|
||||
ts.retessellatePolygons(*frontGeo);
|
||||
}
|
||||
|
||||
{
|
||||
osgUtil::Tessellator ts;
|
||||
ts.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE);
|
||||
ts.setTessellationType(osgUtil::Tessellator::TESS_TYPE_GEOMETRY);
|
||||
ts.retessellatePolygons(*backGeo);
|
||||
}
|
||||
|
||||
// ** generate normal
|
||||
{
|
||||
osgUtil::SmoothingVisitor sm;
|
||||
osg::ref_ptr<osg::Geode> geode(new osg::Geode);
|
||||
geode->addDrawable(wallGeo.get());
|
||||
geode->accept(sm);
|
||||
}
|
||||
|
||||
// ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
|
||||
osg::ref_ptr<osgText::Glyph3D> glyph3D = new osgText::Glyph3D(charcode);
|
||||
|
||||
// copy the raw primitive set list before we tessellate it.
|
||||
glyph3D->getRawFacePrimitiveSetList() = rawPrimitives;
|
||||
glyph3D->setRawVertexArray(rawVertices.get());
|
||||
|
||||
glyph3D->setVertexArray(dynamic_cast<osg::Vec3Array*>(frontGeo->getVertexArray()));
|
||||
glyph3D->setNormalArray(dynamic_cast<osg::Vec3Array*>(wallGeo->getNormalArray()));
|
||||
|
||||
glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList();
|
||||
glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList();
|
||||
glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList();
|
||||
|
||||
|
||||
FT_Glyph_Metrics* metrics = &(_face->glyph->metrics);
|
||||
|
||||
glyph3D->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left.
|
||||
glyph3D->setHorizontalAdvance((float)metrics->horiAdvance/64.0f);
|
||||
glyph3D->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX/64.0f,(float)(metrics->vertBearingY-metrics->height)/64.0f)); // top middle.
|
||||
glyph3D->setVerticalAdvance((float)metrics->vertAdvance/64.0f);
|
||||
|
||||
glyph3D->setWidth((float)metrics->width / 64.0f);
|
||||
glyph3D->setHeight((float)metrics->height / 64.0f);
|
||||
|
||||
|
||||
FT_BBox ftbb;
|
||||
FT_Outline_Get_BBox(&outline, &ftbb);
|
||||
|
||||
long xmin = ft_floor( ftbb.xMin );
|
||||
long xmax = ft_ceiling( ftbb.xMax );
|
||||
long ymin = ft_floor( ftbb.yMin );
|
||||
long ymax = ft_ceiling( ftbb.yMax );
|
||||
|
||||
osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f);
|
||||
|
||||
glyph3D->setBoundingBox(bb);
|
||||
|
||||
return glyph3D.release();
|
||||
}
|
||||
|
||||
osg::Vec2 FreeTypeFont::getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());
|
||||
|
||||
@@ -31,22 +31,33 @@ public:
|
||||
|
||||
virtual std::string getFileName() const { return _filename; }
|
||||
|
||||
virtual osgText::Font::Glyph* getGlyph(const osgText::FontResolution& fontRes,unsigned int charcode);
|
||||
|
||||
virtual osgText::Glyph* getGlyph(const osgText::FontResolution& fontRes,unsigned int charcode);
|
||||
|
||||
virtual osgText::Glyph3D* getGlyph3D(unsigned int charcode);
|
||||
|
||||
virtual osg::Vec2 getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType _kerningType);
|
||||
|
||||
|
||||
virtual bool hasVertical() const;
|
||||
|
||||
virtual float getScale() const { return _scale; }
|
||||
|
||||
protected:
|
||||
|
||||
void init();
|
||||
|
||||
void setFontResolution(const osgText::FontResolution& fontSize);
|
||||
|
||||
osgText::FontResolution _currentRes;
|
||||
|
||||
long ft_round( long x ) { return (( x + 32 ) & -64); }
|
||||
long ft_floor( long x ) { return (x & -64); }
|
||||
long ft_ceiling( long x ){ return (( x + 63 ) & -64); }
|
||||
|
||||
std::string _filename;
|
||||
FT_Byte* _buffer;
|
||||
FT_Face _face;
|
||||
unsigned int _flags;
|
||||
float _scale;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include "FreeTypeFont3D.h"
|
||||
#include "FreeTypeLibrary.h"
|
||||
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftbbox.h>
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <fstream>
|
||||
@@ -26,12 +29,6 @@
|
||||
#include <osgUtil/Tessellator>
|
||||
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include <freetype/ftoutln.h>
|
||||
#include <freetype/ftbbox.h>
|
||||
|
||||
#include <osg/io_utils>
|
||||
|
||||
namespace
|
||||
@@ -195,10 +192,7 @@ FreeTypeFont3D::FreeTypeFont3D(const std::string& filename, FT_Face face, unsign
|
||||
_buffer(0),
|
||||
_face(face),
|
||||
_flags(flags),
|
||||
_scale(1.0),
|
||||
_shiftY(0.0),
|
||||
_shiftX(0.0),
|
||||
_charScale(1.0)
|
||||
_scale(1.0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -208,10 +202,7 @@ FreeTypeFont3D::FreeTypeFont3D(FT_Byte* buffer, FT_Face face, unsigned int flags
|
||||
_buffer(buffer),
|
||||
_face(face),
|
||||
_flags(flags),
|
||||
_scale(1.0),
|
||||
_shiftY(0.0),
|
||||
_shiftX(0.0),
|
||||
_charScale(1.0)
|
||||
_scale(1.0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@@ -263,26 +254,15 @@ void FreeTypeFont3D::init()
|
||||
FT_BBox bb;
|
||||
FT_Outline_Get_BBox(&outline,&bb);
|
||||
|
||||
long xmin = ft_floor( bb.xMin );
|
||||
long xmax = ft_ceiling( bb.xMax );
|
||||
long ymin = ft_floor( bb.yMin );
|
||||
long ymax = ft_ceiling( bb.yMax );
|
||||
double height = double(ymax - ymin)/64.0;
|
||||
|
||||
double width = (xmax - xmin)/64.0;
|
||||
double height = (ymax - ymin)/64.0;
|
||||
// long xmin = ft_floor( bb.xMin );
|
||||
// long xmax = ft_ceiling( bb.xMax );
|
||||
// double width = (xmax - xmin)/64.0;
|
||||
|
||||
_scale = 1.0/height;
|
||||
|
||||
double charHeight = char3d._maxY-char3d._minY;
|
||||
double charWidth = char3d._maxX-char3d._minX;
|
||||
|
||||
double dh = fabs(bb.yMin/64.0)/height;
|
||||
double dw = fabs(bb.xMin/64.0)/width;
|
||||
|
||||
_shiftY = char3d._minY + dh*charHeight;
|
||||
_shiftX = char3d._minX + dw*charWidth;
|
||||
|
||||
_charScale = 1/charHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +292,7 @@ FreeTypeFont3D::~FreeTypeFont3D()
|
||||
}
|
||||
|
||||
|
||||
osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
osgText::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());
|
||||
|
||||
@@ -472,7 +452,7 @@ osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
|
||||
}
|
||||
|
||||
// ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
|
||||
osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode);
|
||||
osgText::Glyph3D * glyph3D = new osgText::Glyph3D(charcode);
|
||||
|
||||
// copy the raw primitive set list before we tessellate it.
|
||||
glyph3D->getRawFacePrimitiveSetList() = rawPrimitives;
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
virtual std::string getFileName() const { return _filename; }
|
||||
|
||||
virtual osgText::Font3D::Glyph3D * getGlyph(unsigned int charcode);
|
||||
virtual osgText::Glyph3D * getGlyph(unsigned int charcode);
|
||||
|
||||
virtual osg::Vec2 getKerning(unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType _kerningType);
|
||||
|
||||
@@ -52,11 +52,7 @@ protected:
|
||||
FT_Face _face;
|
||||
unsigned int _flags;
|
||||
|
||||
|
||||
double _scale;
|
||||
double _shiftY;
|
||||
double _shiftX;
|
||||
double _charScale;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -81,8 +81,7 @@ TXFFont::getFileName() const
|
||||
return _filename;
|
||||
}
|
||||
|
||||
osgText::Font::Glyph*
|
||||
TXFFont::getGlyph(const osgText::FontResolution&, unsigned int charcode)
|
||||
osgText::Glyph* TXFFont::getGlyph(const osgText::FontResolution&, unsigned int charcode)
|
||||
{
|
||||
GlyphMap::iterator i = _chars.find(charcode);
|
||||
if (i != _chars.end())
|
||||
@@ -96,7 +95,6 @@ TXFFont::getGlyph(const osgText::FontResolution&, unsigned int charcode)
|
||||
if (i != _chars.end())
|
||||
{
|
||||
_chars[charcode] = i->second;
|
||||
addGlyph(osgText::FontResolution(i->second->s(), i->second->t()), charcode, i->second.get());
|
||||
return i->second.get();
|
||||
}
|
||||
}
|
||||
@@ -106,7 +104,6 @@ TXFFont::getGlyph(const osgText::FontResolution&, unsigned int charcode)
|
||||
if (i != _chars.end())
|
||||
{
|
||||
_chars[charcode] = i->second;
|
||||
addGlyph(osgText::FontResolution(i->second->s(), i->second->t()), charcode, i->second.get());
|
||||
return i->second.get();
|
||||
}
|
||||
}
|
||||
@@ -230,7 +227,7 @@ TXFFont::loadFont(std::istream& stream)
|
||||
continue;
|
||||
|
||||
// add the characters ...
|
||||
osgText::Font::Glyph* glyph = new osgText::Font::Glyph(glyphs[i].ch);
|
||||
osgText::Glyph* glyph = new osgText::Glyph(glyphs[i].ch);
|
||||
|
||||
unsigned sourceWidth = glyphs[i].width;
|
||||
unsigned sourceHeight = glyphs[i].height;
|
||||
@@ -267,11 +264,12 @@ TXFFont::loadFont(std::istream& stream)
|
||||
- glyphs[i].height*texToVertY));
|
||||
|
||||
_chars[glyphs[i].ch] = glyph;
|
||||
|
||||
addGlyph(fontResolution, glyphs[i].ch, glyph);
|
||||
}
|
||||
|
||||
// insert a trivial blank character
|
||||
osgText::Font::Glyph* glyph = new osgText::Font::Glyph(' ');
|
||||
osgText::Glyph* glyph = new osgText::Glyph(' ');
|
||||
|
||||
unsigned width = 1;
|
||||
unsigned height = 1;
|
||||
|
||||
@@ -28,16 +28,20 @@ public:
|
||||
|
||||
virtual std::string getFileName() const;
|
||||
|
||||
virtual osgText::Font::Glyph* getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode);
|
||||
virtual osgText::Glyph* getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode);
|
||||
|
||||
virtual osgText::Glyph3D* getGlyph3D(unsigned int) { return 0; }
|
||||
|
||||
virtual bool hasVertical() const;
|
||||
|
||||
virtual osg::Vec2 getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode,unsigned int rightcharcode, osgText::KerningType kerningType);
|
||||
|
||||
virtual float getScale() const { return 1.0; }
|
||||
|
||||
bool loadFont(std::istream& stream);
|
||||
|
||||
protected:
|
||||
typedef std::map<unsigned int, osg::ref_ptr<osgText::Font::Glyph> > GlyphMap;
|
||||
typedef std::map<unsigned int, osg::ref_ptr<osgText::Glyph> > GlyphMap;
|
||||
|
||||
std::string _filename;
|
||||
GlyphMap _chars;
|
||||
|
||||
@@ -51,7 +51,7 @@ QFontImplementation::setFontResolution(const osgText::FontResolution& fontSize)
|
||||
_font.setPixelSize(fontSize.second);
|
||||
}
|
||||
|
||||
osgText::Font::Glyph*
|
||||
osgText::Glyph*
|
||||
QFontImplementation::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode)
|
||||
{
|
||||
setFontResolution(fontRes);
|
||||
@@ -83,7 +83,7 @@ QFontImplementation::getGlyph(const osgText::FontResolution& fontRes, unsigned i
|
||||
painter.end();
|
||||
|
||||
// Transfer the rendered image to osg
|
||||
osg::ref_ptr<osgText::Font::Glyph> glyph = new osgText::Font::Glyph(charcode);
|
||||
osg::ref_ptr<osgText::Glyph> glyph = new osgText::Glyph(charcode);
|
||||
|
||||
unsigned int dataSize = imageWidth*imageHeight;
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
|
||||
@@ -33,23 +33,12 @@ DefaultFont::~DefaultFont()
|
||||
{
|
||||
}
|
||||
|
||||
DefaultFont* DefaultFont::instance()
|
||||
{
|
||||
static OpenThreads::Mutex s_DefaultFontMutex;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_DefaultFontMutex);
|
||||
|
||||
static osg::ref_ptr<DefaultFont> s_defaultFont = new DefaultFont;
|
||||
return s_defaultFont.get();
|
||||
}
|
||||
|
||||
void DefaultFont::setSize(unsigned int, unsigned int)
|
||||
{
|
||||
OSG_INFO<<"DefaultFont::setSize(,) call is ignored."<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Font::Glyph* DefaultFont::getGlyph(const FontResolution& fontRes, unsigned int charcode)
|
||||
osgText::Glyph* DefaultFont::getGlyph(const FontResolution& fontRes, unsigned int charcode)
|
||||
{
|
||||
if (_sizeGlyphMap.empty()) return 0;
|
||||
|
||||
|
||||
@@ -26,22 +26,25 @@ class DefaultFont : public Font
|
||||
{
|
||||
public:
|
||||
|
||||
static DefaultFont* instance();
|
||||
DefaultFont();
|
||||
|
||||
virtual std::string getFileName() const { return ""; }
|
||||
|
||||
/** 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(const FontResolution& fontRes, unsigned int charcode);
|
||||
virtual osgText::Glyph* getGlyph(const FontResolution& fontRes, unsigned int charcode);
|
||||
|
||||
virtual osgText::Glyph3D* getGlyph3D(unsigned int charcode) { return 0; }
|
||||
|
||||
virtual osg::Vec2 getKerning(const FontResolution&, unsigned int leftcharcode,unsigned int rightcharcode, KerningType kerningType);
|
||||
|
||||
virtual bool hasVertical() const;
|
||||
|
||||
virtual float getScale() const { return 1.0; }
|
||||
|
||||
protected:
|
||||
|
||||
DefaultFont();
|
||||
virtual ~DefaultFont();
|
||||
|
||||
void constructGlyphs();
|
||||
|
||||
@@ -27,11 +27,23 @@
|
||||
|
||||
#include <OpenThreads/ReentrantMutex>
|
||||
|
||||
#include "DefaultFont.h"
|
||||
|
||||
using namespace osgText;
|
||||
using namespace std;
|
||||
|
||||
static osg::ApplicationUsageProxy Font_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_TEXT_INCREMENTAL_SUBLOADING <type>","ON | OFF");
|
||||
|
||||
|
||||
osg::ref_ptr<Font>& Font::getDefaultFont()
|
||||
{
|
||||
static OpenThreads::Mutex s_DefaultFontMutex;
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_DefaultFontMutex);
|
||||
|
||||
static osg::ref_ptr<Font> s_defaultFont = new DefaultFont;
|
||||
return s_defaultFont;
|
||||
}
|
||||
|
||||
static OpenThreads::ReentrantMutex s_FontFileMutex;
|
||||
|
||||
std::string osgText::findFontFile(const std::string& str)
|
||||
@@ -210,7 +222,9 @@ Font::Font(FontImplementation* implementation):
|
||||
_textureWidthHint(1024),
|
||||
_textureHeightHint(1024),
|
||||
_minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR),
|
||||
_magFilterHint(osg::Texture::LINEAR)
|
||||
_magFilterHint(osg::Texture::LINEAR),
|
||||
_depth(1),
|
||||
_numCurveSamples(10)
|
||||
{
|
||||
setImplementation(implementation);
|
||||
|
||||
@@ -326,23 +340,46 @@ osg::Texture::FilterMode Font::getMagFilterHint() const
|
||||
}
|
||||
|
||||
|
||||
Font::Glyph* Font::getGlyph(const FontResolution& fontRes, unsigned int charcode)
|
||||
Glyph* Font::getGlyph(const FontResolution& fontRes, unsigned int charcode)
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_glyphMapMutex);
|
||||
FontSizeGlyphMap::iterator itr = _sizeGlyphMap.find(fontRes);
|
||||
if (itr!=_sizeGlyphMap.end())
|
||||
{
|
||||
GlyphMap& glyphmap = itr->second;
|
||||
GlyphMap& glyphmap = itr->second;
|
||||
GlyphMap::iterator gitr = glyphmap.find(charcode);
|
||||
if (gitr!=glyphmap.end()) return gitr->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
if (_implementation.valid()) return _implementation->getGlyph(fontRes, charcode);
|
||||
|
||||
Glyph* glyph = _implementation.valid() ? _implementation->getGlyph(fontRes, charcode) : 0;
|
||||
if (glyph)
|
||||
{
|
||||
addGlyph(fontRes, charcode, glyph);
|
||||
return glyph;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
Glyph3D* Font::getGlyph3D(unsigned int charcode)
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_glyphMapMutex);
|
||||
Glyph3DMap::iterator itr = _glyph3DMap.find(charcode);
|
||||
if (itr!=_glyph3DMap.end()) return itr->second.get();
|
||||
}
|
||||
|
||||
Glyph3D* glyph = _implementation.valid() ? _implementation->getGlyph3D(charcode) : 0;
|
||||
if (glyph)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_glyphMapMutex);
|
||||
_glyph3DMap[charcode] = glyph;
|
||||
return glyph;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Font::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
osg::Object::setThreadSafeRefUnref(threadSafe);
|
||||
@@ -454,7 +491,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
||||
}
|
||||
|
||||
|
||||
Font::GlyphTexture::GlyphTexture():
|
||||
GlyphTexture::GlyphTexture():
|
||||
_margin(1),
|
||||
_marginRatio(0.02f),
|
||||
_usedY(0),
|
||||
@@ -465,12 +502,12 @@ Font::GlyphTexture::GlyphTexture():
|
||||
setWrap(WRAP_T, CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
Font::GlyphTexture::~GlyphTexture()
|
||||
GlyphTexture::~GlyphTexture()
|
||||
{
|
||||
}
|
||||
|
||||
// return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.
|
||||
int Font::GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
||||
int GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
||||
{
|
||||
if (this<&rhs) return -1;
|
||||
else if (this>&rhs) return 1;
|
||||
@@ -478,7 +515,7 @@ int Font::GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
||||
}
|
||||
|
||||
|
||||
bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
{
|
||||
int maxAxis = std::max(glyph->s(), glyph->t());
|
||||
int margin = _margin + (int)((float)maxAxis * _marginRatio);
|
||||
@@ -525,7 +562,7 @@ bool Font::GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Font::GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
|
||||
void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
@@ -545,7 +582,7 @@ void Font::GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
|
||||
static_cast<float>(posY+glyph->t())/static_cast<float>(getTextureHeight()) ) );
|
||||
}
|
||||
|
||||
void Font::GlyphTexture::apply(osg::State& state) const
|
||||
void GlyphTexture::apply(osg::State& state) const
|
||||
{
|
||||
// get the contextID (user defined ID of 0 upwards) for the
|
||||
// current OpenGL context.
|
||||
@@ -797,12 +834,12 @@ void Font::GlyphTexture::apply(osg::State& state) const
|
||||
|
||||
}
|
||||
|
||||
void Font::GlyphTexture::setThreadSafeRefUnref(bool threadSafe)
|
||||
void GlyphTexture::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
osg::Texture2D::setThreadSafeRefUnref(threadSafe);
|
||||
}
|
||||
|
||||
void Font::GlyphTexture::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
void GlyphTexture::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
osg::Texture2D::resizeGLObjectBuffers(maxSize);
|
||||
_glyphsToSubload.resize(maxSize);
|
||||
@@ -810,7 +847,7 @@ void Font::GlyphTexture::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
|
||||
|
||||
// all the methods in Font::Glyph have been made non inline because VisualStudio6.0 is STUPID, STUPID, STUPID PILE OF JUNK.
|
||||
Font::Glyph::Glyph(unsigned int glyphCode):
|
||||
Glyph::Glyph(unsigned int glyphCode):
|
||||
_font(0),
|
||||
_glyphCode(glyphCode),
|
||||
_horizontalBearing(0.0f,0.f),
|
||||
@@ -826,53 +863,53 @@ Font::Glyph::Glyph(unsigned int glyphCode):
|
||||
setThreadSafeRefUnref(true);
|
||||
}
|
||||
|
||||
Font::Glyph::~Glyph()
|
||||
Glyph::~Glyph()
|
||||
{
|
||||
}
|
||||
|
||||
void Font::Glyph::setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
|
||||
const osg::Vec2& Font::Glyph::getHorizontalBearing() const { return _horizontalBearing; }
|
||||
void Glyph::setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
|
||||
const osg::Vec2& Glyph::getHorizontalBearing() const { return _horizontalBearing; }
|
||||
|
||||
void Font::Glyph::setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
|
||||
float Font::Glyph::getHorizontalAdvance() const { return _horizontalAdvance; }
|
||||
void Glyph::setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
|
||||
float Glyph::getHorizontalAdvance() const { return _horizontalAdvance; }
|
||||
|
||||
void Font::Glyph::setVerticalBearing(const osg::Vec2& bearing) { _verticalBearing=bearing; }
|
||||
const osg::Vec2& Font::Glyph::getVerticalBearing() const { return _verticalBearing; }
|
||||
void Glyph::setVerticalBearing(const osg::Vec2& bearing) { _verticalBearing=bearing; }
|
||||
const osg::Vec2& Glyph::getVerticalBearing() const { return _verticalBearing; }
|
||||
|
||||
void Font::Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; }
|
||||
float Font::Glyph::getVerticalAdvance() const { return _verticalAdvance; }
|
||||
void Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; }
|
||||
float Glyph::getVerticalAdvance() const { return _verticalAdvance; }
|
||||
|
||||
void Font::Glyph::setTexture(GlyphTexture* texture) { _texture = texture; }
|
||||
Font::GlyphTexture* Font::Glyph::getTexture() { return _texture; }
|
||||
const Font::GlyphTexture* Font::Glyph::getTexture() const { return _texture; }
|
||||
void Glyph::setTexture(GlyphTexture* texture) { _texture = texture; }
|
||||
GlyphTexture* Glyph::getTexture() { return _texture; }
|
||||
const GlyphTexture* Glyph::getTexture() const { return _texture; }
|
||||
|
||||
void Font::Glyph::setTexturePosition(int posX,int posY) { _texturePosX = posX; _texturePosY = posY; }
|
||||
int Font::Glyph::getTexturePositionX() const { return _texturePosX; }
|
||||
int Font::Glyph::getTexturePositionY() const { return _texturePosY; }
|
||||
void Glyph::setTexturePosition(int posX,int posY) { _texturePosX = posX; _texturePosY = posY; }
|
||||
int Glyph::getTexturePositionX() const { return _texturePosX; }
|
||||
int Glyph::getTexturePositionY() const { return _texturePosY; }
|
||||
|
||||
void Font::Glyph::setMinTexCoord(const osg::Vec2& coord) { _minTexCoord=coord; }
|
||||
const osg::Vec2& Font::Glyph::getMinTexCoord() const { return _minTexCoord; }
|
||||
void Glyph::setMinTexCoord(const osg::Vec2& coord) { _minTexCoord=coord; }
|
||||
const osg::Vec2& Glyph::getMinTexCoord() const { return _minTexCoord; }
|
||||
|
||||
void Font::Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; }
|
||||
const osg::Vec2& Font::Glyph::getMaxTexCoord() const { return _maxTexCoord; }
|
||||
void Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; }
|
||||
const osg::Vec2& Glyph::getMaxTexCoord() const { return _maxTexCoord; }
|
||||
|
||||
void Font::Glyph::subload() const
|
||||
void Glyph::subload() const
|
||||
{
|
||||
GLenum errorNo = glGetError();
|
||||
if (errorNo!=GL_NO_ERROR)
|
||||
{
|
||||
#ifdef OSG_GLU_AVAILABLE
|
||||
const GLubyte* msg = gluErrorString(errorNo);
|
||||
if (msg) { OSG_WARN<<"before Font::Glyph::subload(): detected OpenGL error: "<<msg<<std::endl; }
|
||||
else { OSG_WARN<<"before Font::Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl; }
|
||||
if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<<msg<<std::endl; }
|
||||
else { OSG_WARN<<"before Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl; }
|
||||
#else
|
||||
OSG_WARN<<"before Font::Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl;
|
||||
OSG_WARN<<"before Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(s() <= 0 || t() <= 0)
|
||||
{
|
||||
OSG_INFO<<"Font::Glyph::subload(): texture sub-image width and/or height of 0, ignoring operation."<<std::endl;
|
||||
OSG_INFO<<"Glyph::subload(): texture sub-image width and/or height of 0, ignoring operation."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -892,10 +929,10 @@ void Font::Glyph::subload() const
|
||||
|
||||
#ifdef OSG_GLU_AVAILABLE
|
||||
const GLubyte* msg = gluErrorString(errorNo);
|
||||
if (msg) { OSG_WARN<<"after Font::Glyph::subload() : detected OpenGL error: "<<msg<<std::endl; }
|
||||
else { OSG_WARN<<"after Font::Glyph::subload() : detected OpenGL error number: "<<errorNo<<std::endl; }
|
||||
if (msg) { OSG_WARN<<"after Glyph::subload() : detected OpenGL error: "<<msg<<std::endl; }
|
||||
else { OSG_WARN<<"after Glyph::subload() : detected OpenGL error number: "<<errorNo<<std::endl; }
|
||||
#else
|
||||
OSG_WARN<<"after Font::Glyph::subload() : detected OpenGL error number: "<<errorNo<<std::endl;
|
||||
OSG_WARN<<"after Glyph::subload() : detected OpenGL error number: "<<errorNo<<std::endl;
|
||||
#endif
|
||||
|
||||
OSG_WARN<< "\tglTexSubImage2D(0x"<<hex<<GL_TEXTURE_2D<<dec<<" ,"<<0<<"\t"<<std::endl<<
|
||||
|
||||
@@ -277,7 +277,7 @@ std::string Font3D::getFileName() const
|
||||
return "";
|
||||
}
|
||||
|
||||
Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode)
|
||||
Glyph3D* Font3D::getGlyph(unsigned int charcode)
|
||||
{
|
||||
Glyph3D * glyph3D = NULL;
|
||||
|
||||
@@ -312,7 +312,7 @@ bool Font3D::hasVertical() const
|
||||
else return false;
|
||||
}
|
||||
|
||||
void Font3D::Glyph3D::setThreadSafeRefUnref(bool threadSafe)
|
||||
void Glyph3D::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
if (_vertexArray.valid()) _vertexArray->setThreadSafeRefUnref(threadSafe);
|
||||
if (_normalArray.valid()) _normalArray->setThreadSafeRefUnref(threadSafe);
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include "DefaultFont.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgText;
|
||||
|
||||
@@ -71,8 +69,8 @@ void Text::setFont(osg::ref_ptr<Font> font)
|
||||
{
|
||||
if (_font==font) return;
|
||||
|
||||
osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : DefaultFont::instance()->getStateSet();
|
||||
osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : DefaultFont::instance()->getStateSet();
|
||||
osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet();
|
||||
osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet();
|
||||
|
||||
if (getStateSet() == previousFontStateSet)
|
||||
{
|
||||
@@ -98,12 +96,12 @@ void Text::setColor(const osg::Vec4& color)
|
||||
|
||||
Font* Text::getActiveFont()
|
||||
{
|
||||
return _font.valid() ? _font.get() : DefaultFont::instance();
|
||||
return _font.valid() ? _font.get() : Font::getDefaultFont().get();
|
||||
}
|
||||
|
||||
const Font* Text::getActiveFont() const
|
||||
{
|
||||
return _font.valid() ? _font.get() : DefaultFont::instance();
|
||||
return _font.valid() ? _font.get() : Font::getDefaultFont().get();
|
||||
}
|
||||
|
||||
String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator first,String::iterator last)
|
||||
@@ -128,7 +126,7 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite
|
||||
return lastChar;
|
||||
}
|
||||
|
||||
Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
|
||||
Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
|
||||
if (glyph)
|
||||
{
|
||||
|
||||
@@ -223,7 +221,7 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite
|
||||
// Subtract off glyphs from the cursor position (to correctly center text)
|
||||
if(*prevChar != '-')
|
||||
{
|
||||
Font::Glyph* glyph = activefont->getGlyph(_fontSize, *prevChar);
|
||||
Glyph* glyph = activefont->getGlyph(_fontSize, *prevChar);
|
||||
if (glyph)
|
||||
{
|
||||
switch(_layout)
|
||||
@@ -397,7 +395,7 @@ void Text::computeGlyphRepresentation()
|
||||
{
|
||||
unsigned int charcode = *itr;
|
||||
|
||||
Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
|
||||
Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
|
||||
if (glyph)
|
||||
{
|
||||
float width = (float)(glyph->s()) * wr;
|
||||
|
||||
@@ -135,7 +135,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
return lastChar;
|
||||
}
|
||||
|
||||
Font3D::Glyph3D* glyph = _font->getGlyph(charcode);
|
||||
Glyph3D* glyph = _font->getGlyph(charcode);
|
||||
if (glyph)
|
||||
{
|
||||
const osg::BoundingBox & bb = glyph->getBoundingBox();
|
||||
@@ -245,7 +245,7 @@ String::iterator Text3D::computeLastCharacterOnLine(osg::Vec2& cursor, String::i
|
||||
// Subtract off glyphs from the cursor position (to correctly center text)
|
||||
if(*prevChar != '-')
|
||||
{
|
||||
Font3D::Glyph3D* glyph = _font->getGlyph(*prevChar);
|
||||
Glyph3D* glyph = _font->getGlyph(*prevChar);
|
||||
if (glyph)
|
||||
{
|
||||
switch(_layout)
|
||||
@@ -316,7 +316,7 @@ void Text3D::computeGlyphRepresentation()
|
||||
{
|
||||
unsigned int charcode = *itr;
|
||||
|
||||
Font3D::Glyph3D* glyph = _font->getGlyph(charcode);
|
||||
Glyph3D* glyph = _font->getGlyph(charcode);
|
||||
if (glyph)
|
||||
{
|
||||
const osg::BoundingBox & bb = glyph->getBoundingBox();
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
|
||||
#include <osgText/TextBase>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <osg/Math>
|
||||
#include <osg/GL>
|
||||
@@ -24,8 +25,6 @@
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include "DefaultFont.h"
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgText;
|
||||
|
||||
@@ -49,7 +48,7 @@ TextBase::TextBase():
|
||||
_kerningType(KERNING_DEFAULT),
|
||||
_lineCount(0)
|
||||
{
|
||||
setStateSet(DefaultFont::instance()->getStateSet());
|
||||
setStateSet(Font::getDefaultFont()->getStateSet());
|
||||
setUseDisplayList(false);
|
||||
setSupportsDisplayList(false);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ void Input::_calculateCursorOffsets() {
|
||||
osgText::Text::TextureGlyphQuadMap::iterator tgqmi = tgqm.begin();
|
||||
|
||||
std::vector<osg::Vec2> coords;
|
||||
std::vector<osgText::Font::Glyph*> glyphs;
|
||||
std::vector<osgText::Glyph*> glyphs;
|
||||
for ( ; tgqmi != tgqm.end(); tgqmi++ )
|
||||
{
|
||||
const osgText::Text::GlyphQuads& gq = tgqmi->second;
|
||||
@@ -140,9 +140,9 @@ void Input::_calculateCursorOffsets() {
|
||||
unsigned int key = keys.front();
|
||||
for (unsigned int i=0; i<glyphs.size(); ++i)
|
||||
{
|
||||
static osgText::Font::Glyph* previous_g = 0;
|
||||
static osgText::Glyph* previous_g = 0;
|
||||
|
||||
osgText::Font::Glyph* g = glyphs.at(i);
|
||||
osgText::Glyph* g = glyphs.at(i);
|
||||
if (g->getGlyphCode()==key)
|
||||
{
|
||||
lr = coords[2 + (i * 4)];
|
||||
@@ -653,7 +653,7 @@ unsigned int Input::calculateBestYOffset(const std::string& s)
|
||||
|
||||
for(osgText::String::iterator i = utf.begin(); i != utf.end(); i++) {
|
||||
osgText::Font* font = const_cast<osgText::Font*>(_text->getFont());
|
||||
osgText::Font::Glyph* glyph = font->getGlyph(fr, *i);
|
||||
osgText::Glyph* glyph = font->getGlyph(fr, *i);
|
||||
unsigned int d = abs((int)glyph->getHorizontalBearing().y());
|
||||
|
||||
if(d > descent) descent = d;
|
||||
|
||||
Reference in New Issue
Block a user