| 481 | mutable std::vector<MeshPtr> m_meshes; |
| 482 | |
| 483 | const Mesh *cachedMesh( char c ) const |
| 484 | { |
| 485 | if( c < 0 ) |
| 486 | { |
| 487 | // Map all invalid characters to capital X |
| 488 | c = 'X'; |
| 489 | } |
| 490 | FreeTypeMutex::scoped_lock lock( g_freeTypeMutex ); |
| 491 | |
| 492 | // see if we have it cached |
| 493 | if( m_meshes[c] ) |
| 494 | { |
| 495 | return m_meshes[c].get(); |
| 496 | } |
| 497 | |
| 498 | // not in cache, so load it |
| 499 | FT_Load_Char( m_face, c, FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE ); |
| 500 | |
| 501 | // get the mesh |
| 502 | Mesher m( (FT_Pos)(m_curveTolerance * m_face->units_per_EM) ); |
| 503 | MeshPrimitivePtr primitive = m.mesh( &(m_face->glyph->outline) ); |
| 504 | |
| 505 | // transform it so an EM is 1 unit |
| 506 | M44f transform; transform.scale( V3f( 1.0f / m_face->units_per_EM ) ); |
| 507 | TransformOpPtr transformOp = new TransformOp; |
| 508 | transformOp->inputParameter()->setValue( primitive ); |
| 509 | transformOp->matrixParameter()->setValue( new M44fData( transform ) ); |
| 510 | transformOp->copyParameter()->setTypedValue( false ); |
| 511 | transformOp->operate(); |
| 512 | |
| 513 | // put it in the cache |
| 514 | MeshPtr mesh( new Mesh ); |
| 515 | mesh->primitive = primitive; |
| 516 | mesh->bound = primitive->bound(); |
| 517 | mesh->advance = V2f( m_face->glyph->advance.x, m_face->glyph->advance.y ) / m_face->units_per_EM; |
| 518 | m_meshes[c] = mesh; |
| 519 | |
| 520 | // return it |
| 521 | return mesh.get(); |
| 522 | } |
| 523 | |
| 524 | typedef tbb::spin_mutex FreeTypeMutex; |
| 525 | static FreeTypeMutex g_freeTypeMutex; |
nothing calls this directly
no test coverage detected