titlescreen: make drop cap algorithm utf8 aware (#9122)

* make drop caps utf8 aware and use locale's script font

1. Uses utf8::insert to modify the string so that it works for non-ASCII characters.
2. Use the locale's script font from data/hardwired/fonts.cfg instead of using Oldania always.

* make the algorithm work for multiple start tags in the tip text

* update condition to prevent throwing exception and don't use utf8::size

* adds comment that the tags do not have multibyte characters
This commit is contained in:
Subhraman Sarkar 2024-07-25 08:40:30 +05:30 committed by GitHub
parent 6cb9cbeca8
commit d47466dfc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -19,6 +19,7 @@
#include "addon/manager_ui.hpp"
#include "filesystem.hpp"
#include "font/font_config.hpp"
#include "formula/string_utils.hpp"
#include "game_config.hpp"
#include "game_config_manager.hpp"
@ -53,6 +54,7 @@
#include "gui/widgets/window.hpp"
#include "help/help.hpp"
#include "sdl/surface.hpp"
#include "serialization/unicode.hpp"
#include "video.hpp"
#include <algorithm>
@ -204,26 +206,23 @@ void title_screen::init_callbacks()
widget["use_markup"] = "true";
//
// Use pango markup to insert drop cap
//
if (tip.text().str().substr(0,1) != "<") {
// Example: Lawful units -> <span ...>L</span>awful units
widget["label"] = "<span font_family='OldaniaADFStd' font_size='xx-large'>" + tip.text().str().substr(0,1) + "</span>" + tip.text().str().substr(1);
} else {
// Tip starts with a tag, so we need to insert the <span> after it
// then insert the </span> tag after the first character of the text
// after markup. Example:
// <i>Lawful</i> units -> <i><span ...>L</span>awful</i> units
std::size_t id = tip.text().str().find_first_of(">") + 1;
std::stringstream tip_text;
tip_text << tip.text().str().substr(0,id) // existing start tag
<< "<span font_family='OldaniaADFStd' font_size='xx-large'>" // span start tag
<< tip.text().str().substr(id,1) // first character
<< "</span>" // span end tag
<< tip.text().str().substr(id+1); // rest of the text
widget["label"] = tip_text.str();
// Example: Lawful units -> <span ...>L</span>awful units
// If tip starts with a tag, we need to insert the <span> after it
// then insert the </span> tag after the first character of the text
// after markup. Assumes that the tags themselves don't
// contain non-ASCII characters.
// Example: <i>Lawful</i> units -> <i><span ...>L</span>awful</i> units
const std::string& script_font = font::get_font_families(font::FONT_SCRIPT);
std::string tip_text = tip.text().str();
std::size_t pos = 0;
while (pos < tip_text.size() && tip_text.at(pos) == '<') {
pos = tip_text.find_first_of(">", pos) + 1;
}
utf8::insert(tip_text, pos+1, "</span>");
utf8::insert(tip_text, pos, "<span font_family='" + script_font + "' font_size='xx-large'>");
widget["label"] = tip_text;
page.emplace("tip", widget);