瀏覽代碼

LibWeb: Handle CSS "ch" length unit (mostly)

This isn't 100% spec complaint, as it should use glyph_height()
depending on what the value of the writing-mode is, but we haven't
implemented it yet, so I think it'll be good enough for now.

This can be tested in https://wpt.live/css/css-values/ch-unit-008.html
Other css-unit tests fail as:
- 001 shows an issue related to a renderer (looks to me like you can't
  pass a width and height property to a span -- adding `display: block`
  to it passes the test),
- 002-004 and 009-012 use mentioned writing-mode,
- 016-017 loads custom fonts, which we also don't support (yet).
Karol Kosek 4 年之前
父節點
當前提交
ffa7da0ca5

+ 5 - 0
Userland/Libraries/LibWeb/CSS/Length.cpp

@@ -21,6 +21,9 @@ float Length::relative_length_to_px(const Layout::Node& layout_node) const
         return m_value * layout_node.font().x_height();
     case Type::Em:
         return m_value * layout_node.font_size();
+    case Type::Ch:
+        // FIXME: Use layout_node.font().glyph_height() when writing-mode is not horizontal-tb (it has to be implemented first)
+        return m_value * (layout_node.font().glyph_width('0') + layout_node.font().glyph_spacing());
     case Type::Rem:
         return m_value * layout_node.document().document_element()->layout_node()->font_size();
     case Type::Vw:
@@ -180,6 +183,8 @@ const char* Length::unit_name() const
         return "ex";
     case Type::Em:
         return "em";
+    case Type::Ch:
+        return "ch";
     case Type::Rem:
         return "rem";
     case Type::Auto:

+ 2 - 0
Userland/Libraries/LibWeb/CSS/Length.h

@@ -27,6 +27,7 @@ public:
         Pc,
         Ex,
         Em,
+        Ch,
         Rem,
         Vh,
         Vw,
@@ -93,6 +94,7 @@ public:
     {
         return m_type == Type::Ex
             || m_type == Type::Em
+            || m_type == Type::Ch
             || m_type == Type::Rem
             || m_type == Type::Vh
             || m_type == Type::Vw

+ 2 - 0
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -1466,6 +1466,8 @@ Optional<Length> Parser::parse_length(ParsingContext const& context, StyleCompon
             type = Length::Type::Em;
         } else if (unit_string.equals_ignoring_case("ex")) {
             type = Length::Type::Ex;
+        } else if (unit_string.equals_ignoring_case("ch")) {
+            type = Length::Type::Ch;
         } else if (unit_string.equals_ignoring_case("vw")) {
             type = Length::Type::Vw;
         } else if (unit_string.equals_ignoring_case("vh")) {