diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-10-06 11:23:58 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-06 11:26:34 +0200 |
commit | b9557bf8766f6c94aee541418d040dae3e8bb599 (patch) | |
tree | a37b541711f4eba2b6e966c33f37d1cd634f2299 | |
parent | c8e5039418e2e02537a2b9f107307537e57355ff (diff) | |
download | serenity-b9557bf8766f6c94aee541418d040dae3e8bb599.zip |
LibHTML: Move font loading from LayoutText to StyleProperties
Since LayoutText inherits all of its style information from its parent
Element anyway, it makes more sense to load the font at a higher level.
And since the font depends only on the style and nothing else, this
patch moves font loading (and caching) into StyleProperties. This could
be made a lot smarter to avoid loading the same font many times, etc.
-rw-r--r-- | Libraries/LibHTML/CSS/StyleProperties.cpp | 54 | ||||
-rw-r--r-- | Libraries/LibHTML/CSS/StyleProperties.h | 12 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutText.cpp | 67 | ||||
-rw-r--r-- | Libraries/LibHTML/Layout/LayoutText.h | 5 |
4 files changed, 72 insertions, 66 deletions
diff --git a/Libraries/LibHTML/CSS/StyleProperties.cpp b/Libraries/LibHTML/CSS/StyleProperties.cpp index 754af996d6..56e4b2ae74 100644 --- a/Libraries/LibHTML/CSS/StyleProperties.cpp +++ b/Libraries/LibHTML/CSS/StyleProperties.cpp @@ -1,4 +1,6 @@ +#include <LibCore/CDirIterator.h> #include <LibHTML/CSS/StyleProperties.h> +#include <ctype.h> void StyleProperties::set_property(const String& name, NonnullRefPtr<StyleValue> value) { @@ -36,3 +38,55 @@ Color StyleProperties::color_or_fallback(const StringView& property_name, const return fallback; return value.value()->to_color(document); } + +void StyleProperties::load_font() const +{ + auto font_family = string_or_fallback("font-family", "Katica"); + auto font_weight = string_or_fallback("font-weight", "normal"); + + String weight; + if (font_weight == "lighter") + weight = "Thin"; + else if (font_weight == "normal") + weight = ""; + else if (font_weight == "bold") + weight = "Bold"; + else + ASSERT_NOT_REACHED(); + + auto look_for_file = [](const StringView& expected_name) -> String { + // TODO: handle font sizes properly? + CDirIterator it { "/res/fonts/", CDirIterator::Flags::SkipDots }; + while (it.has_next()) { + String name = it.next_path(); + ASSERT(name.ends_with(".font")); + if (!name.starts_with(expected_name)) + continue; + + // Check that a numeric size immediately + // follows the font name. This prevents, + // for example, matching KaticaBold when + // the regular Katica is requested. + if (!isdigit(name[expected_name.length()])) + continue; + + return name; + } + return {}; + }; + + String file_name = look_for_file(String::format("%s%s", font_family.characters(), weight.characters())); + if (file_name.is_null() && weight == "") + file_name = look_for_file(String::format("%sRegular", font_family.characters())); + + if (file_name.is_null()) { + dbg() << "Failed to find a font for family " << font_family << " weight " << font_weight; + ASSERT_NOT_REACHED(); + } + +#ifdef HTML_DEBUG + dbg() << "Found font " << file_name << " for family " << font_family << " weight " << font_weight; +#endif + + m_font = Font::load_from_file(String::format("/res/fonts/%s", file_name.characters())); +} diff --git a/Libraries/LibHTML/CSS/StyleProperties.h b/Libraries/LibHTML/CSS/StyleProperties.h index 3fbb8ab1db..4a551a8c5f 100644 --- a/Libraries/LibHTML/CSS/StyleProperties.h +++ b/Libraries/LibHTML/CSS/StyleProperties.h @@ -2,6 +2,7 @@ #include <AK/HashMap.h> #include <AK/NonnullRefPtr.h> +#include <LibDraw/Font.h> #include <LibHTML/CSS/StyleValue.h> class Color; @@ -24,6 +25,17 @@ public: String string_or_fallback(const StringView& property_name, const StringView& fallback) const; Color color_or_fallback(const StringView& property_name, const Document&, Color fallback) const; + const Font& font() const + { + if (!m_font) + load_font(); + return *m_font; + } + private: HashMap<String, NonnullRefPtr<StyleValue>> m_property_values; + + void load_font() const; + + mutable RefPtr<Font> m_font; }; diff --git a/Libraries/LibHTML/Layout/LayoutText.cpp b/Libraries/LibHTML/Layout/LayoutText.cpp index 99d6c9e722..fd64c5b64c 100644 --- a/Libraries/LibHTML/Layout/LayoutText.cpp +++ b/Libraries/LibHTML/Layout/LayoutText.cpp @@ -17,59 +17,6 @@ LayoutText::~LayoutText() { } -void LayoutText::load_font() -{ - auto font_family = style().string_or_fallback("font-family", "Katica"); - auto font_weight = style().string_or_fallback("font-weight", "normal"); - - String weight; - if (font_weight == "lighter") - weight = "Thin"; - else if (font_weight == "normal") - weight = ""; - else if (font_weight == "bold") - weight = "Bold"; - else - ASSERT_NOT_REACHED(); - - auto look_for_file = [](const StringView& expected_name) -> String { - // TODO: handle font sizes properly? - CDirIterator it { "/res/fonts/", CDirIterator::Flags::SkipDots }; - while (it.has_next()) { - String name = it.next_path(); - ASSERT(name.ends_with(".font")); - if (!name.starts_with(expected_name)) - continue; - - // Check that a numeric size immediately - // follows the font name. This prevents, - // for example, matching KaticaBold when - // the regular Katica is requested. - if (!isdigit(name[expected_name.length()])) - continue; - - return name; - } - return {}; - }; - - String file_name = look_for_file(String::format("%s%s", font_family.characters(), weight.characters())); - if (file_name.is_null() && weight == "") - file_name = look_for_file(String::format("%sRegular", font_family.characters())); - - if (file_name.is_null()) { - dbg() << "Failed to find a font for family " << font_family << " weight " << font_weight; - dbg() << "My text is " << node().data(); - ASSERT_NOT_REACHED(); - } - -#ifdef HTML_DEBUG - dbg() << "Found font " << file_name << " for family " << font_family << " weight " << font_weight; -#endif - - m_font = Font::load_from_file(String::format("/res/fonts/%s", file_name.characters())); -} - static bool is_all_whitespace(const String& string) { for (int i = 0; i < string.length(); ++i) { @@ -92,7 +39,7 @@ const String& LayoutText::text_for_style(const StyleProperties& style) const void LayoutText::render_fragment(RenderingContext& context, const LineBoxFragment& fragment) const { auto& painter = context.painter(); - painter.set_font(*m_font); + painter.set_font(style().font()); auto color = style().color_or_fallback("color", document(), Color::Black); auto text_decoration = style().string_or_fallback("text-decoration", "none"); @@ -174,12 +121,10 @@ void LayoutText::for_each_source_line(Callback callback) const void LayoutText::split_into_lines(LayoutBlock& container) { - if (!m_font) - load_font(); - - int space_width = m_font->glyph_width(' ') + m_font->glyph_spacing(); + auto& font = style().font(); + int space_width = font.glyph_width(' ') + font.glyph_spacing(); // FIXME: Allow overriding the line-height. We currently default to 140% which seems to look nice. - int line_height = (int)(m_font->glyph_height() * 1.4f); + int line_height = (int)(font.glyph_height() * 1.4f); auto& line_boxes = container.line_boxes(); if (line_boxes.is_empty()) @@ -189,7 +134,7 @@ void LayoutText::split_into_lines(LayoutBlock& container) bool is_preformatted = style().string_or_fallback("white-space", "normal") == "pre"; if (is_preformatted) { for_each_source_line([&](const Utf8View& view, int start, int length) { - line_boxes.last().add_fragment(*this, start, length, m_font->width(view), line_height); + line_boxes.last().add_fragment(*this, start, length, font.width(view), line_height); line_boxes.append(LineBox()); }); return; @@ -215,7 +160,7 @@ void LayoutText::split_into_lines(LayoutBlock& container) if (is_whitespace) word_width = space_width; else - word_width = m_font->width(word.view) + m_font->glyph_spacing(); + word_width = font.width(word.view) + font.glyph_spacing(); if (word_width > available_width) { line_boxes.append(LineBox()); diff --git a/Libraries/LibHTML/Layout/LayoutText.h b/Libraries/LibHTML/Layout/LayoutText.h index 9a70eb23f8..9b70ecdc4c 100644 --- a/Libraries/LibHTML/Layout/LayoutText.h +++ b/Libraries/LibHTML/Layout/LayoutText.h @@ -3,7 +3,6 @@ #include <LibHTML/DOM/Text.h> #include <LibHTML/Layout/LayoutNode.h> -class Font; class LineBoxFragment; class LayoutText : public LayoutNode { @@ -29,8 +28,4 @@ private: void for_each_word(Callback) const; template<typename Callback> void for_each_source_line(Callback) const; - - void load_font(); - - RefPtr<Font> m_font; }; |