Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /html/canvas/offscreen/text/2d.text.measure.getActualBoundingBox-full-text.tentative.worker.html - WPT Dashboard Interop Dashboard
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
// OffscreenCanvas test in a worker:2d.text.measure.getActualBoundingBox-full-text.tentative
// Description:
// Note:
importScripts("/resources/testharness.js");
importScripts("/html/canvas/resources/canvas-tests.js");
test(t => {
const canvas = new OffscreenCanvas(800, 200);
const ctx = canvas.getContext('2d');
// Use measureText to create a rect for the whole text
function getFullTextBoundingBox(text) {
const tm = ctx.measureText(text);
return {
x: -tm.actualBoundingBoxLeft,
y: -tm.actualBoundingBoxAscent,
width: tm.actualBoundingBoxLeft + tm.actualBoundingBoxRight,
height: tm.actualBoundingBoxAscent + tm.actualBoundingBoxDescent
};
}
function checkRectsMatch(rect_a, rect_b) {
assert_approx_equals(rect_a.x, rect_b.x, 1.0);
assert_approx_equals(rect_a.y, rect_b.y, 1.0);
assert_approx_equals(rect_a.width, rect_b.width, 1.0);
assert_approx_equals(rect_a.height, rect_b.height, 1.0);
}
const kAligns = [
'left',
'center',
'right',
];
const kBaselines = [
'top',
'hanging',
'middle',
'alphabetic',
'ideographic',
'bottom',
];
const kTexts = [
'UNAVAILABLE',
'ππΆπ',
'οΌοΌγοΌοΌ',
'-abcd '
]
ctx.font = '50px sans-serif';
ctx.direction = 'ltr';
for (const align of kAligns) {
for (const baseline of kBaselines) {
ctx.textAlign = align;
ctx.textBaseline = baseline;
for (text of kTexts) {
const tm = ctx.measureText(text);
const rect_from_api = tm.getActualBoundingBox(0, text.length);
const rect_from_full_bounds = getFullTextBoundingBox(text);
checkRectsMatch(rect_from_api, rect_from_full_bounds)
}
}
}
}, "Test TextMetrics::getActualBoundingBox() for the full length of the string for some edge cases, with direction ltr and no-directional-override");
test(t => {
const canvas = new OffscreenCanvas(800, 200);
const ctx = canvas.getContext('2d');
// Use measureText to create a rect for the whole text
function getFullTextBoundingBox(text) {
const tm = ctx.measureText(text);
return {
x: -tm.actualBoundingBoxLeft,
y: -tm.actualBoundingBoxAscent,
width: tm.actualBoundingBoxLeft + tm.actualBoundingBoxRight,
height: tm.actualBoundingBoxAscent + tm.actualBoundingBoxDescent
};
}
function checkRectsMatch(rect_a, rect_b) {
assert_approx_equals(rect_a.x, rect_b.x, 1.0);
assert_approx_equals(rect_a.y, rect_b.y, 1.0);
assert_approx_equals(rect_a.width, rect_b.width, 1.0);
assert_approx_equals(rect_a.height, rect_b.height, 1.0);
}
const kAligns = [
'left',
'center',
'right',
];
const kBaselines = [
'top',
'hanging',
'middle',
'alphabetic',
'ideographic',
'bottom',
];
const kTexts = [
'UNAVAILABLE',
'ππΆπ',
'οΌοΌγοΌοΌ',
'-abcd '
]
ctx.font = '50px sans-serif';
ctx.direction = 'rtl';
for (const align of kAligns) {
for (const baseline of kBaselines) {
ctx.textAlign = align;
ctx.textBaseline = baseline;
for (text of kTexts) {
const tm = ctx.measureText(text);
const rect_from_api = tm.getActualBoundingBox(0, text.length);
const rect_from_full_bounds = getFullTextBoundingBox(text);
checkRectsMatch(rect_from_api, rect_from_full_bounds)
}
}
}
}, "Test TextMetrics::getActualBoundingBox() for the full length of the string for some edge cases, with direction rtl and no-directional-override");
test(t => {
const canvas = new OffscreenCanvas(800, 200);
const ctx = canvas.getContext('2d');
// Use measureText to create a rect for the whole text
function getFullTextBoundingBox(text) {
const tm = ctx.measureText(text);
return {
x: -tm.actualBoundingBoxLeft,
y: -tm.actualBoundingBoxAscent,
width: tm.actualBoundingBoxLeft + tm.actualBoundingBoxRight,
height: tm.actualBoundingBoxAscent + tm.actualBoundingBoxDescent
};
}
function checkRectsMatch(rect_a, rect_b) {
assert_approx_equals(rect_a.x, rect_b.x, 1.0);
assert_approx_equals(rect_a.y, rect_b.y, 1.0);
assert_approx_equals(rect_a.width, rect_b.width, 1.0);
assert_approx_equals(rect_a.height, rect_b.height, 1.0);
}
function addDirectionalOverrideCharacters(text, direction_is_ltr) {
// source: www.w3.org/International/questions/qa-bidi-unicode-controls.en
const LTR_OVERRIDE = '\u202D';
const RTL_OVERRIDE = '\u202E';
const OVERRIDE_END = '\u202C';
if (direction_is_ltr) {
return LTR_OVERRIDE + text + OVERRIDE_END;
}
return RTL_OVERRIDE + text + OVERRIDE_END;
}
const kAligns = [
'left',
'center',
'right',
];
const kBaselines = [
'top',
'hanging',
'middle',
'alphabetic',
'ideographic',
'bottom',
];
const kTexts = [
'UNAVAILABLE',
'ππΆπ',
'οΌοΌγοΌοΌ',
'-abcd '
]
ctx.font = '50px sans-serif';
ctx.direction = 'ltr';
for (const align of kAligns) {
for (const baseline of kBaselines) {
ctx.textAlign = align;
ctx.textBaseline = baseline;
for (text of kTexts) {
text = addDirectionalOverrideCharacters(text, ctx.direction == 'ltr');
const tm = ctx.measureText(text);
const rect_from_api = tm.getActualBoundingBox(0, text.length);
const rect_from_full_bounds = getFullTextBoundingBox(text);
checkRectsMatch(rect_from_api, rect_from_full_bounds)
}
}
}
}, "Test TextMetrics::getActualBoundingBox() for the full length of the string for some edge cases, with direction ltr and directional-override");
test(t => {
const canvas = new OffscreenCanvas(800, 200);
const ctx = canvas.getContext('2d');
// Use measureText to create a rect for the whole text
function getFullTextBoundingBox(text) {
const tm = ctx.measureText(text);
return {
x: -tm.actualBoundingBoxLeft,
y: -tm.actualBoundingBoxAscent,
width: tm.actualBoundingBoxLeft + tm.actualBoundingBoxRight,
height: tm.actualBoundingBoxAscent + tm.actualBoundingBoxDescent
};
}
function checkRectsMatch(rect_a, rect_b) {
assert_approx_equals(rect_a.x, rect_b.x, 1.0);
assert_approx_equals(rect_a.y, rect_b.y, 1.0);
assert_approx_equals(rect_a.width, rect_b.width, 1.0);
assert_approx_equals(rect_a.height, rect_b.height, 1.0);
}
function addDirectionalOverrideCharacters(text, direction_is_ltr) {
// source: www.w3.org/International/questions/qa-bidi-unicode-controls.en
const LTR_OVERRIDE = '\u202D';
const RTL_OVERRIDE = '\u202E';
const OVERRIDE_END = '\u202C';
if (direction_is_ltr) {
return LTR_OVERRIDE + text + OVERRIDE_END;
}
return RTL_OVERRIDE + text + OVERRIDE_END;
}
const kAligns = [
'left',
'center',
'right',
];
const kBaselines = [
'top',
'hanging',
'middle',
'alphabetic',
'ideographic',
'bottom',
];
const kTexts = [
'UNAVAILABLE',
'ππΆπ',
'οΌοΌγοΌοΌ',
'-abcd '
]
ctx.font = '50px sans-serif';
ctx.direction = 'rtl';
for (const align of kAligns) {
for (const baseline of kBaselines) {
ctx.textAlign = align;
ctx.textBaseline = baseline;
for (text of kTexts) {
text = addDirectionalOverrideCharacters(text, ctx.direction == 'ltr');
const tm = ctx.measureText(text);
const rect_from_api = tm.getActualBoundingBox(0, text.length);
const rect_from_full_bounds = getFullTextBoundingBox(text);
checkRectsMatch(rect_from_api, rect_from_full_bounds)
}
}
}
}, "Test TextMetrics::getActualBoundingBox() for the full length of the string for some edge cases, with direction rtl and directional-override");
done();