diff --git a/Libraries/LibWeb/CSS/Parser/CSSParser.cpp b/Libraries/LibWeb/CSS/Parser/CSSParser.cpp index 991a9858ad..88780b6f1b 100644 --- a/Libraries/LibWeb/CSS/Parser/CSSParser.cpp +++ b/Libraries/LibWeb/CSS/Parser/CSSParser.cpp @@ -454,6 +454,16 @@ static Optional value_id_from_string(const String& string) return CSS::ValueID::LineThrough; if (string.equals_ignoring_case("blink")) return CSS::ValueID::Blink; + if (string.equals_ignoring_case("capitalize")) + return CSS::ValueID::Capitalize; + if (string.equals_ignoring_case("uppercase")) + return CSS::ValueID::Uppercase; + if (string.equals_ignoring_case("lowercase")) + return CSS::ValueID::Lowercase; + if (string.equals_ignoring_case("full-width")) + return CSS::ValueID::FullWidth; + if (string.equals_ignoring_case("full-size-kana")) + return CSS::ValueID::FullSizeKana; if (string.starts_with("-libweb-palette-", CaseSensitivity::CaseInsensitive)) return value_id_for_palette_string(string.substring_view(16, string.length() - 16)); return {}; diff --git a/Libraries/LibWeb/CSS/StyleProperties.cpp b/Libraries/LibWeb/CSS/StyleProperties.cpp index 6af5ef0084..a0ee588764 100644 --- a/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -430,4 +430,27 @@ Optional StyleProperties::text_decoration_line() const } } +Optional StyleProperties::text_transform() const +{ + auto value = property(CSS::PropertyID::TextTransform); + if (!value.has_value()) + return {}; + switch (value.value()->to_identifier()) { + case CSS::ValueID::None: + return CSS::TextTransform::None; + case CSS::ValueID::Lowercase: + return CSS::TextTransform::Lowercase; + case CSS::ValueID::Uppercase: + return CSS::TextTransform::Uppercase; + case CSS::ValueID::Capitalize: + return CSS::TextTransform::Capitalize; + case CSS::ValueID::FullWidth: + return CSS::TextTransform::FullWidth; + case CSS::ValueID::FullSizeKana: + return CSS::TextTransform::FullSizeKana; + default: + return {}; + } +} + } diff --git a/Libraries/LibWeb/CSS/StyleProperties.h b/Libraries/LibWeb/CSS/StyleProperties.h index 78330438ba..4273edea35 100644 --- a/Libraries/LibWeb/CSS/StyleProperties.h +++ b/Libraries/LibWeb/CSS/StyleProperties.h @@ -67,6 +67,7 @@ public: Optional white_space() const; Optional line_style(CSS::PropertyID) const; Optional text_decoration_line() const; + Optional text_transform() const; const Gfx::Font& font() const { diff --git a/Libraries/LibWeb/CSS/StyleValue.h b/Libraries/LibWeb/CSS/StyleValue.h index 8cf2dd47de..6523ff1a7b 100644 --- a/Libraries/LibWeb/CSS/StyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValue.h @@ -151,6 +151,11 @@ enum class ValueID { Overline, LineThrough, Blink, + Capitalize, + Uppercase, + Lowercase, + FullWidth, + FullSizeKana, }; enum class Position { @@ -177,6 +182,15 @@ enum class TextDecorationLine { Blink, }; +enum class TextTransform { + None, + Capitalize, + Uppercase, + Lowercase, + FullWidth, + FullSizeKana, +}; + enum class Display { None, Block, diff --git a/Libraries/LibWeb/Layout/LayoutStyle.h b/Libraries/LibWeb/Layout/LayoutStyle.h index 2c0b077ede..622fd67b40 100644 --- a/Libraries/LibWeb/Layout/LayoutStyle.h +++ b/Libraries/LibWeb/Layout/LayoutStyle.h @@ -40,6 +40,7 @@ public: static CSS::TextAlign text_align() { return CSS::TextAlign::Left; } static CSS::Position position() { return CSS::Position::Static; } static CSS::TextDecorationLine text_decoration_line() { return CSS::TextDecorationLine::None; } + static CSS::TextTransform text_transform() { return CSS::TextTransform::None; } }; struct BorderData { @@ -56,6 +57,7 @@ public: Optional z_index() const { return m_z_index; } CSS::TextAlign text_align() const { return m_text_align; } CSS::TextDecorationLine text_decoration_line() const { return m_text_decoration_line; } + CSS::TextTransform text_transform() const { return m_text_transform; } CSS::Position position() const { return m_position; } CSS::WhiteSpace white_space() const { return m_white_space; } const CSS::Length& width() const { return m_width; } @@ -80,6 +82,7 @@ protected: Optional m_z_index; CSS::TextAlign m_text_align { InitialValues::text_align() }; CSS::TextDecorationLine m_text_decoration_line { InitialValues::text_decoration_line() }; + CSS::TextTransform m_text_transform { InitialValues::text_transform() }; CSS::Position m_position { InitialValues::position() }; CSS::WhiteSpace m_white_space { InitialValues::white_space() }; CSS::Length m_width; @@ -107,6 +110,7 @@ public: void set_z_index(Optional value) { m_z_index = value; } void set_text_align(CSS::TextAlign text_align) { m_text_align = text_align; } void set_text_decoration_line(CSS::TextDecorationLine value) { m_text_decoration_line = value; } + void set_text_transform(CSS::TextTransform value) { m_text_transform = value; } void set_position(CSS::Position position) { m_position = position; } void set_white_space(CSS::WhiteSpace value) { m_white_space = value; } void set_width(const CSS::Length& width) { m_width = width; } diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index adf13069a6..bb1f62bab5 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -243,6 +243,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) if (text_decoration_line.has_value()) style.set_text_decoration_line(text_decoration_line.value()); + auto text_transform = specified_style.text_transform(); + if (text_transform.has_value()) + style.set_text_transform(text_transform.value()); + style.set_z_index(specified_style.z_index()); style.set_width(specified_style.length_or_fallback(CSS::PropertyID::Width, {})); style.set_min_width(specified_style.length_or_fallback(CSS::PropertyID::MinWidth, {})); diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index 8b241022b8..472c1bb4db 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -89,10 +89,10 @@ void TextNode::paint_fragment(PaintContext& context, const LineBoxFragment& frag // FIXME: text-transform should be done already in layout, since uppercase glyphs may be wider than lowercase, etc. auto text = m_text_for_rendering; - auto text_transform = specified_style().string_or_fallback(CSS::PropertyID::TextTransform, "none"); - if (text_transform == "uppercase") + auto text_transform = style().text_transform(); + if (text_transform == CSS::TextTransform::Uppercase) text = m_text_for_rendering.to_uppercase(); - if (text_transform == "lowercase") + if (text_transform == CSS::TextTransform::Lowercase) text = m_text_for_rendering.to_lowercase(); painter.draw_text(enclosing_int_rect(fragment.absolute_rect()), text.substring_view(fragment.start(), fragment.length()), Gfx::TextAlignment::CenterLeft, color);