BOX2D STROKE_FONT::computeBoundingBox( const GLYPH& aGLYPH, const VECTOR2D& aGLYPHBoundingX ) const { BOX2D boundingBox; std::deque<VECTOR2D> boundingPoints; boundingPoints.push_back( VECTOR2D( aGLYPHBoundingX.x, 0 ) ); boundingPoints.push_back( VECTOR2D( aGLYPHBoundingX.y, 0 ) ); for( GLYPH::const_iterator pointListIt = aGLYPH.begin(); pointListIt != aGLYPH.end(); ++pointListIt ) { for( std::deque<VECTOR2D>::const_iterator pointIt = pointListIt->begin(); pointIt != pointListIt->end(); ++pointIt ) { boundingPoints.push_back( VECTOR2D( aGLYPHBoundingX.x, pointIt->y ) ); } } boundingBox.Compute( boundingPoints ); return boundingBox; }
bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize ) { m_glyphs.clear(); m_glyphBoundingBoxes.clear(); m_glyphs.resize( aNewStrokeFontSize ); m_glyphBoundingBoxes.resize( aNewStrokeFontSize ); for( int j = 0; j < aNewStrokeFontSize; j++ ) { GLYPH glyph; double glyphStartX = 0.0; double glyphEndX = 0.0; VECTOR2D glyphBoundingX; std::deque<VECTOR2D> pointList; int i = 0; while( aNewStrokeFont[j][i] ) { VECTOR2D point( 0.0, 0.0 ); char coordinate[2] = { 0, }; for( int k = 0; k < 2; k++ ) { coordinate[k] = aNewStrokeFont[j][i + k]; } if( i < 2 ) { // The first two values contain the width of the char glyphStartX = ( coordinate[0] - 'R' ) * STROKE_FONT_SCALE; glyphEndX = ( coordinate[1] - 'R' ) * STROKE_FONT_SCALE; glyphBoundingX = VECTOR2D( 0, glyphEndX - glyphStartX ); } else if( ( coordinate[0] == ' ' ) && ( coordinate[1] == 'R' ) ) { // Raise pen if( pointList.size() > 0 ) glyph.push_back( pointList ); pointList.clear(); } else { // In stroke font, coordinates values are coded as <value> + 'R', // <value> is an ASCII char. // therefore every coordinate description of the Hershey format has an offset, // it has to be subtracted // Note: // * the stroke coordinates are stored in reduced form (-1.0 to +1.0), // and the actual size is stroke coordinate * glyph size // * a few shapes have a height slightly bigger than 1.0 ( like '{' '[' ) point.x = (double) ( coordinate[0] - 'R' ) * STROKE_FONT_SCALE - glyphStartX; #define FONT_OFFSET -10 // FONT_OFFSET is here for historical reasons, due to the way the stroke font // was built. It allows shapes coordinates like W M ... to be >= 0 // Only shapes like j y have coordinates < 0 point.y = (double) ( coordinate[1] - 'R' + FONT_OFFSET ) * STROKE_FONT_SCALE; pointList.push_back( point ); } i += 2; } if( pointList.size() > 0 ) glyph.push_back( pointList ); m_glyphs[j] = glyph; // Compute the bounding box of the glyph m_glyphBoundingBoxes[j] = computeBoundingBox( glyph, glyphBoundingX ); } return true; }
bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNewStrokeFontSize ) { m_glyphs.clear(); m_glyphBoundingBoxes.clear(); m_glyphs.resize( aNewStrokeFontSize ); m_glyphBoundingBoxes.resize( aNewStrokeFontSize ); for( int j = 0; j < aNewStrokeFontSize; j++ ) { GLYPH glyph; double glyphStartX = 0.0; double glyphEndX = 0.0; VECTOR2D glyphBoundingX; std::deque<VECTOR2D> pointList; int i = 0; while( aNewStrokeFont[j][i] ) { VECTOR2D point( 0.0, 0.0 ); char coordinate[2] = { 0, }; for( int k = 0; k < 2; k++ ) { coordinate[k] = aNewStrokeFont[j][i + k]; } if( i < 2 ) { // The first two values contain the width of the char glyphStartX = ( coordinate[0] - 'R' ) * HERSHEY_SCALE; glyphEndX = ( coordinate[1] - 'R' ) * HERSHEY_SCALE; glyphBoundingX = VECTOR2D( 0, glyphEndX - glyphStartX ); } else if( ( coordinate[0] == ' ' ) && ( coordinate[1] == 'R' ) ) { // Raise pen if( pointList.size() > 0 ) glyph.push_back( pointList ); pointList.clear(); } else { // Every coordinate description of the Hershey format has an offset, // it has to be subtracted point.x = (double) ( coordinate[0] - 'R' ) * HERSHEY_SCALE - glyphStartX; point.y = (double) ( coordinate[1] - 'R' ) * HERSHEY_SCALE; pointList.push_back( point ); } i += 2; } if( pointList.size() > 0 ) glyph.push_back( pointList ); m_glyphs[j] = glyph; // Compute the bounding box of the glyph m_glyphBoundingBoxes[j] = computeBoundingBox( glyph, glyphBoundingX ); } return true; }