#include "FontEngine.h" #include #include #include #include #include #include FontEngine::FontEngine() { this->loadfontfromfile( "/documents/widget/Fonts/THIN.WFE.tns" ); this->loadfontfromfile( "/documents/widget/Fonts/VGA.WFE.tns" ); this->loadfontfromfile( "/documents/widget/Fonts/SPACE.WFE.tns" ); this->loadfontfromfile( "/documents/widget/Fonts/TINY.WFE.tns" ); this->loadfontfromfile( "/documents/widget/Fonts/STANDARD.WFE.tns" ); this->loadfontfromfile( "/documents/widget/Fonts/FANTASY.WFE.tns" ); this->setcurrentfont( THIN_FONT ); vspacing = 0; hspacing = -1; currentmodifiertypo = Normal; // set text as normal currentmodifierunder = NoUnder; // No underlining currentmodifierstrike = NoStrike; // No striking } FontEngine::~FontEngine() { //dtor for (auto& c : FontCollection ) { for(auto& f : c->Font) { free( f->chardata ); } delete c; } //delete FontCollection; } FontData* FontEngine::loadfontfromfilepointer( char* filename ) { FILE * pFile; pFile = fopen (filename,"r"); if (pFile!=NULL) { bool flag = true; char line[20]; int value=0; int width, height, temp; //char p0[2], p1[2], p2[2], p3[2], p4[2], p5[2], p6[2], p7[2]; char valstr[10]; FontData *tempFont = new FontData; { fscanf( pFile, "%s", line ); // Should read "Name" fscanf( pFile, "%s", tempFont->fontname ); fscanf( pFile, "%s", line ); // Should read "Width" fscanf( pFile, "%d", &width ); fscanf( pFile, "%s", line ); // Should read "Height" fscanf( pFile, "%d", &height ); fscanf( pFile, "%s", line ); // Should read "CharNumber" fscanf( pFile, "%d", &temp ); tempFont->numberchar = temp; fscanf( pFile, "%s", line ); // Should read "Data" for (int j = 0; jnumberchar; j++) { FontChar *tempChar = new FontChar; tempChar->charwidth = width; tempChar->charheight = height; tempChar->chardata = (unsigned short *) malloc( height * sizeof( unsigned short ) ); for (int i = 0; i < height; i++) { // we read the hexadecimal value in the file fscanf( pFile, "%s", valstr ); // we check how many characters has the Hexa value (F->1; FF->2, FFF->3, FFFF->4) (max is 4 bytes) int length = strlen( valstr ); int nbvalue=0; char digit; for(int k = 0; kchardata[i] = nbvalue; } tempFont->Font.push_back( tempChar ); } } fclose (pFile); return tempFont; } } void FontEngine::loadfontfromfile( char* filename ) { FILE * pFile; pFile = fopen (filename,"r"); if (pFile!=NULL) { bool flag = true; char line[20]; int value=0; int width, height, temp; //char p0[2], p1[2], p2[2], p3[2], p4[2], p5[2], p6[2], p7[2]; char valstr[10]; FontData *tempFont = new FontData; { fscanf( pFile, "%s", line ); // Should read "Name" fscanf( pFile, "%s", tempFont->fontname ); fscanf( pFile, "%s", line ); // Should read "Width" fscanf( pFile, "%d", &width ); fscanf( pFile, "%s", line ); // Should read "Height" fscanf( pFile, "%d", &height ); fscanf( pFile, "%s", line ); // Should read "CharNumber" fscanf( pFile, "%d", &temp ); tempFont->numberchar = temp; fscanf( pFile, "%s", line ); // Should read "Data" for (int j = 0; jnumberchar; j++) { FontChar *tempChar = new FontChar; tempChar->charwidth = width; tempChar->charheight = height; tempChar->chardata = (unsigned short *) malloc( height * sizeof( unsigned short ) ); for (int i = 0; i < height; i++) { // we read the hexadecimal value in the file fscanf( pFile, "%s", valstr ); // we check how many characters has the Hexa value (F->1; FF->2, FFF->3, FFFF->4) (max is 4 bytes) int length = strlen( valstr ); int nbvalue=0; char digit; for(int k = 0; kchardata[i] = nbvalue; } tempFont->Font.push_back( tempChar ); } } fclose (pFile); FontCollection.push_back( tempFont ); } } int FontEngine::getstringwidth( char *str ) { int length = (int) strlen( str ); int posx = 0; for(int i=0; i< length-1; i++) { posx += currentfont->Font[str[i]]->charwidth + hspacing; } posx +=currentfont->Font[str[length-1]]->charwidth; // for the alst character we do not add the spacing return posx; } // this is for monoline text, does not take into consideration \n character yet int FontEngine::getstringheight( char *str ) { int length = (int) strlen( str ); int posy = 0; for(int i=0; i< length; i++) { if( currentfont->Font[str[i]]->charheight > posy) posy = currentfont->Font[str[i]]->charheight; } return posy; } int FontEngine::getcharwidth( char str ) { return currentfont->Font[str]->charwidth; } int FontEngine::getcharheight( char str ) { return currentfont->Font[str]->charheight; } void FontEngine::setcurrentfont( fontname curfont ) // To be checked for internam parameters { currentfont = FontCollection[ curfont ]; } void FontEngine::setspacing( int hspace, int vspace ) { hspacing = hspace; vspacing = vspace; } void FontEngine::setmodifiertypo( fontmodifiertypo mod ) { currentmodifiertypo = mod; } void FontEngine::setmodifierunder( fontmodifierunder mod ) { currentmodifierunder = mod; } void FontEngine::setmodifierstrike( fontmodifierstrike mod ) { currentmodifierstrike = mod; } void FontEngine::drawstringleft( SDL_Surface *screen, char *str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { int length = (int) strlen( str ); int posx = x; int posy = y; for(int i=0; i< length; i++) { drawcharleft( screen, str[i], posx, posy, R, G, B, A ); posx += currentfont->Font[str[i]]->charwidth + hspacing; } } void FontEngine::drawcharleft( SDL_Surface *screen, char str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { FontChar *temp = currentfont->Font[str]; for (int j=0; jcharheight; j++) { int mask = 1; for (int i=0; icharwidth; i++) { if ((temp->chardata[j] & (mask << i)) != 0) { if ((currentmodifiertypo & Normal) !=0 ) { // text is Normal pixelRGBA( screen, x+temp->charwidth-i-1, y+j, R, G, B, A); } if ((currentmodifiertypo & Italic) !=0 ) { // text is Italic but not Bold int shift = (int) ((temp->charheight-1-j)/4); pixelRGBA( screen, x+temp->charwidth-i-1+shift, y+j, R, G, B, A); } if ((currentmodifiertypo & Bold) !=0 ) { // text is Bold but not Italic pixelRGBA( screen, x+temp->charwidth-i-1, y+j, R, G, B, A); pixelRGBA( screen, x+temp->charwidth-i, y+j, R, G, B, A); } if ((currentmodifiertypo & ItalicBold) !=0 ) { // text is Italic and Bold int shift = (int) ((temp->charheight-1-j)/4); pixelRGBA( screen, x+temp->charwidth-i-1+shift, y+j, R, G, B, A); pixelRGBA( screen, x+temp->charwidth-i+shift, y+j, R, G, B, A); } } } } if ((currentmodifierunder & NoUnder) !=0 ) { // text is not underlined } if ((currentmodifierunder & UnderSimple) !=0 ) { // text is underlined with one single line lineRGBA( screen, x-1, y+temp->charheight+2, x+temp->charwidth+1, y+temp->charheight+2, R, G, B, A ); } if ((currentmodifierunder & UnderDouble) !=0 ) { // text is underlined with two lines lineRGBA( screen, x-1, y+temp->charheight+2, x+temp->charwidth+1, y+temp->charheight+2, R, G, B, A ); lineRGBA( screen, x-1, y+temp->charheight+4, x+temp->charwidth+1, y+temp->charheight+4, R, G, B, A ); } if ((currentmodifierstrike & NoStrike) !=0 ) { // text is not underlined } if ((currentmodifierstrike & StrikeSimple) !=0 ) { // text is underlined with one single line lineRGBA( screen, x-1, (int) (y+temp->charheight/2), x+temp->charwidth+1, (int) (y+temp->charheight/2), R, G, B, A ); } if ((currentmodifierstrike & StrikeDouble) !=0 ) { // text is underlined with two lines lineRGBA( screen, x-1, (int) (y+temp->charheight/2)-1, x+temp->charwidth+1, (int) (y+temp->charheight/2)-1, R, G, B, A ); lineRGBA( screen, x-1, (int) (y+temp->charheight/2)+1, x+temp->charwidth+1, (int) (y+temp->charheight/2)+1, R, G, B, A ); } } void FontEngine::drawstringcenter( SDL_Surface *screen, char *str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { int dx = (int) (getstringwidth( str ) / 2); drawstringleft( screen, str, x-dx, y, R, G, B, A); } void FontEngine::drawcharcenter( SDL_Surface *screen, char str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { int dx = (int) (getcharwidth( str ) / 2); drawcharleft( screen, str, x-dx, y, R, G, B, A); } void FontEngine::drawstringright( SDL_Surface *screen, char *str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { int dx = (int) getstringwidth( str ); drawstringleft( screen, str, x-dx, y, R, G, B, A); } void FontEngine::drawcharright( SDL_Surface *screen, char str, int x, int y, unsigned short R, unsigned short G, unsigned short B, unsigned short A ) { int dx = (int) getcharwidth( str ); drawcharleft( screen, str, x-dx, y, R, G, B, A); }