C++ 将通过loadFromFile()加载字体的函数更改为我的资源类中的loadFromMemory()

C++ 将通过loadFromFile()加载字体的函数更改为我的资源类中的loadFromMemory(),c++,memory,resources,sfml,C++,Memory,Resources,Sfml,我有一个资源类,它为我保存我的资源(只是字体)。我调用initialise()加载资源,然后 正常的程序流,在退出程序之前,我调用cleanUp()。这一切都很完美 这是该类的代码。资源.h: #ifndef __RESOURCES_H__ #define __RESOURCES_H__ #include <SFML\Graphics.hpp> class Resources { public: Resources(); bool initialise(); voi

我有一个资源类,它为我保存我的资源(只是字体)。我调用initialise()加载资源,然后 正常的程序流,在退出程序之前,我调用cleanUp()。这一切都很完美

这是该类的代码。资源.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::loadFont()
中,我想从内存中加载字体,而不是从带有
loadFromFile(filename)
的文件中加载字体

我知道如何从内存加载字体。我只需转换字体文件并用字体数据填充未签名字符数组:

unsigned char myFontChar[] = {0x00,0x01, .......... ,0x00,0x30,0x4f,0x53,0x2f};
然后我像这样加载字体:

int main() {
  //...

  Resources resources_;
  resources_.initialise();

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

  // ... (program loop)

  resources_.cleanUp();

  return 0;
}
sf::Font font;
if (!font.loadFromMemory(myFontChar, sizeof(myFontChar))) { return -1; }
当我按照上面的演示进行操作时,这是可行的,但我不知道如何调整
Resources::loadFont()
函数,以便从内存(无符号字符数组)加载指定字体,而不是从文件加载指定字体

你能帮我指一下正确的方向吗

我不是职业选手,所以这对我来说很难,但我对如何做到这一点(理论上)有一些模糊的想法。我将应用与当前相同的原则:使用“标识符”,以便可以使用std::map。 我将不得不使用一些东西来取代第二个参数
sf::Font*
,而不是
std::map
,但我不知道这将是什么,以及
Resources::loadFont()
函数将是什么样子

我希望我解释得足够好,真的希望有人能帮助我


谢谢

我不会这么做。它使事情变得不那么可配置和不灵活。大多数用户不会接触程序所在的目录。另一方面,如果有人真的想更改字体,他们仍然可以覆盖可执行文件中包含字体的内存部分。不过,假设你有充分的理由这么做,这里有一些想法

一种方法是简单地初始化构造函数中的
std::map
,为字体指定所需的字符串:

bool Resources::loadAllFonts() {
  sf::Font *tempfont;

  tempfont = new sf::Font();
  if (!(tempfont->loadFromMemory(myFontMem)) { return false; }
  fonts_["myfont"] = tempfont;

  tempfont = new sf::Font();
  if (!(tempfont->loadFromMemory(myOtherFontMem)) { return false; }
  fonts_["myotherfont"] = tempfont;

  return true;
}
稍后,您需要记住指定的字符串

但是,如果您只有少量字体,我会将它们作为单个成员存储在
资源中,然后将
getFont()
函数转换为if/else块:

#include <SFML\Graphics.hpp>

class Resources {
 public:
    //...

 private:
  const std::string fontPath_;
  // Load these fonts in the constructor
  sf::Font myFont;
  sf::Font myOtherFont;

};

// ...

sf::Font &Resources::getFont(std::string fontname) {
   if(fontname == "myfont") {
       return myFont;
   } else if(fontname == "myotherfont") {
       return myOtherFont;
   } else {
       // Error somehow
   }
}
#包括
班级资源{
公众:
//...
私人:
常量std::字符串fontPath_u2;;
//在构造函数中加载这些字体
sf::字体myFont;
sf::Font myOtherFont;
};
// ...
sf::Font&Resources::getFont(std::string fontname){
如果(fontname==“myfont”){
返回myFont;
}else if(fontname==“myotherfont”){
返回myOtherFont;
}否则{
//莫名其妙地出错了
}
}

您的错误处理将适合您。如果无法加载字体,是否再次尝试加载?是什么让你认为它第二次会起作用?您甚至不检查或报告无法加载字体的原因。@JoachimPileborg抱歉,复制粘贴错误,已修复!只是为了确保:不是从文件中加载字体,而是将它们硬编码到程序中,然后从静态内存中加载它们?如果是,原因是什么?@Chaosed0是的,没错,事实上有几个原因。除其他外,我只需要发送.exe,我可以确保字体文件不会被用户用相同名称的另一个字体文件替换(因为我的程序取决于我拥有的确切字体)。这正是我想要的。我测试了两个建议和两个工作!我选择了第二种方法,因为现在我甚至不再需要
std::map
cleanUp()
loadFont()
了,我只需要将
sf::Font
作为成员,从
initialise()
中的内存中加载它们,然后使用
getFont()
函数(我稍微更改了一下)归还它们。为此非常感谢!!!
#include <SFML\Graphics.hpp>

class Resources {
 public:
    //...

 private:
  const std::string fontPath_;
  // Load these fonts in the constructor
  sf::Font myFont;
  sf::Font myOtherFont;

};

// ...

sf::Font &Resources::getFont(std::string fontname) {
   if(fontname == "myfont") {
       return myFont;
   } else if(fontname == "myotherfont") {
       return myOtherFont;
   } else {
       // Error somehow
   }
}