Sign in to follow this  
Gary_Higham

AngelCode BMPFont Parser

Recommended Posts

Hi all hope this is the correct place to post this, first post un' all. I am currently going through the tutorial on how to make use AngelCodes bitmap fonts in your games. I have created my parser and debugging the application it seems that the correct data is being read in and sent to the correct place, the problem comes on the next iteration of the render method. It never happens, my programme goes into an infinite loop, windows allways posts a message and thus render is never called again. Have I left something open? here is some code I think may be of use p.s is there a clearer way to display code on a post? I have seen some peoples that looks like it is in an embedded frame, do you code your own inline frame?? Render loop called only on first iteration //create bmp font menu CBmpFont = new CBMPFont(); //file buf std::filebuf fb; fb.open ("testfnt.fnt", std::ios::in); std::istream is(&fb); CBmpFont->ParseFont( is, CharSetMenu ); fb.close() Parser //************************************************************* // Name:ParseFont // Purpose: parse the fnt file created by angelcode bmpfont // creator // The output from the bmpfont creator looks like this // // common lineHeight=32 base=25 scaleW=256 scaleH=256 pages=1 // char id=0 x=149 y=113 width=9 height=19 xoffset=1 yoffset=7 xadvance=11 page=0 // char id=1 x=159 y=112 width=9 height=19 xoffset=1 yoffset=7 xadvance=11 page=0 // char id=2 x=169 y=112 width=9 height=19 xoffset=1 yoffset=7 xadvance=11 page=0 // char id=3 x=179 y=112 width=9 height=19 xoffset=1 yoffset=7 xadvance=11 page=0 // // and so on for all chars in the font set // //************************************************************* bool CBMPFont::ParseFont( std::istream &Stream, CharSet &CharsetDesc ) { //the entire line read in std::string Line; //read is key word that finds is the line a common or char std::string Read; //value is the value asscoiated to the specific key eg id, x, y etc. std::string Value; //size of the line //std::size_t i; std::string::size_type i; //location of next white space char std::string::size_type Space; //while not eof while( !Stream.eof() ) { //get the string for the current line std::getline( Stream, Line ); //stringstream to hold the current line //std::stringstream LineStream; //now read the line type i = Line.find( "common" ); //check if it has been found if( i != std::string::npos ) { //now we are looking at common data //look for LineHeight i = Line.find( "lineHeight" ); //check it has been found if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); //use i + 11 as lineheight is 10 chars long then we have the = char Value.assign( Line, i + 11, Space - ( i + 11 ) ); //convert the string value to int CharsetDesc.LineHeight = atoi( StringToChar( Value ) ); } //look for base i = Line.find( "base" ); //check it has been found if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 5, Space - ( i + 5 ) ); CharsetDesc.Base = atoi( StringToChar( Value ) ); } //look for scaleW i = Line.find( "scaleW" ); //check for it if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line); Value.assign( Line, i + 7, Space - ( i + 7 ) ); CharsetDesc.Width = atoi( StringToChar( Value ) ); } //look for scaleH i = Line.find( "scaleH" ); //check it if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 7, Space - ( i + 7 ) ); CharsetDesc.Height = atoi( StringToChar( Value ) ); } //look for pages i = Line.find( "pages" ); //check it if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); //last value in string, that also ends without a space after it Value.assign( Line, i + 6, Space ); CharsetDesc.Pages = atoi( StringToChar( Value ) ); } } //end looking for common values //char values i = Line.find( "char" ); //fill in char attributes if( i != std::string::npos ) { //we are looking at a char //a charset has 256 chars so we can support this with an unsigned short unsigned short CharID; //does it have an id i = Line.find( "id" ); //check it if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 3, Space - ( i + 3 ) ); CharID = atoi( StringToChar( Value ) ); LogInfo( "
  • CharID found ok for " ); } //now we have an id we can fill out the character structs i = Line.find( "x" ); //check it if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 2, Space - ( i + 2 ) ); CharsetDesc.Chars[CharID].x = atoi( StringToChar( Value ) ); } //y i = Line.find( "y" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 2, Space - ( i + 2 ) ); CharsetDesc.Chars[CharID].y = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //width i = Line.find( "width" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 6, Space - ( i + 6 ) ); CharsetDesc.Chars[CharID].Width = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //height i = Line.find( "height" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 7, Space - ( i + 7 ) ); CharsetDesc.Chars[CharID].Height = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //xoffset i = Line.find( "xoffset" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 8, Space - ( i + 8 ) ); CharsetDesc.Chars[CharID].XOffset = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //yoffset i = Line.find( "yoffset" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 8, Space - ( i + 8 ) ); CharsetDesc.Chars[CharID].YOffset = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //xadvance i = Line.find( "xadvance" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 9, Space - ( i + 9 ) ); CharsetDesc.Chars[CharID].XAdvance = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } //page i = Line.find( "page" ); if( i != std::string::npos ) { Space = FindWhiteSpace( i, Line ); Value.assign( Line, i + 5, Space - ( i + 5 ) ); CharsetDesc.Chars[CharID].Page = atoi( StringToChar( Value ) ); LogInfo( "
  • Y found ok for " ); } } } return true; } //************************************************************* // Name:ParseFont // Purpose: Finds the next white space character in the string, // given how far into the string we are, returns the location, // of the white space char //************************************************************* std::string::size_type CBMPFont::FindWhiteSpace( std::string::size_type LineLocation, std::string Line ) { //number of chars until next space std::string::size_type Space; //loop through string from i + 12 ( length of lineheight + 2 just after = char) until we reach the next string for( std::string::size_type j = LineLocation; j != Line.size(); ++j ) { Space = j; if( Line[j] == ' ' ) { break; } if( j == Line.size() ) { //we are at the end of file so break here, probably denotes last value in the string break; } } //return the position of the space return Space; } //************************************************************* // Name: StringToChar // Purpose: convert string to char array //************************************************************* char* CBMPFont::StringToChar( std::string Text ) { //get the length of the string int StringLength = Text.size(); //create the char array char *pca = new char[ StringLength ]; //convert the std::string into char* for( std::string::size_type ix = 0; ix != Text.size(); ++ix ) { *(pca + ix) = Text[ix]; } //return the created string return pca; }

    Share this post


    Link to post
    Share on other sites
    You claimed it froze while drawing... but didn't post drawing code.

    Well, lets forget that for now. Instead, lets address other issues. Just dealing with your two 'helper functions'...

    FindWhiteSpace - This does not detect white space. It detects a space. It does not detect tabs, newlines, or carriage returns. You should change the name of the function, perhaps to 'std::string::find_first_of'. No, you can't do that because that function already exists.

    StringToChar - This function leaks. Nor does it stick a null terminator on the end of the string, which makes attemtping to use it with the C stdlib fatal. You seem to be using it so you can call atoi. Don't. First, use std::string::c_str() instead. Once again, std::string already does what you want. Second, don't even use atoi. Use boost::lexical_cast.

    Share this post


    Link to post
    Share on other sites
    thanks Deyja,

    although there is no code to render the font onto the screen yet, the next port of call should of been the render method and it should draw a cube. After getting rid of my "helper functionws" and using the std library functions all seems to be in order.

    Share this post


    Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    Sign in to follow this