⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freetypefont3d.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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.*/#include "FreeTypeFont3D.h"#include "FreeTypeLibrary.h"#include <limits.h>#include <fstream>#include <osg/Geometry>#include <osg/Notify>  #include <osgDB/WriteFile>#include <osgUtil/SmoothingVisitor>#include <osgUtil/Tessellator>#include <ft2build.h>  #include FT_FREETYPE_H#include <freetype/ftoutln.h>#include <freetype/ftbbox.h>namespace{struct Char3DInfo{    Char3DInfo(int numSteps=50):        _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 moveTo(osg::Vec2 pos)    {        if (_verts->size())        {            int len = _verts->size()-_idx;            _geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::POLYGON, _idx, len ) );        }        _idx = _verts->size();        _verts->push_back( osg::Vec3(pos.x(),pos.y(),0) );        setMinMax(pos);    }    void lineTo(osg::Vec2 pos)    {        _verts->push_back( osg::Vec3(pos.x(),pos.y(),0) );        setMinMax(pos);    }    void conicTo(osg::Vec2 control, 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;            _verts->push_back( p );            u += dt;        }        setMinMax(pos);    }    void cubicTo(osg::Vec2 control1, osg::Vec2 control2, 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 );            _verts->push_back( p );            u += dt;        }        setMinMax(pos);    }    void setMinMax(osg::Vec2 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}FreeTypeFont3D::FreeTypeFont3D(const std::string& filename, FT_Face face, unsigned int flags):    _filename(filename),    _buffer(0),    _face(face),    _flags(flags),    _scale(1.0),    _shiftY(0.0),    _shiftX(0.0),    _charScale(1.0){    init();}FreeTypeFont3D::FreeTypeFont3D(FT_Byte* buffer, FT_Face face, unsigned int flags):    _filename(""),    _buffer(buffer),    _face(face),    _flags(flags),    _scale(1.0),    _shiftY(0.0),    _shiftX(0.0),    _charScale(1.0){    init();}void FreeTypeFont3D::init(){    FT_Error _error = FT_Set_Pixel_Sizes(_face, 32, 32);    if (_error)    {        osg::notify(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::notify(osg::NOTICE) << "FreeTypeFont3D: initial glyph load failed ..." << std::endl;        return;    }    if (_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)    {        osg::notify(osg::NOTICE) << "FreeTypeFont3D: not a vector font" << std::endl;        return;    }    {        Char3DInfo char3d;        FT_Outline outline = _face->glyph->outline;        FT_Outline_Funcs funcs;        funcs.conic_to = (FT_Outline_ConicToFunc)&conicTo;        funcs.line_to = (FT_Outline_LineToFunc)&lineTo;        funcs.cubic_to = (FT_Outline_CubicToFunc)&cubicTo;        funcs.move_to = (FT_Outline_MoveToFunc)&moveTo;        funcs.shift = 0;        funcs.delta = 0;        _error = FT_Outline_Decompose(&outline,&funcs,&char3d);        if (_error)        {            osg::notify(osg::NOTICE) << "FreeTypeFont3D: - outline decompose failed ..." << std::endl;            return;        }        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 width = (xmax - xmin)/64.0;        double height = (ymax - ymin)/64.0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -