mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-09 01:29:17 +00:00
LibWeb: Serialize more @font-face
descriptors
Adapt the existing `font-face-src-local-serialization.html` test into a more general test for these.
This commit is contained in:
parent
e43f3e4808
commit
c497e5f850
Notes:
github-actions[bot]
2024-10-02 15:37:27 +00:00
Author: https://github.com/AtkinsSJ
Commit: c497e5f850
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1599
5 changed files with 105 additions and 19 deletions
|
@ -0,0 +1,7 @@
|
||||||
|
@font-face { font-family: "a1"; src: local("xyz"); unicode-range: "U+0-10ffff"; }
|
||||||
|
@font-face { font-family: "b1"; unicode-range: "U+0-10ffff"; font-feature-settings: "aaaa", "bbbb" 0, "yyyy" 3, "zzzz"; }
|
||||||
|
@font-face { font-family: "b2"; unicode-range: "U+0-10ffff"; font-feature-settings: "aaaa" 3; }
|
||||||
|
@font-face { font-family: "c1"; unicode-range: "U+0-10ffff"; font-width: 62.5%; }
|
||||||
|
@font-face { font-family: "c2"; unicode-range: "U+0-10ffff"; font-width: 50%; }
|
||||||
|
@font-face { font-family: "c3"; unicode-range: "U+0-10ffff"; font-width: 62.5%; }
|
||||||
|
@font-face { font-family: "c4"; unicode-range: "U+0-10ffff"; font-width: 50%; }
|
|
@ -1 +0,0 @@
|
||||||
@font-face { font-family: "a1"; src: local("xyz"); unicode-range: "U+0-10ffff"; }
|
|
30
Tests/LibWeb/Text/input/css/font-face-serialization.html
Normal file
30
Tests/LibWeb/Text/input/css/font-face-serialization.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
let testCases = [
|
||||||
|
// src
|
||||||
|
// - local()
|
||||||
|
"@font-face { font-family: 'a1'; src: local('xyz'); }",
|
||||||
|
|
||||||
|
// font-feature-settings is sorted by tag
|
||||||
|
"@font-face { font-family: 'b1'; font-feature-settings: 'bbbb' 0, 'aaaa', 'zzzz' 1, 'yyyy' 3; }",
|
||||||
|
// font-feature-settings deduplicates tags, keeping the last value
|
||||||
|
"@font-face { font-family: 'b2'; font-feature-settings: 'aaaa', 'aaaa' 0, 'aaaa' 3; }",
|
||||||
|
|
||||||
|
// font-width
|
||||||
|
"@font-face { font-family: 'c1'; font-width: extra-condensed; }",
|
||||||
|
"@font-face { font-family: 'c2'; font-width: 50%; }",
|
||||||
|
// - font-stretch is a legacy alias for font-width
|
||||||
|
"@font-face { font-family: 'c3'; font-stretch: extra-condensed; }",
|
||||||
|
"@font-face { font-family: 'c4'; font-stretch: 50%; }",
|
||||||
|
];
|
||||||
|
for (let testCase of testCases) {
|
||||||
|
let style = document.createElement("style");
|
||||||
|
style.innerText = testCase;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
let sheet = style.sheet;
|
||||||
|
println(sheet.cssRules[0].cssText);
|
||||||
|
style.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,10 +0,0 @@
|
||||||
<script src="../include.js"></script>
|
|
||||||
<script>
|
|
||||||
test(() => {
|
|
||||||
let style = document.createElement("style");
|
|
||||||
style.innerText = "@font-face { font-family: 'a1'; src: local('xyz'); }";
|
|
||||||
document.head.appendChild(style);
|
|
||||||
let sheet = style.sheet;
|
|
||||||
println(sheet.cssRules[0].cssText);
|
|
||||||
});
|
|
||||||
</script>
|
|
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibGfx/Font/Font.h>
|
||||||
#include <LibGfx/Font/FontStyleMapping.h>
|
#include <LibGfx/Font/FontStyleMapping.h>
|
||||||
#include <LibWeb/Bindings/CSSFontFaceRulePrototype.h>
|
#include <LibWeb/Bindings/CSSFontFaceRulePrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
@ -92,15 +93,74 @@ String CSSFontFaceRule::serialized() const
|
||||||
// followed by the result of performing serialize a <'font-variant'>,
|
// followed by the result of performing serialize a <'font-variant'>,
|
||||||
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
||||||
|
|
||||||
// FIXME: 8. If rule’s associated font-feature-settings descriptor is present, a single SPACE (U+0020),
|
// 8. If rule’s associated font-feature-settings descriptor is present, a single SPACE (U+0020),
|
||||||
// followed by the string "font-feature-settings:", followed by a single SPACE (U+0020),
|
// followed by the string "font-feature-settings:", followed by a single SPACE (U+0020),
|
||||||
// followed by the result of performing serialize a <'font-feature-settings'>,
|
// followed by the result of performing serialize a <'font-feature-settings'>,
|
||||||
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
||||||
|
if (m_font_face.font_feature_settings().has_value()) {
|
||||||
|
auto const& feature_settings = m_font_face.font_feature_settings().value();
|
||||||
|
builder.append(" font-feature-settings: "sv);
|
||||||
|
// NOTE: We sort the tags during parsing, so they're already in the correct order.
|
||||||
|
bool first = true;
|
||||||
|
for (auto const& [key, value] : feature_settings) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
builder.append(", "sv);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: 9. If rule’s associated font-stretch descriptor is present, a single SPACE (U+0020),
|
serialize_a_string(builder, key);
|
||||||
// followed by the string "font-stretch:", followed by a single SPACE (U+0020),
|
// NOTE: 1 is the default value, so don't serialize it.
|
||||||
// followed by the result of performing serialize a <'font-stretch'>,
|
if (value != 1)
|
||||||
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
builder.appendff(" {}", value);
|
||||||
|
}
|
||||||
|
builder.append(";"sv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. If rule’s associated font-stretch descriptor is present, a single SPACE (U+0020),
|
||||||
|
// followed by the string "font-stretch:", followed by a single SPACE (U+0020),
|
||||||
|
// followed by the result of performing serialize a <'font-stretch'>,
|
||||||
|
// followed by the string ";", i.e., SEMICOLON (U+003B).
|
||||||
|
// NOTE: font-stretch is now an alias for font-width, so we use that instead.
|
||||||
|
if (m_font_face.width().has_value()) {
|
||||||
|
builder.append(" font-width: "sv);
|
||||||
|
// NOTE: font-width is supposed to always be serialized as a percentage.
|
||||||
|
// Right now, it's stored as a Gfx::FontWidth value, so we have to lossily convert it back.
|
||||||
|
float percentage = 100.0f;
|
||||||
|
switch (m_font_face.width().value()) {
|
||||||
|
case Gfx::FontWidth::UltraCondensed:
|
||||||
|
percentage = 50.0f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::ExtraCondensed:
|
||||||
|
percentage = 62.5f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::Condensed:
|
||||||
|
percentage = 75.0f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::SemiCondensed:
|
||||||
|
percentage = 87.5f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::Normal:
|
||||||
|
percentage = 100.0f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::SemiExpanded:
|
||||||
|
percentage = 112.5f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::Expanded:
|
||||||
|
percentage = 125.0f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::ExtraExpanded:
|
||||||
|
percentage = 150.0f;
|
||||||
|
break;
|
||||||
|
case Gfx::FontWidth::UltraExpanded:
|
||||||
|
percentage = 200.0f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
builder.appendff("{}%", percentage);
|
||||||
|
builder.append(";"sv);
|
||||||
|
}
|
||||||
|
|
||||||
// 10. If rule’s associated font-weight descriptor is present, a single SPACE (U+0020),
|
// 10. If rule’s associated font-weight descriptor is present, a single SPACE (U+0020),
|
||||||
// followed by the string "font-weight:", followed by a single SPACE (U+0020),
|
// followed by the string "font-weight:", followed by a single SPACE (U+0020),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue