Skip to content

Commit

Permalink
Add metric override descriptors to FontFace JS interface
Browse files Browse the repository at this point in the history
Following the CSSWG resolution to add metric override descriptors
to @font-face, this patch also adds these descriptors as attributes
to the JavaScript FontFace interface.

Bug: 1098355
Change-Id: Ia5ef4ad870559457834fe9fafaaab79b24a0e08b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2425484
Reviewed-by: Anders Hartvoll Ruud <[email protected]>
Reviewed-by: Chris Harrelson <[email protected]>
Commit-Queue: Xiaocheng Hu <[email protected]>
Cr-Commit-Position: refs/heads/master@{#810907}
  • Loading branch information
xiaochengh authored and chromium-wpt-export-bot committed Sep 26, 2020
1 parent 83a5a73 commit 16fbdd5
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 0 deletions.
222 changes: 222 additions & 0 deletions css/css-font-loading/fontface-override-descriptor-getter-setter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<!DOCTYPE html>
<title>Tests getters and setters of the font metrics override descriptors of FontFace</title>
<link rel="author" href="mailto:[email protected]">
<link rel="help" href="https://drafts.csswg.org/css-font-loading/#fontface-interface">
<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-metrics-override-desc">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function rejection(promise) {
return new Promise((resolve, reject) => promise.then(reject, resolve));
}

// ascentOverride

test(() => {
const face = new FontFace(
'ascent-override-initial',
'url(https://example.com/font.woff)');
assert_equals(face.ascentOverride, 'normal');
}, "Initial value of ascentOverride should be 'normal'");

test(() => {
const face = new FontFace(
'ascent-override-initialize-with-normal',
'url(https://example.com/font.woff)',
{ascentOverride: 'normal'});
assert_equals(face.ascentOverride, 'normal');
}, "Initialize ascentOverride with 'normal' should succeed");

test(() => {
const face = new FontFace(
'ascent-override-initialize-with-percentage',
'url(https://example.com/font.woff)',
{ascentOverride: '50%'});
assert_equals(face.ascentOverride, '50%');
}, "Initialize ascentOverride with a percentage should succeed");

