From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../css/css-text/support/get-char-advances.js | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 testing/web-platform/tests/css/css-text/support/get-char-advances.js (limited to 'testing/web-platform/tests/css/css-text/support/get-char-advances.js') diff --git a/testing/web-platform/tests/css/css-text/support/get-char-advances.js b/testing/web-platform/tests/css/css-text/support/get-char-advances.js new file mode 100644 index 0000000000..0fd7332c4e --- /dev/null +++ b/testing/web-platform/tests/css/css-text/support/get-char-advances.js @@ -0,0 +1,70 @@ +'use strict'; + +/** + * Returns an array of advances for all characters in the descendants + * of the specified element. + * + * Technically speaking, advances and glyph bounding boxes are different things, + * and advances are not exposed. This function computes approximate values from + * bounding boxes. + */ +function getCharAdvances(element) { + const style = getComputedStyle(element); + const is_vertical = style.writingMode.startsWith('vertical'); + const range = document.createRange(); + const all_bounds = [] + + function walk(element) { + for (const node of element.childNodes) { + const nodeType = node.nodeType; + if (nodeType === Node.TEXT_NODE) { + const text = node.nodeValue; + for (let i = 0; i < text.length; ++i) { + range.setStart(node, i); + range.setEnd(node, i + 1); + let bounds = range.getBoundingClientRect(); + // Transpose if it's in vertical flow. Guarantee that top < bottom + // and left < right are always true. + if (is_vertical) { + bounds = { + left: bounds.top, + top: bounds.left, + right: bounds.bottom, + bottom: bounds.right + }; + } + all_bounds.push(bounds); + } + } else if (nodeType === Node.ELEMENT_NODE) { + walk(node); + } + } + } + walk(element); + all_bounds.sort(function(bound_a, bound_b) { + if (bound_a.bottom <= bound_b.top) { + return -1; + } + if (bound_b.bottom <= bound_a.top) { + return 1; + } + return bound_a.left - bound_b.left; + }); + let origin = undefined; + let blockEnd = -1; + const advances = []; + for (let bounds of all_bounds) { + // Check if this is on the same line. + if (bounds.top >= blockEnd) { + origin = undefined; + blockEnd = bounds.bottom; + } + // For the first character, the left bound is closest to the origin. + if (origin === undefined) + origin = bounds.left; + // The right bound is a good approximation of the next origin. + advances.push(bounds.right - origin); + origin = bounds.right; + } + return advances; +} -- cgit v1.2.3