forked from Mirrorlandia_minetest/minetest
Replace all core::unicode::ustring with std::u32string (#13775)
This commit is contained in:
parent
56965bc814
commit
3a4bf14c20
@ -2,6 +2,7 @@
|
||||
CGUITTFont FreeType class for Irrlicht
|
||||
Copyright (c) 2009-2010 John Norman
|
||||
Copyright (c) 2016 Nathanaëlle Courant
|
||||
Copyright (c) 2023 Caleb Butler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@ -31,6 +32,8 @@
|
||||
|
||||
#include <irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include "CGUITTFont.h"
|
||||
|
||||
namespace irr
|
||||
@ -313,7 +316,7 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antia
|
||||
|
||||
// Log.
|
||||
if (logger)
|
||||
logger->log(L"CGUITTFont", core::stringw(core::stringw(L"Creating new font: ") + core::ustring(filename).toWCHAR_s() + L" " + core::stringc(size) + L"pt " + (antialias ? L"+antialias " : L"-antialias ") + (transparency ? L"+transparency" : L"-transparency")).c_str(), irr::ELL_INFORMATION);
|
||||
logger->log(L"CGUITTFont", core::stringw(core::stringw(L"Creating new font: ") + core::stringw(filename) + L" " + core::stringc(size) + L"pt " + (antialias ? L"+antialias " : L"-antialias ") + (transparency ? L"+transparency" : L"-transparency")).c_str(), irr::ELL_INFORMATION);
|
||||
|
||||
// Grab the face.
|
||||
SGUITTFace* face = 0;
|
||||
@ -354,8 +357,7 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antia
|
||||
}
|
||||
else
|
||||
{
|
||||
core::ustring converter(filename);
|
||||
if (FT_New_Face(c_library, reinterpret_cast<const char*>(converter.toUTF8_s().c_str()), 0, &face->face))
|
||||
if (FT_New_Face(c_library, reinterpret_cast<const char*>(filename.c_str()), 0, &face->face))
|
||||
{
|
||||
if (logger) logger->log(L"CGUITTFont", L"FT_New_Face failed.", irr::ELL_INFORMATION);
|
||||
|
||||
@ -398,7 +400,7 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antia
|
||||
// Cache the first 127 ascii characters.
|
||||
u32 old_size = batch_load_size;
|
||||
batch_load_size = 127;
|
||||
getGlyphIndexByChar((uchar32_t)0);
|
||||
getGlyphIndexByChar((char32_t)0);
|
||||
batch_load_size = old_size;
|
||||
|
||||
return true;
|
||||
@ -578,28 +580,28 @@ void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& positio
|
||||
}
|
||||
|
||||
// Convert to a unicode string.
|
||||
core::ustring utext = text.getString();
|
||||
std::u32string utext = convertWCharToU32String(text.c_str());
|
||||
|
||||
// Set up our render map.
|
||||
std::map<u32, CGUITTGlyphPage*> Render_Map;
|
||||
|
||||
// Start parsing characters.
|
||||
u32 n;
|
||||
uchar32_t previousChar = 0;
|
||||
core::ustring::const_iterator iter(utext);
|
||||
while (!iter.atEnd())
|
||||
char32_t previousChar = 0;
|
||||
std::u32string::const_iterator iter = utext.begin();
|
||||
while (iter != utext.end())
|
||||
{
|
||||
uchar32_t currentChar = *iter;
|
||||
char32_t currentChar = *iter;
|
||||
n = getGlyphIndexByChar(currentChar);
|
||||
bool visible = (Invisible.findFirst(currentChar) == -1);
|
||||
bool visible = (Invisible.find_first_of(currentChar) == std::u32string::npos);
|
||||
bool lineBreak=false;
|
||||
if (currentChar == L'\r') // Mac or Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if (*(iter + 1) == (uchar32_t)'\n') // Windows line breaks.
|
||||
if (*(iter + 1) == (char32_t)'\n') // Windows line breaks.
|
||||
currentChar = *(++iter);
|
||||
}
|
||||
else if (currentChar == (uchar32_t)'\n') // Unix breaks
|
||||
else if (currentChar == (char32_t)'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
}
|
||||
@ -632,8 +634,9 @@ void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& positio
|
||||
CGUITTGlyphPage* const page = Glyph_Pages[glyph.glyph_page];
|
||||
page->render_positions.push_back(core::position2di(offset.X + offx, offset.Y + offy));
|
||||
page->render_source_rects.push_back(glyph.source_rect);
|
||||
if (iter.getPos() < colors.size())
|
||||
page->render_colors.push_back(colors[iter.getPos()]);
|
||||
const size_t iterPos = iter - utext.begin();
|
||||
if (iterPos < colors.size())
|
||||
page->render_colors.push_back(colors[iterPos]);
|
||||
else
|
||||
page->render_colors.push_back(video::SColor(255,255,255,255));
|
||||
Render_Map[glyph.glyph_page] = page;
|
||||
@ -653,7 +656,7 @@ void CGUITTFont::draw(const EnrichedString &text, const core::rect<s32>& positio
|
||||
offset.X += fallback->getKerningWidth(l1, &l2);
|
||||
offset.Y += fallback->getKerningHeight();
|
||||
|
||||
u32 current_color = iter.getPos();
|
||||
const u32 current_color = iter - utext.begin();
|
||||
fallback->draw(core::stringw(l1),
|
||||
core::rect<s32>({offset.X-1, offset.Y-1}, position.LowerRightCorner), // ???
|
||||
current_color < colors.size() ? colors[current_color] : video::SColor(255, 255, 255, 255),
|
||||
@ -718,10 +721,10 @@ core::dimension2d<u32> CGUITTFont::getCharDimension(const wchar_t ch) const
|
||||
|
||||
core::dimension2d<u32> CGUITTFont::getDimension(const wchar_t* text) const
|
||||
{
|
||||
return getDimension(core::ustring(text));
|
||||
return getDimension(convertWCharToU32String(text));
|
||||
}
|
||||
|
||||
core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
|
||||
core::dimension2d<u32> CGUITTFont::getDimension(const std::u32string& text) const
|
||||
{
|
||||
// Get the maximum font height. Unfortunately, we have to do this hack as
|
||||
// Irrlicht will draw things wrong. In FreeType, the font size is the
|
||||
@ -730,19 +733,19 @@ core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
|
||||
// Irrlicht does not understand this concept when drawing fonts. Also, I
|
||||
// add +1 to give it a 1 pixel blank border. This makes things like
|
||||
// tooltips look nicer.
|
||||
s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1;
|
||||
s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1;
|
||||
s32 test3 = getHeightFromCharacter((uchar32_t)'_') + 1;
|
||||
s32 test1 = getHeightFromCharacter((char32_t)'g') + 1;
|
||||
s32 test2 = getHeightFromCharacter((char32_t)'j') + 1;
|
||||
s32 test3 = getHeightFromCharacter((char32_t)'_') + 1;
|
||||
s32 max_font_height = core::max_(test1, core::max_(test2, test3));
|
||||
|
||||
core::dimension2d<u32> text_dimension(0, max_font_height);
|
||||
core::dimension2d<u32> line(0, max_font_height);
|
||||
|
||||
uchar32_t previousChar = 0;
|
||||
core::ustring::const_iterator iter = text.begin();
|
||||
for (; !iter.atEnd(); ++iter)
|
||||
char32_t previousChar = 0;
|
||||
std::u32string::const_iterator iter = text.begin();
|
||||
for (; iter != text.end(); ++iter)
|
||||
{
|
||||
uchar32_t p = *iter;
|
||||
char32_t p = *iter;
|
||||
bool lineBreak = false;
|
||||
if (p == '\r') // Mac or Windows line breaks.
|
||||
{
|
||||
@ -784,10 +787,10 @@ core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
|
||||
|
||||
inline u32 CGUITTFont::getWidthFromCharacter(wchar_t c) const
|
||||
{
|
||||
return getWidthFromCharacter((uchar32_t)c);
|
||||
return getWidthFromCharacter((char32_t)c);
|
||||
}
|
||||
|
||||
inline u32 CGUITTFont::getWidthFromCharacter(uchar32_t c) const
|
||||
inline u32 CGUITTFont::getWidthFromCharacter(char32_t c) const
|
||||
{
|
||||
// Set the size of the face.
|
||||
// This is because we cache faces and the face may have been set to a different size.
|
||||
@ -812,10 +815,10 @@ inline u32 CGUITTFont::getWidthFromCharacter(uchar32_t c) const
|
||||
|
||||
inline u32 CGUITTFont::getHeightFromCharacter(wchar_t c) const
|
||||
{
|
||||
return getHeightFromCharacter((uchar32_t)c);
|
||||
return getHeightFromCharacter((char32_t)c);
|
||||
}
|
||||
|
||||
inline u32 CGUITTFont::getHeightFromCharacter(uchar32_t c) const
|
||||
inline u32 CGUITTFont::getHeightFromCharacter(char32_t c) const
|
||||
{
|
||||
// Set the size of the face.
|
||||
// This is because we cache faces and the face may have been set to a different size.
|
||||
@ -841,10 +844,10 @@ inline u32 CGUITTFont::getHeightFromCharacter(uchar32_t c) const
|
||||
|
||||
u32 CGUITTFont::getGlyphIndexByChar(wchar_t c) const
|
||||
{
|
||||
return getGlyphIndexByChar((uchar32_t)c);
|
||||
return getGlyphIndexByChar((char32_t)c);
|
||||
}
|
||||
|
||||
u32 CGUITTFont::getGlyphIndexByChar(uchar32_t c) const
|
||||
u32 CGUITTFont::getGlyphIndexByChar(char32_t c) const
|
||||
{
|
||||
// Get the glyph.
|
||||
u32 glyph = FT_Get_Char_Index(tt_face, c);
|
||||
@ -888,20 +891,20 @@ u32 CGUITTFont::getGlyphIndexByChar(uchar32_t c) const
|
||||
|
||||
s32 CGUITTFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
|
||||
{
|
||||
return getCharacterFromPos(core::ustring(text), pixel_x);
|
||||
return getCharacterFromPos(convertWCharToU32String(text), pixel_x);
|
||||
}
|
||||
|
||||
s32 CGUITTFont::getCharacterFromPos(const core::ustring& text, s32 pixel_x) const
|
||||
s32 CGUITTFont::getCharacterFromPos(const std::u32string& text, s32 pixel_x) const
|
||||
{
|
||||
s32 x = 0;
|
||||
//s32 idx = 0;
|
||||
|
||||
u32 character = 0;
|
||||
uchar32_t previousChar = 0;
|
||||
core::ustring::const_iterator iter = text.begin();
|
||||
while (!iter.atEnd())
|
||||
char32_t previousChar = 0;
|
||||
std::u32string::const_iterator iter = text.begin();
|
||||
while (iter != text.end())
|
||||
{
|
||||
uchar32_t c = *iter;
|
||||
char32_t c = *iter;
|
||||
x += getWidthFromCharacter(c);
|
||||
|
||||
// Kerning.
|
||||
@ -936,10 +939,10 @@ s32 CGUITTFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previo
|
||||
if (thisLetter == 0 || previousLetter == 0)
|
||||
return 0;
|
||||
|
||||
return getKerningWidth((uchar32_t)*thisLetter, (uchar32_t)*previousLetter);
|
||||
return getKerningWidth((char32_t)*thisLetter, (char32_t)*previousLetter);
|
||||
}
|
||||
|
||||
s32 CGUITTFont::getKerningWidth(const uchar32_t thisLetter, const uchar32_t previousLetter) const
|
||||
s32 CGUITTFont::getKerningWidth(const char32_t thisLetter, const char32_t previousLetter) const
|
||||
{
|
||||
// Return only the kerning width.
|
||||
return getKerning(thisLetter, previousLetter).X;
|
||||
@ -953,10 +956,10 @@ s32 CGUITTFont::getKerningHeight() const
|
||||
|
||||
core::vector2di CGUITTFont::getKerning(const wchar_t thisLetter, const wchar_t previousLetter) const
|
||||
{
|
||||
return getKerning((uchar32_t)thisLetter, (uchar32_t)previousLetter);
|
||||
return getKerning((char32_t)thisLetter, (char32_t)previousLetter);
|
||||
}
|
||||
|
||||
core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32_t previousLetter) const
|
||||
core::vector2di CGUITTFont::getKerning(const char32_t thisLetter, const char32_t previousLetter) const
|
||||
{
|
||||
if (tt_face == 0 || thisLetter == 0 || previousLetter == 0)
|
||||
return core::vector2di();
|
||||
@ -1006,20 +1009,18 @@ core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32
|
||||
|
||||
void CGUITTFont::setInvisibleCharacters(const wchar_t *s)
|
||||
{
|
||||
core::ustring us(s);
|
||||
Invisible = us;
|
||||
Invisible = convertWCharToU32String(s);
|
||||
}
|
||||
|
||||
void CGUITTFont::setInvisibleCharacters(const core::ustring& s)
|
||||
video::IImage* CGUITTFont::createTextureFromChar(const char32_t& ch)
|
||||
{
|
||||
Invisible = s;
|
||||
}
|
||||
// This character allows us to print something to the screen for unknown, unrecognizable, or
|
||||
// unrepresentable characters. See Unicode spec.
|
||||
const char32_t UTF_REPLACEMENT_CHARACTER = 0xFFFD;
|
||||
|
||||
video::IImage* CGUITTFont::createTextureFromChar(const uchar32_t& ch)
|
||||
{
|
||||
u32 n = getGlyphIndexByChar(ch);
|
||||
if (n == 0)
|
||||
n = getGlyphIndexByChar((uchar32_t) core::unicode::UTF_REPLACEMENT_CHARACTER);
|
||||
n = getGlyphIndexByChar(UTF_REPLACEMENT_CHARACTER);
|
||||
|
||||
const SGUITTGlyph& glyph = Glyphs[n-1];
|
||||
CGUITTGlyphPage* page = Glyph_Pages[glyph.glyph_page];
|
||||
@ -1246,5 +1247,27 @@ core::array<scene::ISceneNode*> CGUITTFont::addTextSceneNode(const wchar_t* text
|
||||
return container;
|
||||
}
|
||||
|
||||
std::u32string CGUITTFont::convertWCharToU32String(const wchar_t* const charArray) const
|
||||
{
|
||||
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "unexpected wchar size");
|
||||
|
||||
if (sizeof(wchar_t) == 4) // Systems where wchar_t is UTF-32
|
||||
return std::u32string(reinterpret_cast<const char32_t*>(charArray));
|
||||
|
||||
// Systems where wchar_t is UTF-16:
|
||||
// First, convert to UTF-8
|
||||
std::u16string utf16String(reinterpret_cast<const char16_t*>(charArray));
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter1;
|
||||
std::string utf8String = converter1.to_bytes(utf16String);
|
||||
|
||||
// Next, convert to UTF-32
|
||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter2;
|
||||
return converter2.from_bytes(utf8String);
|
||||
|
||||
// This is inefficient, but importantly it is _correct_, rather than a hand-rolled UTF-16 to
|
||||
// UTF-32 converter which may or may not be correct.
|
||||
}
|
||||
|
||||
|
||||
} // end namespace gui
|
||||
} // end namespace irr
|
||||
|
@ -2,6 +2,7 @@
|
||||
CGUITTFont FreeType class for Irrlicht
|
||||
Copyright (c) 2009-2010 John Norman
|
||||
Copyright (c) 2016 Nathanaëlle Courant
|
||||
Copyright (c) 2023 Caleb Butler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
@ -35,7 +36,6 @@
|
||||
#include <ft2build.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <irrUString.h>
|
||||
#include "util/enriched_string.h"
|
||||
#include "util/basic_macros.h"
|
||||
#include FT_FREETYPE_H
|
||||
@ -289,11 +289,9 @@ namespace gui
|
||||
|
||||
//! Returns the dimension of a text string.
|
||||
virtual core::dimension2d<u32> getDimension(const wchar_t* text) const;
|
||||
virtual core::dimension2d<u32> getDimension(const core::ustring& text) const;
|
||||
|
||||
//! Calculates the index of the character in the text which is on a specific position.
|
||||
virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const;
|
||||
virtual s32 getCharacterFromPos(const core::ustring& text, s32 pixel_x) const;
|
||||
|
||||
//! Sets global kerning width for the font.
|
||||
virtual void setKerningWidth(s32 kerning);
|
||||
@ -303,14 +301,13 @@ namespace gui
|
||||
|
||||
//! Gets kerning values (distance between letters) for the font. If no parameters are provided,
|
||||
virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const;
|
||||
virtual s32 getKerningWidth(const uchar32_t thisLetter=0, const uchar32_t previousLetter=0) const;
|
||||
virtual s32 getKerningWidth(const char32_t thisLetter=0, const char32_t previousLetter=0) const;
|
||||
|
||||
//! Returns the distance between letters
|
||||
virtual s32 getKerningHeight() const;
|
||||
|
||||
//! Define which characters should not be drawn by the font.
|
||||
virtual void setInvisibleCharacters(const wchar_t *s);
|
||||
virtual void setInvisibleCharacters(const core::ustring& s);
|
||||
|
||||
//! Get the last glyph page if there's still available slots.
|
||||
//! If not, it will return zero.
|
||||
@ -330,7 +327,7 @@ namespace gui
|
||||
//! Create corresponding character's software image copy from the font,
|
||||
//! so you can use this data just like any ordinary video::IImage.
|
||||
//! \param ch The character you need
|
||||
virtual video::IImage* createTextureFromChar(const uchar32_t& ch);
|
||||
virtual video::IImage* createTextureFromChar(const char32_t& ch);
|
||||
|
||||
//! This function is for debugging mostly. If the page doesn't exist it returns zero.
|
||||
//! \param page_index Simply return the texture handle of a given page index.
|
||||
@ -360,6 +357,14 @@ namespace gui
|
||||
static scene::IMesh* shared_plane_ptr_;
|
||||
static scene::SMesh shared_plane_;
|
||||
|
||||
// Helper functions for the same-named public member functions above
|
||||
// (Since std::u32string is nicer to work with than wchar_t *)
|
||||
core::dimension2d<u32> getDimension(const std::u32string& text) const;
|
||||
s32 getCharacterFromPos(const std::u32string& text, s32 pixel_x) const;
|
||||
|
||||
// Helper function for the above helper functions :P
|
||||
std::u32string convertWCharToU32String(const wchar_t* const) const;
|
||||
|
||||
CGUITTFont(IGUIEnvironment *env);
|
||||
bool load(const io::path& filename, const u32 size, const bool antialias, const bool transparency);
|
||||
void reset_images();
|
||||
@ -374,13 +379,13 @@ namespace gui
|
||||
else load_flags |= FT_LOAD_TARGET_NORMAL;
|
||||
}
|
||||
u32 getWidthFromCharacter(wchar_t c) const;
|
||||
u32 getWidthFromCharacter(uchar32_t c) const;
|
||||
u32 getWidthFromCharacter(char32_t c) const;
|
||||
u32 getHeightFromCharacter(wchar_t c) const;
|
||||
u32 getHeightFromCharacter(uchar32_t c) const;
|
||||
u32 getHeightFromCharacter(char32_t c) const;
|
||||
u32 getGlyphIndexByChar(wchar_t c) const;
|
||||
u32 getGlyphIndexByChar(uchar32_t c) const;
|
||||
u32 getGlyphIndexByChar(char32_t c) const;
|
||||
core::vector2di getKerning(const wchar_t thisLetter, const wchar_t previousLetter) const;
|
||||
core::vector2di getKerning(const uchar32_t thisLetter, const uchar32_t previousLetter) const;
|
||||
core::vector2di getKerning(const char32_t thisLetter, const char32_t previousLetter) const;
|
||||
core::dimension2d<u32> getDimensionUntilEndOfLine(const wchar_t* p) const;
|
||||
|
||||
void createSharedPlane();
|
||||
@ -398,7 +403,7 @@ namespace gui
|
||||
|
||||
s32 GlobalKerningWidth;
|
||||
s32 GlobalKerningHeight;
|
||||
core::ustring Invisible;
|
||||
std::u32string Invisible;
|
||||
u32 shadow_offset;
|
||||
u32 shadow_alpha;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user