promise_test(async () => {
const face = new FontFace(
'ascent-override-initialize-with-negative-percentage',
'url(https://example.com/font.woff)',
{ascentOverride: '-50%'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize ascentOverride with a negative percentage should fail");

promise_test(async () => {
const face = new FontFace(
'ascent-override-initialize-with-non-percentage',
'url(https://example.com/font.woff)',
{ascentOverride: '10px'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize ascentOverride with a non-percentage should fail");

test(() => {
const face = new FontFace(
'ascent-override-normal-to-percentage',
'url(https://example.com/font.woff)',
{ascentOverride: 'normal'});
face.ascentOverride = '50%';
assert_equals(face.ascentOverride, '50%');
}, "Changing ascentOverride from 'normal' to percentage should succeed");

test(() => {
const face = new FontFace(
'ascent-override-percentage-to-normal',
'url(https://example.com/font.woff)',
{ascentOverride: '50%'});
face.ascentOverride = 'normal';
assert_equals(face.ascentOverride, 'normal');
}, "Changing ascentOverride from percentage to 'normal' should succeed");

test(() => {
const face = new FontFace(
'ascent-override-set-to-invalid',
'url(https://example.com/font.woff)');
assert_throws_dom('SyntaxError', () => {face.ascentOverride = '10px'});
}, "Changing ascentOverride to invalid value should fail");

// descentOverride

test(() => {
const face = new FontFace(
'descent-override-initial',
'url(https://example.com/font.woff)');
assert_equals(face.descentOverride, 'normal');
}, "Initial value of descentOverride should be 'normal'");

test(() => {
const face = new FontFace(
'descent-override-initialize-with-normal',
'url(https://example.com/font.woff)',
{descentOverride: 'normal'});
assert_equals(face.descentOverride, 'normal');
}, "Initialize descentOverride with 'normal' should succeed");

test(() => {
const face = new FontFace(
'descent-override-initialize-with-percentage',
'url(https://example.com/font.woff)',
{descentOverride: '50%'});
assert_equals(face.descentOverride, '50%');
}, "Initialize descentOverride with a percentage should succeed");

promise_test(async () => {
const face = new FontFace(
'descent-override-initialize-with-negative-percentage',
'url(https://example.com/font.woff)',
{descentOverride: '-50%'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize descentOverride with a negative percentage should fail");

promise_test(async () => {
const face = new FontFace(
'descent-override-initialize-with-non-percentage',
'url(https://example.com/font.woff)',
{descentOverride: '10px'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize descentOverride with a non-percentage should fail");

test(() => {
const face = new FontFace(
'descent-override-normal-to-percentage',
'url(https://example.com/font.woff)',
{descentOverride: 'normal'});
face.descentOverride = '50%';
assert_equals(face.descentOverride, '50%');
}, "Changing descentOverride from 'normal' to percentage should succeed");

test(() => {
const face = new FontFace(
'descent-override-percentage-to-normal',
'url(https://example.com/font.woff)',
{descentOverride: '50%'});
face.descentOverride = 'normal';
assert_equals(face.descentOverride, 'normal');
}, "Changing descentOverride from percentage to 'normal' should succeed");

test(() => {
const face = new FontFace(
'descent-override-set-to-invalid',
'url(https://example.com/font.woff)');
assert_throws_dom('SyntaxError', () => {face.descentOverride = '10px'});
}, "Changing descentOverride to invalid value should fail");

// lineGapOverride

test(() => {
const face = new FontFace(
'lineGap-override-initial',
'url(https://example.com/font.woff)');
assert_equals(face.lineGapOverride, 'normal');
}, "Initial value of lineGapOverride should be 'normal'");

test(() => {
const face = new FontFace(
'lineGap-override-initialize-with-normal',
'url(https://example.com/font.woff)',
{lineGapOverride: 'normal'});
assert_equals(face.lineGapOverride, 'normal');
}, "Initialize lineGapOverride with 'normal' should succeed");

test(() => {
const face = new FontFace(
'lineGap-override-initialize-with-percentage',
'url(https://example.com/font.woff)',
{lineGapOverride: '50%'});
assert_equals(face.lineGapOverride, '50%');
}, "Initialize lineGapOverride with a percentage should succeed");

promise_test(async () => {
const face = new FontFace(
'lineGap-override-initialize-with-negative-percentage',
'url(https://example.com/font.woff)',
{lineGapOverride: '-50%'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize lineGapOverride with a negative percentage should fail");

promise_test(async () => {
const face = new FontFace(
'lineGap-override-initialize-with-non-percentage',
'url(https://example.com/font.woff)',
{lineGapOverride: '10px'});
const error = await rejection(face.load());
assert_equals('error', face.status);
assert_throws_dom('SyntaxError', () => {throw error});
}, "Initialize lineGapOverride with a non-percentage should fail");

test(() => {
const face = new FontFace(
'lineGap-override-normal-to-percentage',
'url(https://example.com/font.woff)',
{lineGapOverride: 'normal'});
face.lineGapOverride = '50%';
assert_equals(face.lineGapOverride, '50%');
}, "Changing lineGapOverride from 'normal' to percentage should succeed");

test(() => {
const face = new FontFace(
'lineGap-override-percentage-to-normal',
'url(https://example.com/font.woff)',
{lineGapOverride: '50%'});
face.lineGapOverride = 'normal';
assert_equals(face.lineGapOverride, 'normal');
}, "Changing lineGapOverride from percentage to 'normal' should succeed");

test(() => {
const face = new FontFace(
'lineGap-override-set-to-invalid',
'url(https://example.com/font.woff)');
assert_throws_dom('SyntaxError', () => {face.lineGapOverride = '10px'});
}, "Changing lineGapOverride to invalid value should fail");
</script>
27 changes: 27 additions & 0 deletions css/css-font-loading/fontface-override-descriptors-ref.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>Tests that the ascentOverride, descentOverride and lineGapOverride attributes of FontFace work</title>
<link rel="stylesheet" herf="/fonts/ahem.css">
<style>
#target {
position: absolute;
font-family: Ahem;
font-size: 20px;
}

#first-line {
position: absolute;
left: 0;
top: 0.7em;
}

#second-line {
position: absolute;
left: 0;
top: 3.7em;
}
</style>

<div id="target">
<div id="first-line">XXXXX</div>
<div id="second-line">XXXXX</div>
</div>
29 changes: 29 additions & 0 deletions css/css-font-loading/fontface-override-descriptors.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<title>Tests that the ascentOverride, descentOverride and lineGapOverride attributes of FontFace work</title>
<link rel="help" href="https://drafts.csswg.org/css-font-loading/#fontface-interface">
<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-metrics-override-desc">
<link rel="match" href="fontface-override-descriptors-ref.html">
<script>
const face = new FontFace(
'ahem-overridden',
'local("Ahem"), url("/fonts/Ahem.ttf")',
{ascentOverride: '100%', descentOverride: '100%', lineGapOverride: '100%'});
document.fonts.add(face);

// Line height is ascent + descent + lineGap = 3em
// Baseline is placed at lineGap * 0.5 + ascent = 1.5em below line box top
// Since each Ahem 'X' glyph has 0.8em above baseline, the top of each glyph
// should be placed at 0.7em below line box top
</script>
<style>
#target {
position: absolute;
font-family: ahem-overridden;
font-size: 20px;
}
</style>

<div id="target">
XXXXX<br>
XXXXX
</div>
1 change: 1 addition & 0 deletions lint.ignore
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ AHEM SYSTEM FONT: acid/acid3/test.html
AHEM SYSTEM FONT: resource-timing/resources/all_resource_types.htm
AHEM SYSTEM FONT: resource-timing/resources/iframe-reload-TAO.sub.html
AHEM SYSTEM FONT: html/canvas/element/drawing-text-to-the-canvas/2d.text.measure.fontBoundingBox.ahem.html
AHEM SYSTEM FONT: css/css-font-loading/fontface-override-descriptors.html

# TODO: The following should be deleted along with the Ahem web font cleanup
# PR (https://github.com/web-platform-tests/wpt/pull/18702)
Expand Down

0 comments on commit 16fbdd5

Please sign in to comment.