AngelCode BMPFont Parser
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;
}
Can yuou, please, enclose your source code in [source lang="cpp"][/source] tags? Without formatting, it is a pain to read.
Regards,
Regards,
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement