Ejemplo n.º 1
0
void FreeTypeFont::init()
{
    FT_Error _error;
#if 0
    _error = FT_Set_Pixel_Sizes(_face, 32, 32);
    if (_error)
    {
        OSG_NOTICE << "FreeTypeFont3D: set pixel sizes failed ..." << std::endl;
        return;
    }
#endif
    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;
        _freetype_scale = 1.0f/height;
    }
}
Ejemplo n.º 2
0
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;
    }

    float coord_scale = _freetype_scale/64.0f;

    // ** init FreeType to describe the glyph
    FreeType::Char3DInfo char3d(_facade->getNumberCurveSamples());
    char3d._coord_scale = coord_scale;

    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)));
    }

    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
    osg::ref_ptr<osgText::Glyph3D> glyph3D = new osgText::Glyph3D(_facade, charcode);

    // copy the raw primitive set list before we tessellate it.
    glyph3D->getRawFacePrimitiveSetList() = rawPrimitives;
    glyph3D->setRawVertexArray(rawVertices.get());


    FT_Glyph_Metrics* metrics = &(_face->glyph->metrics);

    glyph3D->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX * coord_scale,(float)(metrics->horiBearingY-metrics->height) * coord_scale)); // bottom left.
    glyph3D->setHorizontalAdvance((float)metrics->horiAdvance * coord_scale);
    glyph3D->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX * coord_scale,(float)(metrics->vertBearingY-metrics->height) * coord_scale)); // top middle.
    glyph3D->setVerticalAdvance((float)metrics->vertAdvance * coord_scale);

    glyph3D->setWidth((float)metrics->width * coord_scale);
    glyph3D->setHeight((float)metrics->height * coord_scale);

    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 * coord_scale, ymin * coord_scale, 0.0f, xmax * coord_scale, ymax * coord_scale, 0.0f);

    glyph3D->setBoundingBox(bb);

    return glyph3D.release();
}