HH-708: align container fonts with fingerprint maps #4

Merged
rogee merged 4 commits from agent/hh-708-font-fingerprint into main 2026-08-26 21:42:11 +08:00
3 changed files with 103 additions and 3 deletions
Showing only changes of commit 308b6c82aa - Show all commits
+4
View File
@@ -25,12 +25,16 @@ LABEL org.opencontainers.image.revision="$OCI_REVISION" \
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
fonts-croscore \
fonts-crosextra-caladea \
fonts-crosextra-carlito \
fonts-dejavu-core \
fonts-dejavu-extra \
fonts-freefont-ttf \
fonts-liberation \
fonts-liberation-sans-narrow \
fonts-noto-core \
fonts-noto-cjk \
fonts-noto-color-emoji \
fonts-ubuntu \
fonts-urw-base35 \
+52 -3
View File
@@ -8,9 +8,6 @@ grep -q 'Xvfb :99' docker-entrypoint.sh
! grep -q -- '--headless' docker-entrypoint.sh
grep -q -- '--no-sandbox' docker-entrypoint.sh
grep -q 'TCP-LISTEN:' docker-entrypoint.sh
for package in fonts-dejavu-core fonts-dejavu-extra fonts-freefont-ttf fonts-liberation fonts-liberation-sans-narrow fonts-noto-core fonts-noto-color-emoji fonts-ubuntu fonts-urw-base35; do
grep -q " $package \\\\" Dockerfile
done
grep -q 'git.ipao.vip/rogee/fingerprint-chromium' .gitea/workflows/publish.yml
grep -q 'ghcr.io/rogeecn/fingerprint-chromium' .github/workflows/publish.yml
grep -q 'packages: write' .gitea/workflows/publish.yml
@@ -33,3 +30,55 @@ DOCKER_LOG="$docker_log" OCI_REVISION=test PUSH=true PATH="$tmpdir:$PATH" \
./scripts/build.sh registry.example/fingerprint-chromium > "$tmpdir/output"
test "$(cat "$docker_log")" = "manifest inspect registry.example/fingerprint-chromium:1.2.3.4"
grep -q 'skipping build and push' "$tmpdir/output"
font_packages=(
fonts-croscore
fonts-crosextra-caladea
fonts-crosextra-carlito
fonts-dejavu-core
fonts-dejavu-extra
fonts-freefont-ttf
fonts-liberation
fonts-liberation-sans-narrow
fonts-noto-cjk
fonts-noto-color-emoji
fonts-noto-core
fonts-ubuntu
fonts-urw-base35
)
version="$(curl --fail --location --retry 3 --silent --show-error \
https://api.github.com/repos/adryfish/fingerprint-chromium/releases/latest \
| jq -er '.tag_name | select(test("^[0-9]+(\\.[0-9]+){3}$"))')"
image="fingerprint-chromium-test:$version"
CHROME_VERSION="$version" ./scripts/build.sh fingerprint-chromium-test
docker run --rm --entrypoint dpkg-query "$image" --show "${font_packages[@]}" >/dev/null
docker run --rm --entrypoint sh "$image" -c '
for font do
fc-match --format "%{family}\n" "$font" | grep -Fq "$font"
done
' sh Arimo Tinos Cousine Caladea Carlito \
'Noto Sans CJK JP' 'Noto Sans CJK SC' 'Noto Sans CJK TC' \
'Noto Serif CJK JP' 'Noto Serif CJK SC' 'Noto Serif CJK TC'
probe() {
local platform="$1" threshold="$2" output count
output="$(docker run --rm \
--volume "$PWD/tests/font-probe.html:/tmp/font-probe.html:ro" \
--entrypoint /opt/chromium/chrome "$image" \
--no-sandbox --headless=new --disable-gpu --disable-dev-shm-usage \
--fingerprint=1000 --fingerprint-platform="$platform" \
--dump-dom "file:///tmp/font-probe.html#$platform" 2>/dev/null)"
count="$(sed -n 's/.*data-count="\([0-9][0-9]*\)".*/\1/p' <<<"$output")"
[[ "$count" =~ ^[0-9]+$ && "$count" -ge "$threshold" ]] || {
printf '%s font probe: expected >= %s, got %s\n' "$platform" "$threshold" "${count:-none}" >&2
return 1
}
printf '%s font probe: %s\n' "$platform" "$count"
}
probe windows 22
probe macos 24
probe linux 27
+47
View File
@@ -0,0 +1,47 @@
<!doctype html>
<output id="result"></output>
<script>
const fonts = {
windows: [
'Arial Black', 'Bahnschrift', 'Cambria', 'Candara', 'Cascadia Code',
'Comic Sans MS', 'Consolas', 'Constantia', 'Corbel', 'Ebrima',
'Franklin Gothic Medium', 'Gabriola', 'Gadugi', 'Georgia', 'Impact',
'Ink Free', 'Javanese Text', 'Lucida Console', 'Malgun Gothic',
'Microsoft YaHei', 'Palatino Linotype', 'Segoe UI', 'SimSun', 'Tahoma',
'Trebuchet MS', 'Verdana', 'Webdings', 'Wingdings', 'Yu Gothic'
],
macos: [
'Academy Engraved LET', 'American Typewriter', 'Andale Mono',
'Apple Chancery', 'Apple Color Emoji', 'Apple Symbols', 'Avenir',
'Avenir Next', 'Baskerville', 'Big Caslon', 'Bradley Hand', 'Chalkboard',
'Chalkduster', 'Charter', 'Cochin', 'Copperplate', 'Didot', 'Futura',
'Geneva', 'Gill Sans', 'Helvetica Neue', 'Herculanum', 'Hoefler Text',
'Lucida Grande', 'Marker Felt', 'Menlo', 'Monaco', 'Optima', 'Papyrus',
'PingFang SC', 'Rockwell', 'SF Pro Display', 'Skia', 'Snell Roundhand',
'Songti SC', 'Times', 'Trattatello', 'Zapfino'
],
linux: [
'Arimo', 'Caladea', 'Carlito', 'Cousine', 'DejaVu Math TeX Gyre',
'DejaVu Sans', 'DejaVu Sans Mono', 'DejaVu Serif', 'FreeMono', 'FreeSans',
'FreeSerif', 'Liberation Mono', 'Liberation Sans', 'Liberation Sans Narrow',
'Liberation Serif', 'Nimbus Mono PS', 'Nimbus Roman', 'Nimbus Sans',
'Nimbus Sans Narrow', 'Noto Color Emoji', 'Noto Sans', 'Noto Sans CJK JP',
'Noto Sans CJK SC', 'Noto Serif', 'Noto Serif CJK JP', 'Noto Serif CJK SC',
'Tinos', 'Ubuntu', 'Ubuntu Mono'
]
};
const platform = location.hash.slice(1);
const sample = 'mmmmmmmmmmlli';
const bases = ['monospace', 'sans-serif', 'serif'];
const context = document.createElement('canvas').getContext('2d');
const widths = bases.map(base => {
context.font = `72px ${base}`;
return context.measureText(sample).width;
});
const detected = fonts[platform].filter(font => bases.some((base, index) => {
context.font = `72px "${font}",${base}`;
return context.measureText(sample).width !== widths[index];
}));
result.dataset.count = detected.length;
result.textContent = `${platform}:${detected.join('|')}`;
</script>