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

📄 freetypefont.cpp

📁 最新osg包
💻 CPP
字号:
/* -*-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 "FreeTypeFont.h"#include "FreeTypeLibrary.h"#include <osg/Notify>  #include <osgDB/WriteFile>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){}FreeTypeFont::FreeTypeFont(FT_Byte* buffer, FT_Face face, unsigned int flags):    _currentRes(osgText::FontResolution(0,0)),    _filename(""),    _buffer(buffer),    _face(face),    _flags(flags){}FreeTypeFont::~FreeTypeFont(){    if(_face)    {        FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance();        if (freeTypeLibrary)        {            // remove myself from the local registry to ensure that            // not dangling pointers remain            freeTypeLibrary->removeFontImplmentation(this);                    // free the freetype font face itself            FT_Done_Face(_face);            _face = 0;            // release memory held for FT_Face to work            if (_buffer)            {                delete [] _buffer;                _buffer = 0;            }        }    }}void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize){    if (fontSize==_currentRes) return;    int width = fontSize.first;    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::notify(osg::WARN)<<"Warning: FreeTypeFont::setSize("<<width<<","<<height<<") sizes too large,"<<std::endl;            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;    }    FT_Error error = FT_Set_Pixel_Sizes( _face,      /* handle to face object  */                                         width,      /* pixel_width            */                                         height );   /* pixel_height            */    if (error)    {        osg::notify(osg::WARN)<<"FT_Set_Pixel_Sizes() - error 0x"<<std::hex<<error<<std::dec<<std::endl;    }    else    {        _currentRes = fontSize;    }}osgText::Font::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode){    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());    setFontResolution(fontRes);    //    // 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_RENDER|FT_LOAD_NO_BITMAP|_flags );    if (error)    {        osg::notify(osg::WARN) << "FT_Load_Char(...) error 0x"<<std::hex<<error<<std::dec<<std::endl;        return 0;    }    FT_GlyphSlot glyphslot = _face->glyph;    int pitch = glyphslot->bitmap.pitch;    unsigned char* buffer = glyphslot->bitmap.buffer;    unsigned int sourceWidth = glyphslot->bitmap.width;;    unsigned int sourceHeight = glyphslot->bitmap.rows;        unsigned int width = sourceWidth;    unsigned int height = sourceHeight;    osg::ref_ptr<osgText::Font::Glyph> glyph = new osgText::Font::Glyph;        unsigned int dataSize = width*height;    unsigned char* data = new unsigned char[dataSize];        // clear the image to zeros.    for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }    glyph->setImage(width,height,1,                    GL_ALPHA,                    GL_ALPHA,GL_UNSIGNED_BYTE,                    data,                    osg::Image::USE_NEW_DELETE,                    1);    glyph->setInternalTextureFormat(GL_ALPHA);    // copy image across to osgText::Glyph image.         switch(glyphslot->bitmap.pixel_mode)    {        case FT_PIXEL_MODE_MONO:            for(int r=sourceHeight-1;r>=0;--r)            {                unsigned char* ptr = buffer+r*pitch;                for(unsigned int c=0;c<sourceWidth;++c)                {                    (*data++)= (ptr[c >> 3] & (1 << (~c & 7))) ? 255 : 0;                }            }            break;                case FT_PIXEL_MODE_GRAY:            for(int r=sourceHeight-1;r>=0;--r)            {                unsigned char* ptr = buffer+r*pitch;                for(unsigned int c=0;c<sourceWidth;++c,++ptr)                {                    (*data++)=*ptr;                }            }            break;                    default:            osg::notify(osg::WARN) << "FT_Load_Char(...) returned bitmap with unknown pixel_mode " << glyphslot->bitmap.pixel_mode << std::endl;    }    FT_Glyph_Metrics* metrics = &(glyphslot->metrics);    glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX/64.0f,(float)(metrics->horiBearingY-metrics->height)/64.0f)); // bottom left.    glyph->setHorizontalAdvance((float)metrics->horiAdvance/64.0f);    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();}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());    if (!FT_HAS_KERNING(_face) || (kerningType == osgText::KERNING_NONE)) return osg::Vec2(0.0f,0.0f);    setFontResolution(fontRes);    FT_Kerning_Mode mode = (kerningType==osgText::KERNING_DEFAULT) ? ft_kerning_default : ft_kerning_unfitted;    // convert character code to glyph index    FT_UInt left = FT_Get_Char_Index( _face, leftcharcode );    FT_UInt right = FT_Get_Char_Index( _face, rightcharcode );        // get the kerning distances.       FT_Vector  kerning;    FT_Error error = FT_Get_Kerning( _face,                     // handle to face object                                     left,                      // left glyph index                                     right,                     // right glyph index                                     mode,                      // kerning mode                                     &kerning );                // target vector    if (error)    {        osg::notify(osg::WARN) << "FT_Get_Kerning(...) returned error code " <<std::hex<<error<<std::dec<< std::endl;        return osg::Vec2(0.0f,0.0f);    }    return osg::Vec2((float)kerning.x/64.0f,(float)kerning.y/64.0f);}bool FreeTypeFont::hasVertical() const{    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());    return FT_HAS_VERTICAL(_face)!=0;}

⌨️ 快捷键说明

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