feat: add text tile modifier

This commit is contained in:
jingkaimori 2024-09-19 00:10:06 +08:00
parent 58ea11c2b3
commit 681b915044
2 changed files with 118 additions and 0 deletions

View File

@ -361,3 +361,20 @@ minetest.register_node("testnodes:tga_type10_32bpp_tb", {
use_texture_alpha = "blend",
groups = { dig_immediate = 2 },
})
minetest.register_node("testnodes:glyph_font", {
description = S("Combine Test Node"),
tiles = {{
name = "testnodes_generated_mb.png"..
"^[text:regular font::::white"..
"^[text:large font(16pt):16::0,32:white"..
"^[text:larger font(32pt):32::0,64:white"..
"^[text:bold font(20pt):20:bold:0,96:white"..
"^[text:italic font(20pt):20:italic:0,128:white"..
"^[text:monospace font(20pt):20:mono:0,160:white"..
"^[text:red monospace font(20pt):20:mono:0,192:red",
align_style = "world",
scale = 8,
}},
groups = { dig_immediate = 2 },
})

View File

@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "imagefilters.h"
#include "texturepaths.h"
#include "util/numeric.h"
#include "client/fontengine.h"
#include "irrlicht_changes/CGUITTFont.h"
////////////////////////////////
@ -1814,6 +1816,105 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
apply_brightness_contrast(baseimg, v2u32(0, 0),
baseimg->getDimension(), brightness, contrast);
}
/*
[text:string:size:mono,bold,italic:x,y:color
Render a character at given position
size and font is optional, but colon should be kept
*/
else if (str_starts_with(part_of_name, "[text:")) {
Strfnd sf(part_of_name);
sf.next(":");
std::string textdef = sf.next(":");
core::stringw textdefW = utf8_to_stringw(textdef);
unsigned int fontSize = FONT_SIZE_UNSPECIFIED;
std::string sizeStr = sf.next(":");
if (is_number(sizeStr))
{
fontSize = mystoi(sizeStr,0,200);
}
FontMode mode = FM_Standard;
bool bold = false, italic = false;
std::string fontStyle = sf.next(":");
std::vector<std::string> styleWords = str_split(fontStyle, ',');
for(auto word : styleWords){
if (word == "mono")
{
mode = FM_Mono;
}else if (word == "bold")
{
bold = true;
}else if(word == "italic"){
italic = true;
}
}
FontSpec spec(fontSize, mode, bold, italic);
core::position2di pos(0,0);
std::string positionStr = sf.next(":");
std::vector<std::string> positionStrs = str_split(positionStr, ',');
if (positionStrs.size() >= 2)
{
if (is_number(positionStrs[0]))
{
pos.X=mystoi(positionStrs[0]);
}
if (is_number(positionStrs[1]))
{
pos.Y=mystoi(positionStrs[1]);
}
}
video::SColor color(0xff,0xff,0xff,0xff);
std::string colorStr = sf.next("");
if (!parseColorString(colorStr,color,false)){
return false;
};
irr::gui::CGUITTFont *font =
static_cast<irr::gui::CGUITTFont *>(g_fontengine->getFont(spec));
core::dimension2d<u32> sizeText = font->getDimension(textdefW.c_str());
video::ECOLOR_FORMAT colorFormat = video::ECF_A8R8G8B8;
core::dimension2d<u32> size =sizeText;
if (baseimg)
{
colorFormat = baseimg->getColorFormat();
size =baseimg->getDimension();
}
std::string textureName("text_renderer__");
textureName.append(part_of_name);
auto texture =
driver->addRenderTargetTexture(size, textureName, colorFormat);
if(!driver->setRenderTarget(texture,irr::video::ECBF_ALL, video::SColor(0,0,0,0))){
errorstream << "fails to set render target" << std::endl;
};
if (baseimg){
auto baseTexture = driver->addTexture("text_renderer_base__", baseimg);
driver->draw2DImage(baseTexture, core::vector2di(0,0));
driver->removeTexture(baseTexture);
}
font->draw(textdefW, irr::core::recti(pos, sizeText), color);
driver->setRenderTarget(NULL);
void* lockedData = texture->lock();
if (lockedData)
{
if (baseimg)
{
baseimg->drop();
}
baseimg = driver->createImageFromData(colorFormat, size, lockedData, false);
texture->unlock();
}else
{
errorstream << "no data inside texture, internal error" << std::endl;
}
driver->removeTexture(texture);
}
else
{
errorstream << "generateImagePart(): Invalid "