mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 13:36:13 +03:00
LibGfx: Pass font width to FontDatabase::get()
Width need to be passed to `FontDatabase::get()` to resolve font name unambiguously.
This commit is contained in:
parent
79006c03b4
commit
1f4106842d
Notes:
sideshowbarker
2024-07-17 00:46:13 +09:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/SerenityOS/serenity/commit/1f4106842d Pull-request: https://github.com/SerenityOS/serenity/pull/17311
@ -34,11 +34,11 @@ FontPluginQt::FontPluginQt()
|
||||
update_generic_fonts();
|
||||
|
||||
auto default_font_name = generic_font_name(Web::Platform::GenericFont::UiSansSerif);
|
||||
m_default_font = Gfx::FontDatabase::the().get(default_font_name, 12.0, 400, 0);
|
||||
m_default_font = Gfx::FontDatabase::the().get(default_font_name, 12.0, 400, Gfx::FontWidth::Normal, 0);
|
||||
VERIFY(m_default_font);
|
||||
|
||||
auto default_fixed_width_font_name = generic_font_name(Web::Platform::GenericFont::UiMonospace);
|
||||
m_default_fixed_width_font = Gfx::FontDatabase::the().get(default_fixed_width_font_name, 12.0, 400, 0);
|
||||
m_default_fixed_width_font = Gfx::FontDatabase::the().get(default_fixed_width_font_name, 12.0, 400, Gfx::FontWidth::Normal, 0);
|
||||
VERIFY(m_default_fixed_width_font);
|
||||
}
|
||||
|
||||
@ -73,10 +73,10 @@ void FontPluginQt::update_generic_fonts()
|
||||
QFontInfo qt_info(qt_font);
|
||||
auto qt_font_family = qt_info.family();
|
||||
|
||||
auto gfx_font = Gfx::FontDatabase::the().get(qt_font_family.toUtf8().data(), 16, 400, 0, Gfx::Font::AllowInexactSizeMatch::Yes);
|
||||
auto gfx_font = Gfx::FontDatabase::the().get(qt_font_family.toUtf8().data(), 16, 400, Gfx::FontWidth::Normal, 0, Gfx::Font::AllowInexactSizeMatch::Yes);
|
||||
if (!gfx_font) {
|
||||
for (auto& fallback : fallbacks) {
|
||||
gfx_font = Gfx::FontDatabase::the().get(fallback, 16, 400, 0, Gfx::Font::AllowInexactSizeMatch::Yes);
|
||||
gfx_font = Gfx::FontDatabase::the().get(fallback, 16, 400, Gfx::FontWidth::Normal, 0, Gfx::Font::AllowInexactSizeMatch::Yes);
|
||||
if (gfx_font)
|
||||
break;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ TEST_CASE(test_fontdatabase_get)
|
||||
{
|
||||
Gfx::FontDatabase::set_default_fonts_lookup_path(TEST_INPUT(""));
|
||||
auto& font_database = Gfx::FontDatabase::the();
|
||||
EXPECT(!font_database.get("Family", 12, 400, 0)->name().is_null());
|
||||
EXPECT(!font_database.get("Family", 12, 400, Gfx::FontWidth::Normal, 0)->name().is_null());
|
||||
}
|
||||
|
||||
TEST_CASE(test_fontdatabase_for_each_font)
|
||||
|
@ -409,7 +409,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
auto adjust_font_size = [&](float adjustment) {
|
||||
auto& font = terminal->font();
|
||||
auto new_size = max(5, font.presentation_size() + adjustment);
|
||||
if (auto new_font = Gfx::FontDatabase::the().get(font.family(), new_size, font.weight(), font.slope())) {
|
||||
if (auto new_font = Gfx::FontDatabase::the().get(font.family(), new_size, font.weight(), font.width(), font.slope())) {
|
||||
terminal->set_font_and_resize_to_fit(*new_font);
|
||||
terminal->apply_size_increments_to_window(*window);
|
||||
window->resize(terminal->size());
|
||||
|
@ -638,7 +638,7 @@ void TextEditor::paint_event(PaintEvent& event)
|
||||
}
|
||||
auto font = unspanned_font;
|
||||
if (span.attributes.bold) {
|
||||
if (auto bold_font = Gfx::FontDatabase::the().get(font->family(), font->presentation_size(), 700, 0))
|
||||
if (auto bold_font = Gfx::FontDatabase::the().get(font->family(), font->presentation_size(), 700, font->width(), 0))
|
||||
font = bold_font;
|
||||
}
|
||||
draw_text_helper(span_start, span_end, font, span.attributes);
|
||||
|
@ -815,25 +815,25 @@ void Widget::set_font(Gfx::Font const* font)
|
||||
|
||||
void Widget::set_font_family(DeprecatedString const& family)
|
||||
{
|
||||
set_font(Gfx::FontDatabase::the().get(family, m_font->presentation_size(), m_font->weight(), m_font->slope()));
|
||||
set_font(Gfx::FontDatabase::the().get(family, m_font->presentation_size(), m_font->weight(), m_font->width(), m_font->slope()));
|
||||
}
|
||||
|
||||
void Widget::set_font_size(unsigned size)
|
||||
{
|
||||
set_font(Gfx::FontDatabase::the().get(m_font->family(), size, m_font->weight(), m_font->slope()));
|
||||
set_font(Gfx::FontDatabase::the().get(m_font->family(), size, m_font->weight(), m_font->width(), m_font->slope()));
|
||||
}
|
||||
|
||||
void Widget::set_font_weight(unsigned weight)
|
||||
{
|
||||
set_font(Gfx::FontDatabase::the().get(m_font->family(), m_font->presentation_size(), weight, m_font->slope()));
|
||||
set_font(Gfx::FontDatabase::the().get(m_font->family(), m_font->presentation_size(), weight, m_font->width(), m_font->slope()));
|
||||
}
|
||||
|
||||
void Widget::set_font_fixed_width(bool fixed_width)
|
||||
{
|
||||
if (fixed_width)
|
||||
set_font(Gfx::FontDatabase::the().get(Gfx::FontDatabase::the().default_fixed_width_font().family(), m_font->presentation_size(), m_font->weight(), m_font->slope()));
|
||||
set_font(Gfx::FontDatabase::the().get(Gfx::FontDatabase::the().default_fixed_width_font().family(), m_font->presentation_size(), m_font->weight(), m_font->width(), m_font->slope()));
|
||||
else
|
||||
set_font(Gfx::FontDatabase::the().get(Gfx::FontDatabase::the().default_font().family(), m_font->presentation_size(), m_font->weight(), m_font->slope()));
|
||||
set_font(Gfx::FontDatabase::the().get(Gfx::FontDatabase::the().default_font().family(), m_font->presentation_size(), m_font->weight(), m_font->width(), m_font->slope()));
|
||||
}
|
||||
|
||||
void Widget::set_min_size(UISize const& size)
|
||||
|
@ -28,7 +28,7 @@ CoverWizardPage::CoverWizardPage()
|
||||
m_content_widget->layout()->set_margins(20);
|
||||
|
||||
m_header_label = m_content_widget->add<Label>();
|
||||
m_header_label->set_font(Gfx::FontDatabase::the().get("Pebbleton", 14, 700, 0));
|
||||
m_header_label->set_font(Gfx::FontDatabase::the().get("Pebbleton", 14, 700, Gfx::FontWidth::Normal, 0));
|
||||
m_header_label->set_text_alignment(Gfx::TextAlignment::TopLeft);
|
||||
m_header_label->set_fixed_height(48);
|
||||
|
||||
|
@ -385,7 +385,7 @@ Font const& Font::bold_variant() const
|
||||
{
|
||||
if (m_bold_variant)
|
||||
return *m_bold_variant;
|
||||
m_bold_variant = Gfx::FontDatabase::the().get(family(), presentation_size(), 700, 0);
|
||||
m_bold_variant = Gfx::FontDatabase::the().get(family(), presentation_size(), 700, Gfx::FontWidth::Normal, 0);
|
||||
if (!m_bold_variant)
|
||||
m_bold_variant = this;
|
||||
return *m_bold_variant;
|
||||
|
@ -44,6 +44,8 @@ public:
|
||||
|
||||
virtual float pixel_size() const override { return m_glyph_height; }
|
||||
|
||||
u16 width() const override { return FontWidth::Normal; }
|
||||
|
||||
u16 weight() const override { return m_weight; }
|
||||
void set_weight(u16 weight) { m_weight = weight; }
|
||||
|
||||
|
@ -127,6 +127,19 @@ struct FontPixelMetrics {
|
||||
float line_spacing() const { return ascent + descent + line_gap; }
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass
|
||||
enum FontWidth {
|
||||
UltraCondensed = 1,
|
||||
ExtraCondensed = 2,
|
||||
Condensed = 3,
|
||||
SemiCondensed = 4,
|
||||
Normal = 5,
|
||||
SemiExpanded = 6,
|
||||
Expanded = 7,
|
||||
ExtraExpanded = 8,
|
||||
UltraExpanded = 9
|
||||
};
|
||||
|
||||
class Font : public RefCounted<Font> {
|
||||
public:
|
||||
enum class AllowInexactSizeMatch {
|
||||
@ -144,6 +157,8 @@ public:
|
||||
virtual float pixel_size() const = 0;
|
||||
virtual u8 slope() const = 0;
|
||||
|
||||
virtual u16 width() const = 0;
|
||||
|
||||
virtual u16 weight() const = 0;
|
||||
virtual Glyph glyph(u32 code_point) const = 0;
|
||||
virtual Glyph glyph(u32 code_point, GlyphSubpixelOffset) const = 0;
|
||||
|
@ -206,7 +206,7 @@ RefPtr<Gfx::Font> FontDatabase::get_by_name(StringView name)
|
||||
auto weight = parts.take_last().to_int().value_or(0);
|
||||
auto size = parts.take_last().to_int().value_or(0);
|
||||
auto family = DeprecatedString::join(' ', parts);
|
||||
return get(family, size, weight, slope);
|
||||
return get(family, size, weight, Gfx::FontWidth::Normal, slope);
|
||||
}
|
||||
dbgln("Font lookup failed: '{}'", name);
|
||||
return nullptr;
|
||||
@ -214,13 +214,13 @@ RefPtr<Gfx::Font> FontDatabase::get_by_name(StringView name)
|
||||
return it->value;
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Font> FontDatabase::get(DeprecatedFlyString const& family, float point_size, unsigned weight, unsigned slope, Font::AllowInexactSizeMatch allow_inexact_size_match)
|
||||
RefPtr<Gfx::Font> FontDatabase::get(DeprecatedFlyString const& family, float point_size, unsigned weight, unsigned width, unsigned slope, Font::AllowInexactSizeMatch allow_inexact_size_match)
|
||||
{
|
||||
auto it = m_private->typefaces.find(family);
|
||||
if (it == m_private->typefaces.end())
|
||||
return nullptr;
|
||||
for (auto const& typeface : it->value) {
|
||||
if (typeface->weight() == weight && typeface->slope() == slope)
|
||||
if (typeface->weight() == weight && typeface->width() == width && typeface->slope() == slope)
|
||||
return typeface->get_font(point_size, allow_inexact_size_match);
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
static void set_fixed_width_font_query(DeprecatedString);
|
||||
static void set_default_fonts_lookup_path(DeprecatedString);
|
||||
|
||||
RefPtr<Gfx::Font> get(DeprecatedFlyString const& family, float point_size, unsigned weight, unsigned slope, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No);
|
||||
RefPtr<Gfx::Font> get(DeprecatedFlyString const& family, float point_size, unsigned weight, unsigned width, unsigned slope, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No);
|
||||
RefPtr<Gfx::Font> get(DeprecatedFlyString const& family, DeprecatedFlyString const& variant, float point_size, Font::AllowInexactSizeMatch = Font::AllowInexactSizeMatch::No);
|
||||
RefPtr<Gfx::Font> get_by_name(StringView);
|
||||
void for_each_font(Function<void(Gfx::Font const&)>);
|
||||
|
@ -650,6 +650,15 @@ u16 Font::weight() const
|
||||
return 400;
|
||||
}
|
||||
|
||||
u16 Font::width() const
|
||||
{
|
||||
if (m_os2.has_value()) {
|
||||
return m_os2->width_class();
|
||||
}
|
||||
|
||||
return Gfx::FontWidth::Normal;
|
||||
}
|
||||
|
||||
u8 Font::slope() const
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/typography/opentype/spec/os2
|
||||
@ -680,6 +689,11 @@ u16 OS2::weight_class() const
|
||||
return header().us_weight_class;
|
||||
}
|
||||
|
||||
u16 OS2::width_class() const
|
||||
{
|
||||
return header().us_width_class;
|
||||
}
|
||||
|
||||
u16 OS2::selection() const
|
||||
{
|
||||
return header().fs_selection;
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
virtual DeprecatedString family() const override;
|
||||
virtual DeprecatedString variant() const override;
|
||||
virtual u16 weight() const override;
|
||||
virtual u16 width() const override;
|
||||
virtual u8 slope() const override;
|
||||
virtual bool is_fixed_width() const override;
|
||||
|
||||
|
@ -231,6 +231,7 @@ private:
|
||||
class OS2 {
|
||||
public:
|
||||
u16 weight_class() const;
|
||||
u16 width_class() const;
|
||||
u16 selection() const;
|
||||
i16 typographic_ascender() const;
|
||||
i16 typographic_descender() const;
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
virtual float pixel_size() const override { return m_point_height * 1.33333333f; }
|
||||
virtual Gfx::FontPixelMetrics pixel_metrics() const override;
|
||||
virtual u8 slope() const override { return m_font->slope(); }
|
||||
virtual u16 width() const override { return m_font->width(); }
|
||||
virtual u16 weight() const override { return m_font->weight(); }
|
||||
virtual Gfx::Glyph glyph(u32 code_point) const override;
|
||||
virtual float glyph_left_bearing(u32 code_point) const override;
|
||||
|
@ -19,6 +19,16 @@ unsigned Typeface::weight() const
|
||||
return m_vector_font->weight();
|
||||
}
|
||||
|
||||
unsigned Typeface::width() const
|
||||
{
|
||||
VERIFY(m_vector_font || m_bitmap_fonts.size() > 0);
|
||||
|
||||
if (is_fixed_size())
|
||||
return Gfx::FontWidth::Normal;
|
||||
|
||||
return m_vector_font->width();
|
||||
}
|
||||
|
||||
u8 Typeface::slope() const
|
||||
{
|
||||
VERIFY(m_vector_font || m_bitmap_fonts.size() > 0);
|
||||
|
@ -27,6 +27,7 @@ public:
|
||||
DeprecatedFlyString const& family() const { return m_family; }
|
||||
DeprecatedFlyString const& variant() const { return m_variant; }
|
||||
unsigned weight() const;
|
||||
unsigned width() const;
|
||||
u8 slope() const;
|
||||
|
||||
bool is_fixed_width() const;
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
virtual DeprecatedString family() const = 0;
|
||||
virtual DeprecatedString variant() const = 0;
|
||||
virtual u16 weight() const = 0;
|
||||
virtual u16 width() const = 0;
|
||||
virtual u8 slope() const = 0;
|
||||
virtual bool is_fixed_width() const = 0;
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ public:
|
||||
virtual DeprecatedString family() const override { return m_input_font->family(); }
|
||||
virtual DeprecatedString variant() const override { return m_input_font->variant(); }
|
||||
virtual u16 weight() const override { return m_input_font->weight(); }
|
||||
virtual u16 width() const override { return m_input_font->width(); }
|
||||
virtual u8 slope() const override { return m_input_font->slope(); }
|
||||
virtual bool is_fixed_width() const override { return m_input_font->is_fixed_width(); }
|
||||
|
||||
|
@ -998,6 +998,8 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||
auto font_style = style.property(CSS::PropertyID::FontStyle);
|
||||
auto font_weight = style.property(CSS::PropertyID::FontWeight);
|
||||
|
||||
int width = Gfx::FontWidth::Normal;
|
||||
|
||||
int weight = Gfx::FontWeight::Regular;
|
||||
if (font_weight->is_identifier()) {
|
||||
switch (static_cast<IdentifierStyleValue const&>(*font_weight).id()) {
|
||||
@ -1133,7 +1135,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||
|
||||
auto find_font = [&](DeprecatedString const& family) -> RefPtr<Gfx::Font> {
|
||||
float font_size_in_pt = font_size_in_px * 0.75f;
|
||||
font_selector = { family, font_size_in_pt, weight, slope };
|
||||
font_selector = { family, font_size_in_pt, weight, width, slope };
|
||||
|
||||
if (auto it = m_loaded_fonts.find(family); it != m_loaded_fonts.end()) {
|
||||
auto& loader = *it->value;
|
||||
@ -1144,7 +1146,7 @@ void StyleComputer::compute_font(StyleProperties& style, DOM::Element const* ele
|
||||
if (auto found_font = FontCache::the().get(font_selector))
|
||||
return found_font;
|
||||
|
||||
if (auto found_font = Gfx::FontDatabase::the().get(family, font_size_in_pt, weight, slope, Gfx::Font::AllowInexactSizeMatch::Yes))
|
||||
if (auto found_font = Gfx::FontDatabase::the().get(family, font_size_in_pt, weight, width, slope, Gfx::Font::AllowInexactSizeMatch::Yes))
|
||||
return found_font;
|
||||
|
||||
return {};
|
||||
|
@ -16,11 +16,12 @@ struct FontSelector {
|
||||
DeprecatedFlyString family;
|
||||
float point_size { 0 };
|
||||
int weight { 0 };
|
||||
int width { 0 };
|
||||
int slope { 0 };
|
||||
|
||||
bool operator==(FontSelector const& other) const
|
||||
{
|
||||
return family == other.family && point_size == other.point_size && weight == other.weight && slope == other.slope;
|
||||
return family == other.family && point_size == other.point_size && weight == other.weight && width == other.width && slope == other.slope;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user