[英]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.