1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-27 22:24:28 +01:00

Revert: "Change: Support side-by-side fallback FontCaches instead of hierarchical. (#13303)"

This reverts commit 1829f7926d.
This commit is contained in:
Peter Nelson
2025-12-13 00:29:06 +00:00
committed by Peter Nelson
parent 973514adc3
commit b03347f00c
32 changed files with 480 additions and 783 deletions

View File

@@ -37,6 +37,21 @@
/** Cache of ParagraphLayout lines. */
std::unique_ptr<Layouter::LineCache> Layouter::linecache;
/** Cache of Font instances. */
Layouter::FontColourMap Layouter::fonts[FS_END];
/**
* Construct a new font.
* @param size The font size to use for this font.
* @param colour The colour to draw this font in.
*/
Font::Font(FontSize size, TextColour colour) :
fc(FontCache::Get(size)), colour(colour)
{
assert(size < FS_END);
}
/**
* Helper for getting a ParagraphLayouter of the given type.
*
@@ -56,7 +71,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s
const typename T::CharType *buffer_last = buff_begin + str.size() + 1;
typename T::CharType *buff = buff_begin;
FontMap &font_mapping = line.runs;
Font f{state.font_index, state.cur_colour};
Font *f = Layouter::GetFont(state.fontsize, state.cur_colour);
font_mapping.clear();
@@ -65,10 +80,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s
* whenever the font changes, and convert the wide characters into a format
* usable by ParagraphLayout.
*/
Utf8View view(str);
for (auto it = view.begin(); it != view.end(); /* nothing */) {
auto cur = it;
uint32_t c = *it++;
for (char32_t c : Utf8View(str)) {
if (c == '\0' || c == '\n') {
/* Caller should already have filtered out these characters. */
NOT_REACHED();
@@ -83,40 +95,19 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s
} else {
/* Filter out non printable characters */
if (!IsPrintable(c)) continue;
if (IsTextDirectionChar(c)) {
/* Filter out text direction characters that shouldn't be drawn, and
* will not be handled in the fallback case because they are mostly
* needed for RTL languages which need more proper shaping support. */
if constexpr (!T::SUPPORTS_RTL) continue;
buff += T::AppendToBuffer(buff, buffer_last, c);
if (buff >= buffer_last) break;
continue;
}
FontIndex font_index = FontCache::GetFontIndexForCharacter(state.fontsize, c);
if (font_index == INVALID_FONT_INDEX) {
font_index = FontCache::GetDefaultFontIndex(state.fontsize);
}
if (state.font_index == font_index) {
buff += T::AppendToBuffer(buff, buffer_last, c);
if (buff >= buffer_last) break;
continue;
}
/* This character goes in the next run so don't advance. */
state.font_index = font_index;
it = cur;
/* Filter out text direction characters that shouldn't be drawn, and
* will not be handled in the fallback case because they are mostly
* needed for RTL languages which need more proper shaping support. */
if (!T::SUPPORTS_RTL && IsTextDirectionChar(c)) continue;
buff += T::AppendToBuffer(buff, buffer_last, c);
if (buff >= buffer_last) break;
continue;
}
if (buff - buff_begin > 0 && (font_mapping.empty() || font_mapping.back().first != buff - buff_begin)) {
if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
font_mapping.emplace_back(buff - buff_begin, f);
}
f = {state.font_index, state.cur_colour};
f = Layouter::GetFont(state.fontsize, state.cur_colour);
}
/* Better safe than sorry. */
@@ -125,14 +116,6 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s
if (font_mapping.empty() || font_mapping.back().first != buff - buff_begin) {
font_mapping.emplace_back(buff - buff_begin, f);
}
if constexpr (!std::is_same_v<T, FallbackParagraphLayoutFactory>) {
/* Don't layout if all runs use a built-in font and we're not using the fallback layouter. */
if (std::ranges::all_of(font_mapping, [](const auto &i) { return i.second.GetFontCache().IsBuiltInFont(); })) {
return;
}
}
line.layout = T::GetParagraphLayout(buff_begin, buff, font_mapping);
line.state_after = state;
}
@@ -145,7 +128,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, std::string_view s
*/
Layouter::Layouter(std::string_view str, int maxw, FontSize fontsize) : string(str)
{
FontState state(TC_INVALID, fontsize, FontCache::GetDefaultFontIndex(fontsize));
FontState state(TC_INVALID, fontsize);
while (true) {
auto line_length = str.find_first_of('\n');
@@ -355,6 +338,18 @@ ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const
return -1;
}
/**
* Get a static font instance.
*/
Font *Layouter::GetFont(FontSize size, TextColour colour)
{
FontColourMap::iterator it = fonts[size].find(colour);
if (it != fonts[size].end()) return it->second.get();
fonts[size][colour] = std::make_unique<Font>(size, colour);
return fonts[size][colour].get();
}
/**
* Perform initialization of layout engine.
*/
@@ -367,9 +362,12 @@ void Layouter::Initialize()
/**
* Reset cached font information.
* @param size Font size to reset.
*/
void Layouter::ResetFontCache([[maybe_unused]] FontSize size)
void Layouter::ResetFontCache(FontSize size)
{
fonts[size].clear();
/* We must reset the linecache since it references the just freed fonts */
ResetLineCache();