繁体   English   中英

将 Freetype 位图复制到 Magick::Image 中的特定偏移量

[英]Copy Freetype Bitmap into Magick::Image at specific offset

在我的游戏引擎中,我有一个纹理加载 API,它包装了 OpenGL、DirectX 等低级库。这个 API 使用 Magick++,因为我发现它是一个方便的跨平台解决方案,并且允许我相当轻松地创建程序纹理。

我现在正在添加一个使用 freetype 的文本渲染系统,我想使用这个纹理 API 为所有字形水平相邻存储的任何给定字体动态生成纹理图集。

过去,我可以通过将位图直接缓冲到 OpenGL 中来实现这一点。 但现在我想使用此 API 以独立于平台的方式完成此操作。

我四处寻找一些示例,但找不到与我所追求的完全相似的东西,因此如果周围有任何 magick++ 专家,我将非常感谢一些指示。

所以简单来说:我有一个自由类型位图,我希望能够将其像素缓冲区复制到 Magick::Image 内的特定偏移量。

此代码可能有助于澄清:

auto texture = e6::textures->create(e6::texture::specification{}, [name, totalWidth, maxHeight](){

      // Initialises Freetype
      FT_Face face;
      FT_Library ft;

      if (FT_Init_FreeType(&ft)) {
        std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
      }

      if (int error = FT_New_Face(ft, path(name.c_str()).c_str(), 0, &face)) {
        std::cout << "Failed to initialise fonts: " << name << std::endl;
        throw std::exception();
      }

      // Sets the size of the font
      FT_Set_Pixel_Sizes(face, 0, 100);

      unsigned int cursor = 0; // Keeps track of the horizontal offset.

      // Preallocate an image buffer
      // totalWidth and maxHeight is the size of the entire atlas
      Magick::Image image(Magick::Geometry(totalWidth, maxHeight), "BLACK");
      image.type(Magick::GrayscaleType);
      image.magick("BMP");
      image.depth(8);
      image.modifyImage();
      Magick::Pixels view(image);

      // Loops through a subset of the ASCII codes
      for (uint8_t c = 32; c < 128; c++) {
        if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
          std::cout << "Failed to load glyph: " << c << std::endl;
          continue;
        }

        // Just for clarification...
        unsigned int width = face->glyph->bitmap.width;
        unsigned int height = face->glyph->bitmap.rows;
        unsigned char* image_data = face->glyph->bitmap.buffer;

        // This is the problem part.
        // How can I copy the image_data into `image` at the cursor position?

        cursor += width; // Advance the cursor
      }

      image.write(std::string(TEXTURES) + "font-test.bmp"); // Write to filesystem

      // Clean up freetype
      FT_Done_Face(face);
      FT_Done_FreeType(ft);

      return image;
    }, "font-" + name);

我尝试使用文档演示的像素缓存:

Magick::Quantum *pixels = view.get(cursor, 0, width, height);
*pixels = *image_data;
view.sync();

但这给我留下了一个完全黑色的图像,我认为是因为 image_data 超出了范围。

我希望有一种方法可以直接修改图像数据,但经过大量试验和错误后,我最终只是为每个字形创建了一个图像并将它们合成在一起:

...

Magick::Image glyph (Magick::Geometry(), "BLACK");
glyph.type(MagickCore::GrayscaleType);
glyph.magick("BMP");
glyph.depth(8);
glyph.read(width, height, "R", Magick::StorageType::CharPixel, image_data);

image.composite(glyph, cursor, 0);

cursor += width;

至少,我希望这有助于防止其他人落入我做过的同一个兔子洞。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM