summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-10-06 11:23:58 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-10-06 11:26:34 +0200
commitb9557bf8766f6c94aee541418d040dae3e8bb599 (patch)
treea37b541711f4eba2b6e966c33f37d1cd634f2299
parentc8e5039418e2e02537a2b9f107307537e57355ff (diff)
downloadserenity-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.cpp54
-rw-r--r--Libraries/LibHTML/CSS/StyleProperties.h12
-rw-r--r--Libraries/LibHTML/Layout/LayoutText.cpp67
-rw-r--r--Libraries/LibHTML/Layout/LayoutText.h5
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;
};