From 92f17580846c88108aab023092c23e6bcdcf2f75 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Fri, 14 Aug 2015 23:45:02 +0800 Subject: SMELT is finally finished! Add the SMELT library for future use. Add .gitignore. --- extensions/smbmfont.cpp | 218 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 extensions/smbmfont.cpp (limited to 'extensions/smbmfont.cpp') diff --git a/extensions/smbmfont.cpp b/extensions/smbmfont.cpp new file mode 100644 index 0000000..598c7eb --- /dev/null +++ b/extensions/smbmfont.cpp @@ -0,0 +1,218 @@ +// -*- C++ -*- +/* + * Simple MultimEdia LiTerator(SMELT) + * by Chris Xiong 2015 + * api level 1 + * Bitmap font support implementation + * + * WARNING: This library is in development and interfaces would be very + * unstable. + * This library is developed for the BLR series games. + */ +#include "smbmfont.hpp" +#include +#include +#include + +SMELT *smBMFont::sm=NULL; +SMELT *smBMFontw::sm=NULL; + +void smBMFont::parseMeta(char* meta,DWORD size) +{ + char* cp=meta; + char line[65]; + int cc,cod,pa,pb;smTexRect rct; + while(cp-meta<=size) + { + cc=0; + for(;*(cp+cc)!='\n'&&cp+cc-meta<=size;++cc); + strncpy(line,cp,cc);if(line[cc]=='\n')line[cc]='\0'; + cp+=cc+1; + char* tp=strchr(line,','); + if(tp)*tp='\0';else continue; + sscanf(tp+1,"%d,%f,%f,%f,%f,%d,%d",&cod,&rct.x,&rct.y,&rct.w,&rct.h,&pb,&pa); + if(cod>=0&&cod<256) + { + if(xm.find(std::string(line))==xm.end()) + { + char* texct=anm.getFilePtr(line); + DWORD texsz=anm.getFileSize(line); + xm[std::string(line)]=sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(line); + } + chars[cod]=new smEntity2D(xm[std::string(line)],rct); + pdb[cod]=pb;pda[cod]=pa;if(hadv::iterator i=xm.begin();i!=xm.end();++i) + sm->smTextureFree(i->second); + xm.clear(); + sm->smRelease(); +} +void smBMFont::render(float x,float y,float z,int align,float *rw,const char* text) +{ + float width=0,cw=0,ofs=x; + const char* t=text; + while(*t) + { + cw=0; + for(;*t&&*t!='\n';++t) + { + if(chars[(int)*t]) + cw+=chars[(int)*t]->_w()+pdb[(int)*t]+pda[(int)*t]; + } + if(cw>width)width=cw; + while(*t=='\n')++t; + } + width*=sc; + if(rw)*rw=width; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + while(*text) + { + if(*text=='\n') + { + y+=hadv*sc;ofs=x; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + } + else + { + if(chars[(int)*text]) + { + ofs+=pdb[(int)*text]*sc; + chars[(int)*text]->setZ(z); + chars[(int)*text]->setColor(color); + chars[(int)*text]->setBlend(b); + chars[(int)*text]->render(ofs,y,0,sc); + ofs+=(chars[(int)*text]->_w()+pda[(int)*text])*sc; + } + } + ++text; + } +} +void smBMFont::printf(float x,float y,float z,int align,float *rw,const char* format,...) +{ + char buf[1024]; + va_list vl; + va_start(vl,format); + vsnprintf(buf,sizeof(buf)-1,format,vl); + va_end(vl); + buf[sizeof(buf)-1]='\0'; + render(x,y,z,align,rw,buf); +} + +void smBMFontw::parseMeta(char* meta,DWORD size) +{ + char* cp=meta; + char line[65]; + int cc,cod,pa,pb;smTexRect rct; + while(cp-meta<=size) + { + cc=0; + for(;*(cp+cc)!='\n'&&cp+cc-meta<=size;++cc); + strncpy(line,cp,cc);if(line[cc]=='\n')line[cc]='\0'; + cp+=cc+1; + char* tp=strchr(line,','); + if(tp)*tp='\0';else continue; + sscanf(tp+1,"%d,%f,%f,%f,%f,%d,%d",&cod,&rct.x,&rct.y,&rct.w,&rct.h,&pb,&pa); + if(cod>=WCHAR_MIN&&cod<=WCHAR_MAX) + { + if(xm.find(std::string(line))==xm.end()) + { + char* texct=anm.getFilePtr(line); + DWORD texsz=anm.getFileSize(line); + xm[std::string(line)]=sm->smTextureLoadFromMemory(texct,texsz); + anm.releaseFilePtr(line); + } + chars[cod]=new smEntity2D(xm.find(std::string(line))->second,rct); + pdb[cod]=pb;pda[cod]=pa;if(hadv::iterator i=chars.begin();i!=chars.end();++i)if(i->second){delete i->second;i->second=NULL;} + for(std::map::iterator i=xm.begin();i!=xm.end();++i) + sm->smTextureFree(i->second); + xm.clear();chars.clear();pdb.clear();pda.clear(); + sm->smRelease(); +} +void smBMFontw::render(float x,float y,float z,int align,float *rw,const wchar_t* text) +{ + float width=0,cw=0,ofs=x; + const wchar_t* t=text; + while(*t) + { + cw=0; + for(;*t&&*t!='\n';++t) + { + if(chars[*t]) + cw+=chars[*t]->_w()+pdb[*t]+pda[*t]; + } + if(cw>width)width=cw; + while(*t=='\n')++t; + } + width*=sc; + if(rw)*rw=width; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + while(*text) + { + if(*text=='\n') + { + y+=hadv*sc;ofs=x; + if(align==ALIGN_CENTER)ofs-=width/2.; + if(align==ALIGN_RIGHT)ofs-=width; + } + else + { + if(chars[*text]) + { + ofs+=pdb[*text]*sc; + chars[*text]->setZ(z); + chars[*text]->setColor(color); + chars[*text]->setBlend(b); + chars[*text]->render(ofs,y,0,sc); + ofs+=(chars[*text]->_w()+pda[*text])*sc; + } + } + ++text; + } +} +void smBMFontw::printf(float x,float y,float z,int align,float *rw,const wchar_t* format,...) +{ + wchar_t buf[1024]; + va_list vl; + va_start(vl,format); + vswprintf(buf,sizeof(buf)-1,format,vl); + va_end(vl); + buf[sizeof(buf)-1]='\0'; + render(x,y,z,align,rw,buf); +} -- cgit v1.2.3