SFML community forums

Help => General => Topic started by: smguyk on May 20, 2014, 03:34:01 pm

Title: Change the font loadFromFile() function to loadFromMemory() in my resource class
Post by: smguyk on May 20, 2014, 03:34:01 pm
Hey,

I have this resource class that holds my resources (just fonts) for me. I call initialise() to load the resources, then I do the normal program flow and before I exit the program I call cleanUp(). This is all working perfectly.

This is the code for the class. resources.h:

#ifndef __RESOURCES_H__
#define __RESOURCES_H__

#include <SFML\Graphics.hpp>

class Resources {
 public:
  Resources();
  bool initialise();
  void cleanUp();
  bool loadAllFonts();
  bool loadFont(std::string filename);
  sf::Font &getFont(std::string filename);

  const std::string myFont_;
  const std::string myOtherFont_;

 private:
  const std::string fontPath_;
  std::map<std::string, sf::Font*> fonts_;

};

#endif

resources.cpp

#include "resources.h"

Resources::Resources() :
  myFont_("./data/myFont.ttf"),
  myOtherFont_("./data/myOtherFont.ttf")
{
}

bool Resources::initialise() {
  if (loadAllFonts()) { return true; }
  return false;
}

void Resources::cleanUp() {
  std::map<std::string, sf::Font*>::iterator font_it;
  for (font_it = fonts_.begin(); font_it != fonts_.end(); font_it++) {
    delete font_it->second;
    font_it->second = NULL;
  }
  fonts_.clear();
}

bool Resources::loadAllFonts() {
  if (!loadFont(myFont_)) { return false; }
  if (!loadFont(myOtherFont_)) { return false; }
  return true;
}

bool Resources::loadFont(std::string filename) {
  if (fonts_.find(filename) != fonts_.end()) {
    return false;
  }
  sf::Font *font = new sf::Font();
  sf::err().rdbuf(NULL);
  if (!font->loadFromFile(filename)) {
    delete font;
    font = NULL;
    return false;
  }
  const_cast<sf::Texture&>(font->getTexture(8)).setSmooth(false);
  const_cast<sf::Texture&>(font->getTexture(12)).setSmooth(false);
  const_cast<sf::Texture&>(font->getTexture(16)).setSmooth(false);
  const_cast<sf::Texture&>(font->getTexture(24)).setSmooth(false);
  fonts_.insert(std::pair<std::string, sf::Font*>(filename, font));
  return true;
}

sf::Font &Resources::getFont(std::string filename) {
  return *(fonts_.find(filename)->second);
}

This was simple enough and went without problems. I just use the class like this:

int main() {
  //...

  Resources resources_;
  resources_.initialise();

  sf::Text testText("test text", resources_.getFont(resources_.myFont_), 25);

  // ... (program loop)

  resources_.cleanUp();

  return 0;
}

Now, what I want to do is the following:

In Resources::loadFont(), instead of loading a font from a file with loadFromFile(filename), I want to load it from memory.

I know how loading a font from memory works. I simply convert a font file and fill an unsigned char array with the font data:

unsigned char myFontChar[] = {0x00,0x01,0x00, .......... ,0x00,0x30,0x00,0x03,0x00,0xc0,0x4f,0x53,0x2f};

Then I load the font like this:

sf::Font font;
if (!font.loadFromMemory(myFontChar, sizeof(myFontChar))) { return -1; }

This is working when I do it as demonstrated above, but I have no idea how I would go about adjusting the Resources::loadFont() function so that instead of loading the specified font from a file it loads it from memory (the unsigned char array).

Could you please help me and point me in the right direction?

I am not a pro, so this is hard for me, but I have some vague idea how to do it (in theory). I would apply the same principle that I currently have: Use an "identifier", so the std::map could be used.

Instead of std::map<std::string, sf::Font*> I would have to use something that replaces the second parameter sf::Font*, but I don't know what that would be and how the Resources::loadFont() function would then look like.

I hope I explained it well enough and really really hope someone can help me.

Thanks!
Title: Re: Change the font loadFromFile() function to loadFromMemory() in my resource class
Post by: Ixrec on May 20, 2014, 05:54:20 pm
I believe you simply open the file in binary mode with standard iostreams and read it into memory.
Title: Re: Change the font loadFromFile() function to loadFromMemory() in my resource class
Post by: smguyk on May 20, 2014, 06:35:26 pm
I actually solved it, but it won't let me remove this thread.

Now I have the fonts as class members and load them from memory in the constructor, and the getFont() function just returns the font based on the name that is passed.

I also got rid of the map!
Title: Re: Change the font loadFromFile() function to loadFromMemory() in my resource class
Post by: Nexus on May 20, 2014, 10:17:03 pm
but it won't let me remove this thread.
Removing is a bad idea. Others may benefit in the future, or there may be people writing an answer.

Or people like me who give feedback unrelated to the actual question :p
Title: Re: Change the font loadFromFile() function to loadFromMemory() in my resource class
Post by: smguyk on May 21, 2014, 09:12:42 am

Thanks, I took some of those suggestions to heart and improved my code!