Skip to content

Commit 17bb5cc

Browse files
committed
web: Add device_fonts_rendering integration test
This test check whether device font glyphs are rendered inside proper bounds.
1 parent f1381b0 commit 17bb5cc

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package {
2+
3+
import flash.display.*;
4+
import flash.text.*;
5+
6+
[SWF(width="100", height="100", backgroundColor="#FF00FF")]
7+
public class Test extends MovieClip {
8+
public function Test() {
9+
var text:TextField = createTextField();
10+
addChild(text);
11+
12+
trace("Loaded test!");
13+
14+
trace("Character bounds:");
15+
trace(text.getCharBoundaries(0).x + text.x);
16+
trace(text.getCharBoundaries(0).width);
17+
trace(text.getCharBoundaries(0).y + text.y);
18+
trace(text.getCharBoundaries(0).height);
19+
}
20+
21+
private function createTextField():TextField {
22+
var text:TextField = new TextField();
23+
text.text = "M";
24+
text.x = 20;
25+
text.y = 20;
26+
text.width = 80;
27+
text.height = 80;
28+
return text;
29+
}
30+
}
31+
32+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6+
<script>
7+
const urlParams = new URLSearchParams(window.location.search);
8+
window.RufflePlayer = window.RufflePlayer || {};
9+
window.RufflePlayer.config = {
10+
"deviceFontRenderer": urlParams.get('deviceFontRenderer'),
11+
};
12+
</script>
13+
</head>
14+
15+
<body>
16+
<div>
17+
<object type="application/x-shockwave-flash" data="test.swf" width="100" height="100" id="objectElement"></object>
18+
</div>
19+
</body>
20+
21+
</html>
Binary file not shown.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import {
2+
assertNoMoreTraceOutput,
3+
expectTraceOutput,
4+
getTraceOutput,
5+
hideHardwareAccelerationModal,
6+
injectRuffleAndWait,
7+
openTest,
8+
playAndMonitor,
9+
} from "../../utils.js";
10+
import { expect, use } from "chai";
11+
import chaiHtml from "chai-html";
12+
13+
use(chaiHtml);
14+
15+
const deviceFontRenderers = ["embedded", "canvas"];
16+
17+
describe("Device Fonts: Rendering", () => {
18+
for (const deviceFontRenderer of deviceFontRenderers) {
19+
it(`load the test: ${deviceFontRenderer}`, async () => {
20+
await openTest(
21+
browser,
22+
"integration_tests/device_fonts_rendering",
23+
`index.html?deviceFontRenderer=${deviceFontRenderer}`,
24+
);
25+
await injectRuffleAndWait(browser);
26+
const player = await browser.$("<ruffle-object>");
27+
await playAndMonitor(browser, player, ["Loaded test!"]);
28+
await hideHardwareAccelerationModal(browser, player);
29+
});
30+
31+
it("check rendered image", async () => {
32+
const player = await browser.$("#objectElement");
33+
34+
await expectTraceOutput(browser, player, ["Character bounds:"]);
35+
36+
const messages = await getTraceOutput(browser, player, 4);
37+
38+
const boundsX = Number(messages[0]);
39+
const boundsWidth = Number(messages[1]);
40+
const boundsY = Number(messages[2]);
41+
const boundsHeight = Number(messages[3]);
42+
43+
expect(boundsX).to.be.greaterThan(0);
44+
expect(boundsWidth).to.be.greaterThan(0);
45+
expect(boundsY).to.greaterThan(0);
46+
expect(boundsHeight).to.be.greaterThan(0);
47+
48+
const canvas = await player.shadow$("canvas");
49+
50+
const [canvasWidth, canvasHeight, pixels] = await browser.execute(
51+
(el) => {
52+
const canvas = el as HTMLCanvasElement;
53+
const ctx =
54+
canvas.getContext("webgl") ||
55+
canvas.getContext("webgl2");
56+
const pixels = new Uint8Array(
57+
canvas.width * canvas.height * 4,
58+
);
59+
ctx?.readPixels(
60+
0,
61+
0,
62+
canvas.width,
63+
canvas.height,
64+
ctx.RGBA,
65+
ctx.UNSIGNED_BYTE,
66+
pixels,
67+
);
68+
69+
return [canvas.width, canvas.height, [...pixels]];
70+
},
71+
canvas,
72+
);
73+
74+
let insideBoundsBg = 0;
75+
let insideBoundsNonBg = 0;
76+
77+
for (let i = 0; i < pixels.length; i += 4) {
78+
const pixelIndex = i / 4;
79+
const pixel = pixels.slice(i, i + 4);
80+
const x = pixelIndex % canvasWidth;
81+
const y = Math.floor(pixelIndex / canvasWidth);
82+
83+
const scaledX = (x * 100) / canvasWidth;
84+
const scaledY = (y * 100) / canvasHeight;
85+
86+
const insideBounds =
87+
boundsX <= scaledX &&
88+
scaledX <= boundsX + boundsWidth &&
89+
boundsY <= scaledY &&
90+
scaledY <= boundsY + boundsHeight;
91+
92+
if (insideBounds) {
93+
// All pixels should be shades of magenta.
94+
expect(pixel[1]).to.be.equal(0);
95+
expect(pixel[0]).to.be.equal(pixel[2]);
96+
expect(pixel[3]).to.be.equal(255);
97+
98+
// Background is magenta.
99+
const isBackground =
100+
pixel.toString() === [255, 0, 255, 255].toString();
101+
if (isBackground) {
102+
insideBoundsBg += 1;
103+
} else {
104+
insideBoundsNonBg += 1;
105+
}
106+
} else {
107+
// Pixels outside of bounds should be background only.
108+
expect(pixel.toString()).to.be.equal(
109+
[255, 0, 255, 255].toString(),
110+
);
111+
}
112+
}
113+
114+
// Make sure there are both background and black pixels inside bounds.
115+
expect(insideBoundsBg).is.greaterThan(0);
116+
expect(insideBoundsNonBg).is.greaterThan(0);
117+
});
118+
119+
it("no more traces", async function () {
120+
const player = await browser.$("#objectElement");
121+
assertNoMoreTraceOutput(browser, player);
122+
});
123+
}
124+
});

0 commit comments

Comments
 (0)