Revert: "Change: Support side-by-side fallback FontCaches instead of hierarchical. (#13303)"
This reverts commit 1829f7926d.
This commit is contained in:
@@ -11,9 +11,6 @@
|
||||
#include "gfx_layout_icu.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "gfx_func.h"
|
||||
#include "gfx_layout_fallback.h"
|
||||
#include "string_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "language.h"
|
||||
#include "table/control_codes.h"
|
||||
@@ -43,7 +40,7 @@ public:
|
||||
int length; ///< Length of the run in the buffer.
|
||||
UBiDiLevel level; ///< Embedding level of the run.
|
||||
UScriptCode script; ///< Script of the run.
|
||||
Font font; ///< Font of the run.
|
||||
Font *font; ///< Font of the run.
|
||||
|
||||
std::vector<GlyphID> glyphs; ///< The glyphs of the run. Valid after Shape() is called.
|
||||
std::vector<int> advance; ///< The advance (width) of the glyphs. Valid after Shape() is called.
|
||||
@@ -51,10 +48,9 @@ public:
|
||||
std::vector<ParagraphLayouter::Position> positions; ///< The positions of the glyphs. Valid after Shape() is called.
|
||||
int total_advance = 0; ///< The total advance of the run. Valid after Shape() is called.
|
||||
|
||||
ICURun(int start, int length, UBiDiLevel level, UScriptCode script, const Font &font) : start(start), length(length), level(level), script(script), font(font) {}
|
||||
ICURun(int start, int length, UBiDiLevel level, UScriptCode script = USCRIPT_UNKNOWN, Font *font = nullptr) : start(start), length(length), level(level), script(script), font(font) {}
|
||||
|
||||
void Shape(UChar *buff, size_t length);
|
||||
void FallbackShape(UChar *buff);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -70,7 +66,7 @@ public:
|
||||
std::vector<int> glyph_to_char;
|
||||
|
||||
int total_advance;
|
||||
Font font;
|
||||
const Font *font;
|
||||
|
||||
public:
|
||||
ICUVisualRun(const ICURun &run, int x);
|
||||
@@ -79,8 +75,8 @@ public:
|
||||
std::span<const Position> GetPositions() const override { return this->positions; }
|
||||
std::span<const int> GetGlyphToCharMap() const override { return this->glyph_to_char; }
|
||||
|
||||
const Font &GetFont() const override { return this->font; }
|
||||
int GetLeading() const override { return GetCharacterHeight(this->font.GetFontCache().GetSize()); }
|
||||
const Font *GetFont() const override { return this->font; }
|
||||
int GetLeading() const override { return this->font->fc->GetHeight(); }
|
||||
int GetGlyphCount() const override { return this->glyphs.size(); }
|
||||
int GetAdvance() const { return this->total_advance; }
|
||||
};
|
||||
@@ -145,46 +141,6 @@ ICUParagraphLayout::ICUVisualRun::ICUVisualRun(const ICURun &run, int x) :
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually shape a run for built-in non-truetype fonts.
|
||||
* Similar to but not quite the same as \a UniscribeRun::FallbackShape.
|
||||
* @param buff The complete buffer of the run.
|
||||
*/
|
||||
void ICURun::FallbackShape(UChar *buff)
|
||||
{
|
||||
FontCache &fc = this->font.GetFontCache();
|
||||
|
||||
this->glyphs.reserve(this->length);
|
||||
this->glyph_to_char.reserve(this->length);
|
||||
|
||||
/* Read each UTF-16 character, mapping to an appropriate glyph. */
|
||||
for (int i = this->start; i < this->start + this->length; i += Utf16IsLeadSurrogate(buff[i]) ? 2 : 1) {
|
||||
char32_t c = Utf16DecodeChar(reinterpret_cast<uint16_t *>(buff + i));
|
||||
if (this->level & 1) c = SwapRtlPairedCharacters(c);
|
||||
this->glyphs.emplace_back(fc.MapCharToGlyph(c));
|
||||
this->glyph_to_char.push_back(i);
|
||||
}
|
||||
|
||||
/* Reverse the sequence if this run is RTL. */
|
||||
if (this->level & 1) {
|
||||
std::reverse(std::begin(this->glyphs), std::end(this->glyphs));
|
||||
std::reverse(std::begin(this->glyph_to_char), std::end(this->glyph_to_char));
|
||||
}
|
||||
|
||||
this->positions.reserve(this->glyphs.size());
|
||||
|
||||
/* Set positions of each glyph. */
|
||||
int y_offset = fc.GetGlyphYOffset();
|
||||
int advance = 0;
|
||||
for (const GlyphID glyph : this->glyphs) {
|
||||
int x_advance = fc.GetGlyphWidth(glyph);
|
||||
this->positions.emplace_back(advance, advance + x_advance - 1, y_offset);
|
||||
this->advance.push_back(x_advance);
|
||||
advance += x_advance;
|
||||
}
|
||||
this->total_advance = advance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shape a single run.
|
||||
*
|
||||
@@ -193,20 +149,7 @@ void ICURun::FallbackShape(UChar *buff)
|
||||
*/
|
||||
void ICURun::Shape(UChar *buff, size_t buff_length)
|
||||
{
|
||||
FontCache &fc = this->font.GetFontCache();
|
||||
|
||||
/* Make sure any former run is lost. */
|
||||
this->glyphs.clear();
|
||||
this->glyph_to_char.clear();
|
||||
this->positions.clear();
|
||||
this->advance.clear();
|
||||
|
||||
if (fc.IsBuiltInFont()) {
|
||||
this->FallbackShape(buff);
|
||||
return;
|
||||
}
|
||||
|
||||
auto hbfont = hb_ft_font_create_referenced(*(static_cast<const FT_Face *>(fc.GetOSHandle())));
|
||||
auto hbfont = hb_ft_font_create_referenced(*(static_cast<const FT_Face *>(font->fc->GetOSHandle())));
|
||||
/* Match the flags with how we render the glyphs. */
|
||||
hb_ft_font_set_load_flags(hbfont, GetFontAAState() ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO);
|
||||
|
||||
@@ -227,6 +170,12 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
||||
auto glyph_info = hb_buffer_get_glyph_infos(hbbuf, &glyph_count);
|
||||
auto glyph_pos = hb_buffer_get_glyph_positions(hbbuf, &glyph_count);
|
||||
|
||||
/* Make sure any former run is lost. */
|
||||
this->glyphs.clear();
|
||||
this->glyph_to_char.clear();
|
||||
this->positions.clear();
|
||||
this->advance.clear();
|
||||
|
||||
/* Reserve space, as we already know the size. */
|
||||
this->glyphs.reserve(glyph_count);
|
||||
this->glyph_to_char.reserve(glyph_count);
|
||||
@@ -234,12 +183,20 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
||||
this->advance.reserve(glyph_count);
|
||||
|
||||
/* Prepare the glyphs/position. ICUVisualRun will give the position an offset if needed. */
|
||||
int y_offset = fc.GetGlyphYOffset();
|
||||
hb_position_t advance = 0;
|
||||
for (unsigned int i = 0; i < glyph_count; i++) {
|
||||
int x_advance = glyph_pos[i].x_advance / FONT_SCALE;
|
||||
this->glyphs.push_back(glyph_info[i].codepoint);
|
||||
this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].x_offset / FONT_SCALE + advance + x_advance - 1, glyph_pos[i].y_offset / FONT_SCALE + y_offset);
|
||||
int x_advance;
|
||||
|
||||
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
|
||||
auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
|
||||
x_advance = this->font->fc->GetGlyphWidth(glyph);
|
||||
this->glyphs.push_back(glyph);
|
||||
this->positions.emplace_back(advance, advance + x_advance - 1, (this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
|
||||
} else {
|
||||
x_advance = glyph_pos[i].x_advance / FONT_SCALE;
|
||||
this->glyphs.push_back(glyph_info[i].codepoint);
|
||||
this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].x_offset / FONT_SCALE + advance + x_advance - 1, glyph_pos[i].y_offset / FONT_SCALE);
|
||||
}
|
||||
|
||||
this->glyph_to_char.push_back(glyph_info[i].cluster);
|
||||
this->advance.push_back(x_advance);
|
||||
@@ -323,7 +280,7 @@ std::vector<ICURun> ItemizeBidi(UChar *buff, size_t length)
|
||||
UBiDiLevel level;
|
||||
ubidi_getLogicalRun(ubidi, start_pos, &logical_pos, &level);
|
||||
|
||||
runs.emplace_back(start_pos, logical_pos - start_pos, level, USCRIPT_UNKNOWN, Font{});
|
||||
runs.emplace_back(start_pos, logical_pos - start_pos, level);
|
||||
}
|
||||
|
||||
assert(static_cast<size_t>(count) == runs.size());
|
||||
@@ -354,7 +311,7 @@ std::vector<ICURun> ItemizeScript(UChar *buff, size_t length, std::vector<ICURun
|
||||
int stop_pos = std::min(script_itemizer.getScriptEnd(), cur_run->start + cur_run->length);
|
||||
assert(stop_pos - cur_pos > 0);
|
||||
|
||||
runs.emplace_back(cur_pos, stop_pos - cur_pos, cur_run->level, script_itemizer.getScriptCode(), Font{});
|
||||
runs.emplace_back(cur_pos, stop_pos - cur_pos, cur_run->level, script_itemizer.getScriptCode());
|
||||
|
||||
if (stop_pos == cur_run->start + cur_run->length) cur_run++;
|
||||
cur_pos = stop_pos;
|
||||
@@ -402,6 +359,11 @@ std::vector<ICURun> ItemizeStyle(std::vector<ICURun> &runs_current, FontMap &fon
|
||||
/* Can't layout an empty string. */
|
||||
if (length == 0) return nullptr;
|
||||
|
||||
/* Can't layout our in-built sprite fonts. */
|
||||
for (auto const &[position, font] : font_mapping) {
|
||||
if (font->fc->IsBuiltInFont()) return nullptr;
|
||||
}
|
||||
|
||||
auto runs = ItemizeBidi(buff, length);
|
||||
runs = ItemizeScript(buff, length, runs);
|
||||
runs = ItemizeStyle(runs, font_mapping);
|
||||
|
||||
Reference in New Issue
Block a user