Show
Ignore:
Timestamp:
03/10/09 11:56:00 (6 years ago)
Author:
robert
Message:

From David Callu, "Problem:

osgText::Text and osgText::Text3D use the same font file.
The first really load the file and obtain an osgText::Font object,
the second use the cache created during the first load of the
font file, and so obtain an osgText::Font object instead of
osgText::Font3D object. To obtain an osgText::Font3D object,
osgText::Text3D call osgDB::readObjectFile(...) with an option
to specify the plugin we want an osgText::Font3D instead of
osgText::Font.

Generalised Problem:

In osgDB::Registry, loaded file cache is referenced by the name
of this file, so if I load a file with some options, and the cache
already contain object for this filename, I obtain an object
potentially not loaded with my options.

Behaviours:

Cache management is delegate to osgDB::Registry, but cache
coherence (load a file with option then reuse it, deactivate the
cache when load a specific file or don't cached the loaded file)
is user's responsibility.

Text3D solution:

Postfix the font file name by .text3d or something similar and then have the freetype plugin return
osgText::Font3D when it detects this.
This operation is done by osgText::readFont3DFile() which unsure the filename have .text3d as extension.
This is totaly transparent for user, and backward compatible.

BTW, I fix the bug about the Normal of 3D text. Currently, the front and wall face have
the same normal (0,0,1) in the Text3D object coordinate. Now the wall face have its own
normal array computed by the plugin.

BTW 2, I implement
- void Text3D::accept(osg::Drawable::ConstAttributeFunctor?& af) const
- void Text3D::accept(osg::PrimitiveFunctor?& pf) const
so now statistics are well reported.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeFont3D.cpp

    r7696 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    2121 
    2222#include <osg/Geometry> 
    23 #include <osg/Notify>   
     23#include <osg/Notify> 
    2424#include <osgDB/WriteFile> 
    2525#include <osgUtil/SmoothingVisitor> 
     
    2727 
    2828 
    29 #include <ft2build.h>   
     29#include <ft2build.h> 
    3030#include FT_FREETYPE_H 
    3131 
     
    174174{ 
    175175    Char3DInfo* char3d = (Char3DInfo*)user; 
    176     char3d->cubicTo(  
     176    char3d->cubicTo( 
    177177        osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)), 
    178178        osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)), 
     
    221221    } 
    222222 
    223     FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);  
     223    FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600); 
    224224 
    225225    int glyphIndex = FT_Get_Char_Index( _face, 'M' ); 
     
    291291            // not dangling pointers remain 
    292292            freeTypeLibrary->removeFont3DImplmentation(this); 
    293          
     293 
    294294            // free the freetype font face itself 
    295295            FT_Done_Face(_face); 
     
    309309osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode) 
    310310{ 
    311      
    312      
     311 
     312 
    313313    // 
    314     // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being   
    315     // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct  
    316     // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.   
     314    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being 
     315    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct 
     316    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect. 
    317317    // Microsoft uses a private field for its symbol fonts 
    318318    // 
     
    337337        return 0; 
    338338    } 
    339      
     339 
    340340    // ** init FreeType to describe the glyph 
    341341    Char3DInfo char3d; 
     
    349349    funcs.shift = 0; 
    350350    funcs.delta = 0; 
    351      
     351 
    352352    // ** record description 
    353353    FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d); 
     
    357357        return 0; 
    358358    } 
    359      
     359 
    360360    // ** create geometry for each part of the glyph 
    361361    osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry); 
    362362    frontGeo->setVertexArray(char3d.get()->getVertexArray()); 
    363363    frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList()); 
    364      
     364 
    365365    osg::ref_ptr<osg::Geometry> wallGeo(new osg::Geometry); 
    366366    wallGeo->setVertexArray(frontGeo->getVertexArray()); 
    367      
     367 
    368368    osg::ref_ptr<osg::Geometry> backGeo(new osg::Geometry); 
    369369    backGeo->setVertexArray(frontGeo->getVertexArray()); 
    370          
    371      
    372      
    373     // ** for conveniance. 
     370 
     371 
     372 
     373    // ** for convenience. 
    374374    osg::Vec3Array * vertices = char3d._verts.get(); 
    375      
    376      
    377      
    378     // ** duplicate the vertex for the back face  
     375 
     376 
     377 
     378    // ** duplicate the vertex for the back face 
    379379    // ** with a depth equal to the font depth 
    380380    std::size_t len = vertices->size(); 
    381381    std::size_t dlen = len * 2; 
    382        
     382 
    383383    vertices->reserve(dlen); 
    384         
     384 
    385385    osg::Vec3Array::iterator begin = vertices->begin(); 
    386386    osg::Vec3Array::iterator it = vertices->begin(); 
    387      
     387 
    388388    for (std::size_t i = 0; i != len; ++i, ++it) 
    389389        vertices->push_back(*it); 
    390390//    std::copy(begin, begin + len, begin + len + 1); TOCHECK 
    391      
    392   
     391 
     392 
    393393    // ** and decal new vertices 
    394394    unsigned int depth = _facade->getFontDepth(); 
     
    397397        (*vertices)[i].z() -= depth; 
    398398    } 
    399      
     399 
    400400    osg::Vec3Array::iterator end; 
    401      
     401 
    402402    // ** create wall and back face from the front polygon 
    403     // **  then accumulate them in the apropriate geometry wallGeo and backGeo  
     403    // **  then accumulate them in the appropriate geometry wallGeo and backGeo 
    404404    for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i) 
    405405    { 
     
    408408        unsigned int idx = daFront->getFirst(); 
    409409        unsigned int cnt = daFront->getCount(); 
    410          
     410 
    411411        // ** reverse vertices to draw the front face in the CCW 
    412412        std::reverse(begin + idx, begin + idx + cnt); 
    413          
     413 
    414414        // ** create the back polygon 
    415415        osg::ref_ptr<osg::DrawArrays> daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt)); 
    416416        backGeo->addPrimitiveSet(daBack.get()); 
    417          
    418          
     417 
     418 
    419419        // ** create the wall triangle strip 
    420         osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));  
     420        osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP)); 
    421421        wallGeo->addPrimitiveSet(deWall.get()); 
    422          
     422 
    423423        // **  link triangle strip 
    424424        deWall->push_back(idx + len); 
    425425        for (unsigned int j = 1; j < cnt; ++j) 
    426         {    
     426        { 
    427427            deWall->push_back(idx + cnt - j); 
    428428            deWall->push_back(idx + len + j); 
     
    440440        ts.retessellatePolygons(*frontGeo); 
    441441    } 
    442      
     442 
    443443    { 
    444444        osgUtil::Tessellator ts; 
     
    455455        geode->accept(sm); 
    456456    } 
    457      
    458     // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list  
     457 
     458    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list 
    459459    osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode); 
    460460 
    461461    glyph3D->setVertexArray(dynamic_cast<osg::Vec3Array*>(frontGeo->getVertexArray())); 
    462      
     462    glyph3D->setNormalArray(dynamic_cast<osg::Vec3Array*>(wallGeo->getNormalArray())); 
     463 
    463464    glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList(); 
    464465    glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList(); 
    465466    glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList(); 
    466467 
    467      
     468 
    468469    FT_Glyph_Metrics* metrics = &(_face->glyph->metrics); 
    469470 
     
    476477    glyph3D->setHeight((float)metrics->height / 64.0f); 
    477478 
    478      
     479 
    479480    FT_BBox ftbb; 
    480481    FT_Outline_Get_BBox(&outline, &ftbb); 
     
    484485    long ymin = ft_floor( ftbb.yMin ); 
    485486    long ymax = ft_ceiling( ftbb.yMax ); 
    486          
     487 
    487488    osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f); 
    488      
     489 
    489490    glyph3D->setBoundingBox(bb); 
    490      
     491 
    491492    return glyph3D; 
    492493} 
     
    501502    FT_UInt left = FT_Get_Char_Index( _face, leftcharcode ); 
    502503    FT_UInt right = FT_Get_Char_Index( _face, rightcharcode ); 
    503      
    504     // get the kerning distances.    
     504 
     505    // get the kerning distances. 
    505506    FT_Vector  kerning; 
    506507 
     
    525526} 
    526527 
    527 float FreeTypeFont3D::getScale() const  
    528 {  
    529     return _scale;  
    530 } 
     528float FreeTypeFont3D::getScale() const 
     529{ 
     530    return _scale; 
     531}