Skip to content

Commit

Permalink
Remove TextCluster caching in TextMetrics
Browse files Browse the repository at this point in the history
In a previous CL, the getTextClusters() API was implemented with a cache
for the created TextCluster objects. This API may include as a parameter
a dictionary with text align and baseline options. Since the cache is
used if it was already calculated, subsequent calls with different
options return clusters in the wrong positions.

This CL removes this cache to guarantee that the results are always
calculated from scratch taking into account the current options passed

Tests were added using the CanvasTest font to check that the positions
are coherent with the options passed.

A future CL with reincorporate this cache in a way that allows
offsetting the stored clusters following the current align and
baseline options passed.

Bug: 341213359
Change-Id: I4cabdb62d05a9c8763300c0d268d7794ca9f160b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5933690
Reviewed-by: Jean-Philippe Gravel <[email protected]>
Commit-Queue: Andres Ricardo Perez <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1369650}
  • Loading branch information
AndresRPerez12 authored and chromium-wpt-export-bot committed Oct 16, 2024
1 parent 477be4a commit ed58c69
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>Canvas test: 2d.text.measure.text-clusters-position.tentative</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
<style>
@font-face {
font-family: CanvasTest;
src: url("/fonts/CanvasTest.ttf");
}
</style>
<body class="show_output">

<h1>2d.text.measure.text-clusters-position.tentative</h1>
<p class="desc">Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.</p>


<span style="font-family: CanvasTest; position: absolute; visibility: hidden">A</span>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="500" height="500"><p class="fallback">FAIL (fallback content)</p></canvas>

<ul id="d"></ul>
<script>
promise_test(async t => {

var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');

await document.fonts.ready;
ctx.font = '40px CanvasTest';
const text = 'E';

// Origin for all the measurements is placed at the top left corner.
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
let tm = ctx.measureText(text);

// X position.
_assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0");
_assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20");
_assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40");

// Y position.
_assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0");
_assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20");
_assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40");
_assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30");

}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.");
</script>

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>OffscreenCanvas test: 2d.text.measure.text-clusters-position.tentative</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/canvas/resources/canvas-tests.js"></script>

<h1>2d.text.measure.text-clusters-position.tentative</h1>
<p class="desc">Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.</p>


<script>
promise_test(async t => {

var canvas = new OffscreenCanvas(500, 500);
var ctx = canvas.getContext('2d');

var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
f.load();
document.fonts.add(f);
await document.fonts.ready;
ctx.font = '40px CanvasTest';
const text = 'E';

// Origin for all the measurements is placed at the top left corner.
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
let tm = ctx.measureText(text);

// X position.
_assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0");
_assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20");
_assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40");

// Y position.
_assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0");
_assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20");
_assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40");
_assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30");

}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
// OffscreenCanvas test in a worker:2d.text.measure.text-clusters-position.tentative
// Description:Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.
// Note:

importScripts("/resources/testharness.js");
importScripts("/html/canvas/resources/canvas-tests.js");

promise_test(async t => {
var canvas = new OffscreenCanvas(500, 500);
var ctx = canvas.getContext('2d');

var f = new FontFace("CanvasTest", "url('/fonts/CanvasTest.ttf')");
f.load();
self.fonts.add(f);
await self.fonts.ready;
ctx.font = '40px CanvasTest';
const text = 'E';

// Origin for all the measurements is placed at the top left corner.
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
let tm = ctx.measureText(text);

// X position.
_assertSame(Math.abs(tm.getTextClusters({align: 'left'})[0].x), 0, "Math.abs(tm.getTextClusters({align: 'left'})[\""+(0)+"\"].x)", "0");
_assertSame(tm.getTextClusters({align: 'center'})[0].x, 20, "tm.getTextClusters({align: 'center'})[\""+(0)+"\"].x", "20");
_assertSame(tm.getTextClusters({align: 'right'})[0].x, 40, "tm.getTextClusters({align: 'right'})[\""+(0)+"\"].x", "40");

// Y position.
_assertSame(Math.abs(tm.getTextClusters({baseline: 'top'})[0].y), 0, "Math.abs(tm.getTextClusters({baseline: 'top'})[\""+(0)+"\"].y)", "0");
_assertSame(tm.getTextClusters({baseline: 'middle'})[0].y, 20, "tm.getTextClusters({baseline: 'middle'})[\""+(0)+"\"].y", "20");
_assertSame(tm.getTextClusters({baseline: 'bottom'})[0].y, 40, "tm.getTextClusters({baseline: 'bottom'})[\""+(0)+"\"].y", "40");
_assertSame(tm.getTextClusters({baseline: 'alphabetic'})[0].y, 30, "tm.getTextClusters({baseline: 'alphabetic'})[\""+(0)+"\"].y", "30");
}, "Test that TextMetrics::getTextClusters() returns clusters that are positioned according to the target align and baseline passed as options.");
done();
31 changes: 31 additions & 0 deletions html/canvas/tools/yaml-new/text.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2020,6 +2020,37 @@
() => tm.getTextClusters(text.length, text.length + 1) );
}
- name: 2d.text.measure.text-clusters-position.tentative
desc: >-
Test that TextMetrics::getTextClusters() returns clusters that are
positioned according to the target align and baseline passed as options.
size: [500, 500]
test_type: promise
fonts:
- CanvasTest
code: |
{{ load_font }}
ctx.font = '40px CanvasTest';
const text = 'E';
// Origin for all the measurements is placed at the top left corner.
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
let tm = ctx.measureText(text);
// X position.
@assert Math.abs(tm.getTextClusters({align: 'left'})[0].x) === 0;
@assert tm.getTextClusters({align: 'center'})[0].x === 20;
@assert tm.getTextClusters({align: 'right'})[0].x === 40;
// Y position.
@assert Math.abs(tm.getTextClusters({baseline: 'top'})[0].y) === 0;
@assert tm.getTextClusters({baseline: 'middle'})[0].y === 20;
@assert tm.getTextClusters({baseline: 'bottom'})[0].y === 40;
@assert tm.getTextClusters({baseline: 'alphabetic'})[0].y === 30;
variants:
- *load-font-variant-definition

- name: 2d.text.drawing.style.absolute.spacing
desc: Testing letter spacing and word spacing with absolute length
code: |
Expand Down

0 comments on commit ed58c69

Please sign in to comment.