FTOutlineGlyph::FTOutlineGlyph( FT_GlyphSlot glyph) : FTGlyph( glyph), glList(0) { if( ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } FTVectoriser vectoriser( glyph); size_t numContours = vectoriser.ContourCount(); if ( ( numContours < 1) || ( vectoriser.PointCount() < 3)) { return; } glList = glGenLists(1); glNewList( glList, GL_COMPILE); for( unsigned int c = 0; c < numContours; ++c) { const FTContour* contour = vectoriser.Contour(c); glBegin( GL_LINE_LOOP); for( unsigned int p = 0; p < contour->PointCount(); ++p) { glVertex2f( contour->Point(p).x / 64.0f, contour->Point(p).y / 64.0f); } glEnd(); } glEndList(); }
void testMakeMesh() { setUpFreetype(COMPLEX_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); vectoriser.MakeMesh(FTGL_FRONT_FACING); int d = 0; const FTMesh* mesh = vectoriser.GetMesh(); unsigned int tesselations = mesh->TesselationCount(); CPPUNIT_ASSERT_EQUAL(14U, tesselations); for(unsigned int index = 0; index < tesselations; ++index) { const FTTesselation* subMesh = mesh->Tesselation(index); unsigned int polyType = subMesh->PolygonType(); CPPUNIT_ASSERT_EQUAL(testMeshPolygonTypes[index], polyType); unsigned int numberOfVertices = subMesh->PointCount(); CPPUNIT_ASSERT_EQUAL(testMeshPointCount[index], numberOfVertices); for(unsigned int x = 0; x < numberOfVertices; ++x) { CPPUNIT_ASSERT_DOUBLES_EQUAL(*(testMesh + d), subMesh->Point(x).X() / 64, 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL(*(testMesh + d + 1), subMesh->Point(x).Y() / 64, 0.01); d += 3; } } tearDownFreetype(); }
void testBadGlyphProcess() { setUpFreetype(NULL_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); CPPUNIT_ASSERT_EQUAL((size_t)0, vectoriser.ContourCount()); tearDownFreetype(); }
FTPolyGlyph::FTPolyGlyph( FT_GlyphSlot glyph, bool useDisplayList) : FTGlyph( glyph), glList(0) { if( ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } FTVectoriser vectoriser( glyph); if(( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3)) { return; } unsigned int horizontalTextureScale = glyph->face->size->metrics.x_ppem * 64; unsigned int verticalTextureScale = glyph->face->size->metrics.y_ppem * 64; vectoriser.MakeMesh( 1.0); if( useDisplayList) { glList = glGenLists( 1); glNewList( glList, GL_COMPILE); } const FTMesh* mesh = vectoriser.GetMesh(); for( unsigned int index = 0; index < mesh->TesselationCount(); ++index) { const FTTesselation* subMesh = mesh->Tesselation( index); unsigned int polyonType = subMesh->PolygonType(); glBegin( polyonType); for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex) { FTPoint point = subMesh->Point(pointIndex); glTexCoord2f( point.X() / horizontalTextureScale, point.Y() / verticalTextureScale); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f); } glEnd(); } if(useDisplayList) { glEndList(); } }
void testGetMesh() { setUpFreetype(SIMPLE_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); CPPUNIT_ASSERT(vectoriser.GetMesh() == NULL); vectoriser.MakeMesh(FTGL_FRONT_FACING); CPPUNIT_ASSERT(vectoriser.GetMesh()); }
void testGetContour() { setUpFreetype(SIMPLE_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); CPPUNIT_ASSERT(vectoriser.Contour(1)); CPPUNIT_ASSERT(vectoriser.Contour(99) == NULL); tearDownFreetype(); }
void testComplexGlyphProcess() { setUpFreetype(COMPLEX_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); CPPUNIT_ASSERT_EQUAL((size_t)2, vectoriser.ContourCount()); CPPUNIT_ASSERT_EQUAL((size_t)91, vectoriser.PointCount()); tearDownFreetype(); }
FTOutlineGlyph::FTOutlineGlyph( FT_GlyphSlot glyph, bool useDisplayList) : FTGlyph( glyph), glList(0) { if( ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } FTVectoriser vectoriser( glyph); size_t numContours = vectoriser.ContourCount(); if ( ( numContours < 1) || ( vectoriser.PointCount() < 3)) { return; } if(useDisplayList) { // Check if we are out of display lists if (glList == 0) { useDisplayList = false; } else glNewList( glList, GL_COMPILE); } for( unsigned int c = 0; c < numContours; ++c) { const FTContour* contour = vectoriser.Contour(c); glBegin( GL_LINE_LOOP); for( unsigned int pointIndex = 0; pointIndex < contour->PointCount(); ++pointIndex) { FTPoint point = contour->Point(pointIndex); glVertex2f( point.X() / 64.0f, point.Y() / 64.0f); } glEnd(); } if(useDisplayList) { glEndList(); } }
void testGetOutline() { setUpFreetype(COMPLEX_CHARACTER_INDEX); FTVectoriser vectoriser(face->glyph); unsigned int d = 0; for(size_t c = 0; c < vectoriser.ContourCount(); ++c) { const FTContour* contour = vectoriser.Contour(c); for(size_t p = 0; p < contour->PointCount(); ++p) { CPPUNIT_ASSERT_DOUBLES_EQUAL(*(testOutline + d), contour->Point(p).X() / 64.0f, 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL(*(testOutline + d + 1), contour->Point(p).Y() / 64.0f, 0.01); d += 3; } } tearDownFreetype(); }
FTExtrdGlyph::FTExtrdGlyph( FT_GlyphSlot glyph, float depth, bool useDisplayList) : FTGlyph( glyph), glList(0) { bBox.SetDepth( -depth); if( ft_glyph_format_outline != glyph->format) { err = 0x14; // Invalid_Outline return; } FTVectoriser vectoriser( glyph); if( ( vectoriser.ContourCount() < 1) || ( vectoriser.PointCount() < 3)) { return; } unsigned int tesselationIndex; if(useDisplayList) { glList = glGenLists(1); glNewList( glList, GL_COMPILE); } vectoriser.MakeMesh( 1.0); glNormal3d(0.0, 0.0, 1.0); unsigned int horizontalTextureScale = glyph->face->size->metrics.x_ppem * 64; unsigned int verticalTextureScale = glyph->face->size->metrics.y_ppem * 64; const FTMesh* mesh = vectoriser.GetMesh(); for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex) { const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex); unsigned int polyonType = subMesh->PolygonType(); glBegin( polyonType); for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex) { FTPoint point = subMesh->Point(pointIndex); glTexCoord2f( point.X() / horizontalTextureScale, point.Y() / verticalTextureScale); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f); } glEnd(); } vectoriser.MakeMesh( -1.0); glNormal3d(0.0, 0.0, -1.0); mesh = vectoriser.GetMesh(); for( tesselationIndex = 0; tesselationIndex < mesh->TesselationCount(); ++tesselationIndex) { const FTTesselation* subMesh = mesh->Tesselation( tesselationIndex); unsigned int polyonType = subMesh->PolygonType(); glBegin( polyonType); for( unsigned int pointIndex = 0; pointIndex < subMesh->PointCount(); ++pointIndex) { FTPoint point = subMesh->Point(pointIndex); glTexCoord2f( subMesh->Point(pointIndex).X() / horizontalTextureScale, subMesh->Point(pointIndex).Y() / verticalTextureScale); glVertex3f( subMesh->Point( pointIndex).X() / 64.0f, subMesh->Point( pointIndex).Y() / 64.0f, -depth); } glEnd(); } int contourFlag = vectoriser.ContourFlag(); for( size_t c = 0; c < vectoriser.ContourCount(); ++c) { const FTContour* contour = vectoriser.Contour(c); unsigned int numberOfPoints = contour->PointCount(); glBegin( GL_QUAD_STRIP); for( unsigned int j = 0; j <= numberOfPoints; ++j) { unsigned int pointIndex = ( j == numberOfPoints) ? 0 : j; unsigned int nextPointIndex = ( pointIndex == numberOfPoints - 1) ? 0 : pointIndex + 1; FTPoint point = contour->Point(pointIndex); FTPoint normal = GetNormal( point, contour->Point(nextPointIndex)); if(normal != FTPoint( 0.0f, 0.0f, 0.0f)) { glNormal3dv(static_cast<const FTGL_DOUBLE*>(normal)); } if( contourFlag & ft_outline_reverse_fill) { glTexCoord2f( point.X() / horizontalTextureScale, point.X() / verticalTextureScale); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, -depth); } else { glTexCoord2f( point.X() / horizontalTextureScale, point.Y() / verticalTextureScale); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, -depth); glVertex3f( point.X() / 64.0f, point.Y() / 64.0f, 0.0f); } } glEnd(); } if(useDisplayList) { glEndList(); } }
void testNullGlyphProcess() { FTVectoriser vectoriser(NULL); CPPUNIT_ASSERT_EQUAL((size_t)0, vectoriser.ContourCount()); }