kick
/Users/morten/Programmering/cpp/kick/src/kick/2d/font.cpp
00001 //
00002 // Created by morten on 30/06/14.
00003 //
00004 
00005 #include "kick/2d/font.h"
00006 #include "kick/core/project.h"
00007 #include "kick/core/debug.h"
00008 #include <string>
00009 #include <sstream>
00010 #include <iostream>
00011 
00012 using namespace std;
00013 
00014 namespace kick{
00015     Font::Font()  {
00016         fShader = Project::loadShader("assets/shaders/font.shader");
00017     }
00018 
00019     Font::~Font() {
00020     }
00021 
00022     std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
00023         elems.clear();
00024         std::stringstream ss(s);
00025         std::string item;
00026         while (std::getline(ss, item, delim)) {
00027                         if (item.length()>0){
00028                                 elems.push_back(item);
00029                         }
00030         }
00031         return elems;
00032     }
00033 
00034     bool Font::loadFntFile(string filename) {
00035         string texturename = filename.substr(0, filename.size()-4) + ".png";
00036         mFontMap.clear();
00037         mKerning.clear();
00038         TextureSampler sampler;
00039         sampler.filterMag = TextureFilter::Linear;
00040         sampler.filterMin = TextureFilter::LinearMipmapLinear;
00041 
00042         setTexture(Project::loadTexture2D(texturename, sampler));
00043         if (!mTexture){
00044             logWarning(string("Cannot load font texture file ")+texturename);
00045             return false;
00046         }
00047         string fntFile;
00048         if (!Project::loadTextResource(filename,fntFile)){
00049             logWarning(string("Cannot load font text file ")+filename);
00050             return false;
00051         }
00052         std::istringstream f{fntFile};
00053         std::string line;
00054         std::vector<string> elems;
00055         std::vector<string> keyval;
00056         while (std::getline(f, line)) {
00057             split(line, ' ', elems);
00058             if (elems.empty())
00059                 continue;
00060             if (elems[0] == "info") {
00061             } else if (elems[0] == "common") {
00062                 for (int i=1;i<elems.size();i++) {
00063                     split(elems[i], '=', keyval);
00064                     if (keyval[0] == "lineHeight"){
00065                         mLineHeight = stoi(keyval[1]);
00066                     } else if (keyval[0] == "base"){
00067                         mBase = stoi(keyval[1]);
00068                     } else if (keyval[0] == "scaleW"){
00069                         mScaleW = stoi(keyval[1]);
00070                     } else if (keyval[0] == "scaleH"){
00071                         mScaleH = stoi(keyval[1]);
00072                     } else if (keyval[0] == "pages"){
00073                         mPages = stoi(keyval[1]);
00074                     }
00075                 }
00076             } else if (elems[0] == "page") {
00077             } else if (elems[0] == "chars") {
00078             } else if (elems[0] == "char") {
00079                 FontChar fc{};
00080                 int id = -1;
00081                 for (int i=1;i<elems.size();i++){
00082                     split(elems[i], '=', keyval);
00083                     if (keyval[0] == "id"){
00084                         id = stoi(keyval[1]);
00085                     } else if (keyval[0] == "x"){
00086                         fc.x = stoi(keyval[1]);
00087                     } else if (keyval[0] == "y"){
00088                         fc.y = stoi(keyval[1]);
00089                     } else if (keyval[0] == "width"){
00090                         fc.width = stoi(keyval[1]);
00091                     } else if (keyval[0] == "height"){
00092                         fc.height = stoi(keyval[1]);
00093                     } else if (keyval[0] == "xoffset"){
00094                         fc.xoffset = stoi(keyval[1]);
00095                     } else if (keyval[0] == "yoffset"){
00096                         fc.yoffset = stoi(keyval[1]);
00097                     } else if (keyval[0] == "xadvance"){
00098                         fc.xadvance = stoi(keyval[1]);
00099                     } else if (keyval[0] == "page"){
00100                         fc.page = stoi(keyval[1]);
00101                     } else if (keyval[0] == "chnl"){
00102                         fc.chnl = stoi(keyval[1]);
00103                     } else if (keyval[0] == "letter"){
00104                         //    f.letter = keyval[1].substr (1, (unsigned long) (keyval[1].length()-2));
00105                     }
00106                 }
00107                 mFontMap[id] = fc;
00108             } else if (elems[0] == "kernings") {
00109 
00110             } else if (elems[0] == "kerning") {
00111                 int first =0;
00112                 int second=0;
00113                 int amount=0;
00114                 for (int i=1;i<elems.size();i++) {
00115 
00116                     split(elems[i], '=', keyval);
00117                     if (keyval[0] == "first"){
00118                         first  =stoi(keyval[1]);
00119                     } else if (keyval[0] == "second"){
00120                         second =stoi(keyval[1]);
00121                     } else if (keyval[0] == "amount"){
00122                         amount =stoi(keyval[1]);
00123                     }
00124                 }
00125                 mKerning[pair<int,int>{first, second}] = amount;
00126             } else {
00127                 cout << "Not found type "<<elems[0]<<endl;
00128             }
00129             elems.clear();
00130         }
00131         return true;
00132     }
00133 
00134     int Font::width(std::string text) {
00135         int sum = 0;
00136         int lastChar = -1;
00137         for (int i=0;i<text.length();i++){
00138             int f = text[i];
00139             auto foundChar = mFontMap.find(f);
00140             if (foundChar != mFontMap.end()){
00141                 sum += getKerning(lastChar, f);
00142                 if (i == text.length()-1){
00143                     sum += foundChar->second.width;
00144                 } else {
00145                     sum += foundChar->second.xadvance;
00146                 }
00147                 lastChar = f;
00148             } else {
00149                 cout << "Cannot find char "<<f<<endl;
00150                 return -1;
00151             }
00152         }
00153         return sum;
00154     }
00155 
00156     int Font::getKerning(int t1, int t2){
00157         auto foundKerning = mKerning.find(pair<int,int>{t1, t2});
00158         if (foundKerning != mKerning.end()){
00159             return foundKerning->second;
00160         }
00161         return 0;
00162     }
00163 
00164     int Font::height() {
00165         return mLineHeight;
00166     }
00167 
00168     shared_ptr<Texture2D> Font::texture() const {
00169         return mTexture;
00170     }
00171 
00172     void Font::setTexture(shared_ptr<Texture2D> texture) {
00173         Font::mTexture = texture;
00174         fontListener.notifyListeners(this);
00175     }
00176 
00177     const FontChar Font::getChar(char r) {
00178         auto found = mFontMap.find((int)r);
00179         if (found != mFontMap.end()){
00180             return found->second;
00181         } else {
00182             return kick::FontChar{0,0,0,0};
00183         }
00184     }
00185 
00186     int Font::scaleW() const {
00187         return mScaleW;
00188     }
00189 
00190     int Font::scaleH() const {
00191         return mScaleH;
00192     }
00193 
00194     int Font::base() const {
00195         return mBase;
00196     }
00197 
00198     void Font::setShader(std::shared_ptr<Shader> shader) {
00199         this->fShader = shader;
00200         fontListener.notifyListeners(this);
00201     }
00202 
00203     std::shared_ptr<Shader> Font::getShader() {
00204         return fShader;
00205     }
00206 
00207     bool Font::initialized() const {
00208         return mTexture != nullptr;
00209     }
00210 }
 All Classes Functions Variables