fontconfig: Branch 'main' - 5 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Apr 23 15:15:51 UTC 2025
.gitlab-ci.yml | 4
.gitlab-ci/ci.template | 3
.gitlab-ci/fedora-install.sh | 2
.gitlab-ci/freebsd-install.sh | 1
build-aux/fetch-testfonts.py | 193 ++++++++++++++++++++++++++++++++++++++++++
meson.build | 1
test/meson.build | 21 +++-
test/test_issue431.py | 37 +++++---
8 files changed, 244 insertions(+), 18 deletions(-)
New commits:
commit a352486ad464084ac765b8c954a6d3fc6dc3b0e6
Merge: 88ee3ad 1911d1c
Author: Akira TAGOH <akira at tagoh.org>
Date: Wed Apr 23 15:15:48 2025 +0000
Merge branch 'crosTestFonts' into 'main'
[Fontations] Local and container download of test font files
See merge request fontconfig/fontconfig!386
commit 1911d1ce00ae3b088aeba5326e5205e64b2238f7
Author: Dominik Röttsches <drott at chromium.org>
Date: Wed Apr 23 15:27:21 2025 +0300
Migrate pytest testcase 431 to pre-downloaded fonts
diff --git a/test/meson.build b/test/meson.build
index da5ac1f..895dbab 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -92,9 +92,10 @@ if host_machine.system() != 'windows'
if pytest.found()
test('pytest', pytest, args: ['--tap'],
workdir: meson.current_source_dir(),
- env: ['builddir=@0@'.format(meson.current_build_dir())],
+ env: ['builddir=@0@'.format(meson.project_build_root())],
protocol: 'tap',
- timeout: 600)
+ timeout: 600,
+ depends: fetch_test_fonts)
endif
endif
diff --git a/test/test_issue431.py b/test/test_issue431.py
index 55ca2b4..ba0b336 100644
--- a/test/test_issue431.py
+++ b/test/test_issue431.py
@@ -12,16 +12,29 @@ from pathlib import Path
def test_issue431(tmp_path):
- req = requests.get('https://github.com/googlefonts/roboto-flex/releases/download/3.100/roboto-flex-fonts.zip',
- allow_redirects=True)
- with open(tmp_path / 'roboto-flex-fonts.zip', 'wb') as f:
- f.write(req.content)
- shutil.unpack_archive(tmp_path / 'roboto-flex-fonts.zip', tmp_path)
- builddir = Path(os.environ.get('builddir', Path(__file__).parent)).parent
- result = subprocess.run([builddir / 'fc-query' / 'fc-query', '-f', '%{family[0]}:%{index}:%{style[0]}:%{postscriptname}\n', tmp_path / 'roboto-flex-fonts/fonts/variable/RobotoFlex[GRAD,XOPQ,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght].ttf'], stdout=subprocess.PIPE)
+ builddir = Path(os.environ.get("builddir", Path(__file__).parent.parent))
+ roboto_flex_font = (
+ builddir
+ / "testfonts"
+ / "roboto-flex-fonts/fonts/variable/RobotoFlex[GRAD,XOPQ,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght].ttf"
+ )
- for line in result.stdout.decode('utf-8').splitlines():
- family, index, style, psname = line.split(':')
- normstyle = re.sub('[\x04\\(\\)/<>\\[\\]{}\t\f\r\n ]', '', style)
- assert psname.split('-')[-1] == normstyle, \
- f'postscriptname `{psname}\' does not contain style name `{normstyle}\': index {index}'
+ if not roboto_flex_font.exists():
+ pytest.skip(f"Font file not found: {roboto_flex_font}")
+
+ result = subprocess.run(
+ [
+ builddir / "fc-query" / "fc-query",
+ "-f",
+ "%{family[0]}:%{index}:%{style[0]}:%{postscriptname}\n",
+ roboto_flex_font,
+ ],
+ stdout=subprocess.PIPE,
+ )
+
+ for line in result.stdout.decode("utf-8").splitlines():
+ family, index, style, psname = line.split(":")
+ normstyle = re.sub("[\x04\\(\\)/<>\\[\\]{}\t\f\r\n ]", "", style)
+ assert (
+ psname.split("-")[-1] == normstyle
+ ), f"postscriptname `{psname}' does not contain style name `{normstyle}': index {index}"
commit 00c57ca34ac1c532a0568c7584558185ddeb866e
Author: Dominik Röttsches <drott at chromium.org>
Date: Wed Apr 23 15:27:52 2025 +0300
Add Roboto Flex to font downloading script
Preparation for removing custom download from issue 431 testcase.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8920035..a783d87 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -43,8 +43,8 @@ variables:
# changing these will force rebuilding the associated image
# Note: these tags have no meaning and are not tied to a particular
# fontconfig version
- FEDORA_TAG: '2025-04-23.1-21487182ca34'
- FREEBSD_TAG: '2025-04-23.1-1c3182609f3d'
+ FEDORA_TAG: '2025-04-23.1-36c045e261d1'
+ FREEBSD_TAG: '2025-04-23.1-61a4c35ef3b2'
FEDORA_EXEC: 'bash .gitlab-ci/fedora-install.sh'
FREEBSD_EXEC: 'bash .gitlab-ci/freebsd-install.sh'
diff --git a/build-aux/fetch-testfonts.py b/build-aux/fetch-testfonts.py
index 0bec884..85f11a1 100755
--- a/build-aux/fetch-testfonts.py
+++ b/build-aux/fetch-testfonts.py
@@ -30,6 +30,7 @@ SOURCE_FILES = (
"ko-nanumfonts-3.20.tar.bz2",
)
SOURCES = [URL_TEMPLATE % source for source in SOURCE_FILES]
+SOURCES += ["https://github.com/googlefonts/roboto-flex/releases/download/3.100/roboto-flex-fonts.zip"]
CONTAINER_DOWNLOAD_DIR = "/testfonts"
@@ -41,6 +42,7 @@ notofonts-20250214.tar.xz cb0f9edc030e07eca58b799c607d000dfde588911d8e228fc
robotofonts-2.132.tar.bz2 087c6f0708fe71f71a056f70fdbd5a85f4d2ce916670a98bd4be10b168abe16a
lohitfonts-cros-2.5.5.tar.bz2 ce0ce2a5098c8ffc52327cc030576df7f5328ad9fd8a3289e2476990ad133ff1
ko-nanumfonts-3.20.tar.bz2 59f9b6d7fcf63ca2bea7156ad66c784a1f0601d47be1b11237e17733d7112832
+roboto-flex-fonts.zip 02e0f5db84e69f254958434269d83aa6057b06f3c2a21042bb81b1afe1a0c8c6
"""
STAMP_FILE = ".stamp"
@@ -74,6 +76,8 @@ def extract_archive(filepath, target_dir):
logger.info(f"Extracting {filepath} to {target_dir}")
if filename.endswith((".tar.bz2", ".tar.gz", ".tar.xz")):
subprocess.run(["tar", "xf", filepath, "-C", target_dir], check=True)
+ elif filename.endswith(".zip"):
+ shutil.unpack_archive(filepath, target_dir)
else:
raise ValueError(f"Unsupported archive type: {filename}")
commit 5f00c2e653690489428ff1b26d43c09551f7adb2
Author: Dominik Röttsches <drott at chromium.org>
Date: Wed Apr 23 15:26:55 2025 +0300
Add Pytest status to Meson Summary
diff --git a/meson.build b/meson.build
index cce3585..344682e 100644
--- a/meson.build
+++ b/meson.build
@@ -604,6 +604,7 @@ summary({
'Documentation': (doc_targets.length() > 0 ? doc_targets : false),
'NLS': not opt_nls.disabled(),
'Tests': not get_option('tests').disabled(),
+ 'Pytest': pytest.found(),
'Tools': not get_option('tools').disabled(),
'iconv': found_iconv == 1,
'XML backend': xmltype,
commit 1597b9bafd732f4f7ed8ca6d3eb0b2b57c9c94f7
Author: Dominik Röttsches <drott at chromium.org>
Date: Wed Apr 16 13:23:28 2025 +0300
[Fontations] Container and local download of testfiles
* Add a python script that downloads a set of Chrome OS test
files. Intended as preparation for testing Fontations indexing against
FreeType indexing based on the set of fonts in ChromeOS.
* Define a custom target in Meson that ensure the test files are
available in the build directory. In containers: symlink them from the
directory in the container. Locally: Download them into the
build/testfonts. Skip the test if a stamp file with matching hashes is
present.
* Depend on the presence of the test fonts for the testing target
executables.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 4fa6385..8920035 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -43,8 +43,8 @@ variables:
# changing these will force rebuilding the associated image
# Note: these tags have no meaning and are not tied to a particular
# fontconfig version
- FEDORA_TAG: '2025-04-23.1-dd4daa0bc582'
- FREEBSD_TAG: '2025-04-23.1-e06fb6df1f3e'
+ FEDORA_TAG: '2025-04-23.1-21487182ca34'
+ FREEBSD_TAG: '2025-04-23.1-1c3182609f3d'
FEDORA_EXEC: 'bash .gitlab-ci/fedora-install.sh'
FREEBSD_EXEC: 'bash .gitlab-ci/freebsd-install.sh'
diff --git a/.gitlab-ci/ci.template b/.gitlab-ci/ci.template
index 0a6397d..6f97c72 100644
--- a/.gitlab-ci/ci.template
+++ b/.gitlab-ci/ci.template
@@ -46,7 +46,8 @@ variables:
{% for distro in distributions|unique(attribute="name") %}
{{"%-15s"| format(distro.name.upper() + '_TAG:')}}'{{distro.tag}}-{{
(ci_fairy.hashfiles('.gitlab-ci/config.yml',
- '.gitlab-ci/' + distro.name + '-install.sh'))[0:12]
+ '.gitlab-ci/' + distro.name + '-install.sh',
+ 'build-aux/fetch-testfonts.py'))[0:12]
}}'
{% endfor %}
diff --git a/.gitlab-ci/fedora-install.sh b/.gitlab-ci/fedora-install.sh
index 710b02e..d8ecddd 100644
--- a/.gitlab-ci/fedora-install.sh
+++ b/.gitlab-ci/fedora-install.sh
@@ -27,3 +27,5 @@ unzip android-ndk-r28-linux.zip
ln -sf android-ndk-r28 ndk
rm android-ndk-r28-linux.zip
popd
+
+python3 build-aux/fetch-testfonts.py --target-dir /testfonts
\ No newline at end of file
diff --git a/.gitlab-ci/freebsd-install.sh b/.gitlab-ci/freebsd-install.sh
index 4a21923..5ae6e23 100644
--- a/.gitlab-ci/freebsd-install.sh
+++ b/.gitlab-ci/freebsd-install.sh
@@ -1,3 +1,4 @@
#! /bin/bash
set -ex
+
diff --git a/build-aux/fetch-testfonts.py b/build-aux/fetch-testfonts.py
new file mode 100755
index 0000000..0bec884
--- /dev/null
+++ b/build-aux/fetch-testfonts.py
@@ -0,0 +1,189 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+from urllib.request import urlretrieve
+import multiprocessing
+
+import logging
+import sys
+
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger()
+
+if not sys.stdout.isatty():
+ logger.handlers = []
+
+URL_TEMPLATE = (
+ "https://commondatastorage.googleapis.com/chromeos-localmirror/distfiles/%s"
+)
+SOURCE_FILES = (
+ "noto-cjk-20210501.tar.bz2",
+ "crosextrafonts-20130214.tar.gz",
+ "notofonts-20250214.tar.xz",
+ "robotofonts-2.132.tar.bz2",
+ "lohitfonts-cros-2.5.5.tar.bz2",
+ "ko-nanumfonts-3.20.tar.bz2",
+)
+SOURCES = [URL_TEMPLATE % source for source in SOURCE_FILES]
+
+CONTAINER_DOWNLOAD_DIR = "/testfonts"
+
+# If you want to update these, copy the contents of the .stamp file from the target directory here.
+EXPECTED_HASHES = """
+noto-cjk-20210501.tar.bz2 5c70f246c392bf15aeaee22b2fba26bb0ac54e47c00a4b9c3b556bd06fe89281
+crosextrafonts-20130214.tar.gz c48d1c2fd613c9c06c959c34da7b8388059e2408d2bb19845dc3ed35f76e4d09
+notofonts-20250214.tar.xz cb0f9edc030e07eca58b799c607d000dfde588911d8e228fc82d5f61b9e5b6b3
+robotofonts-2.132.tar.bz2 087c6f0708fe71f71a056f70fdbd5a85f4d2ce916670a98bd4be10b168abe16a
+lohitfonts-cros-2.5.5.tar.bz2 ce0ce2a5098c8ffc52327cc030576df7f5328ad9fd8a3289e2476990ad133ff1
+ko-nanumfonts-3.20.tar.bz2 59f9b6d7fcf63ca2bea7156ad66c784a1f0601d47be1b11237e17733d7112832
+"""
+
+STAMP_FILE = ".stamp"
+
+
+def download_file(url, tmp_dir, target_dir):
+ filename = os.path.basename(url)
+ filepath = os.path.join(tmp_dir, filename)
+ logger.info(f"Downloading {url} to {filepath}")
+ urlretrieve(url, filepath)
+ return filepath
+
+
+def compute_sha256(filepath):
+ """Computes the SHA-256 hash of a file."""
+ import hashlib
+
+ hasher = hashlib.sha256()
+ with open(filepath, "rb") as file:
+ while True:
+ chunk = file.read(4096)
+ if not chunk:
+ break
+ hasher.update(chunk)
+ return hasher.hexdigest()
+
+
+def extract_archive(filepath, target_dir):
+ """Extracts an archive to the target directory."""
+ filename = os.path.basename(filepath)
+ logger.info(f"Extracting {filepath} to {target_dir}")
+ if filename.endswith((".tar.bz2", ".tar.gz", ".tar.xz")):
+ subprocess.run(["tar", "xf", filepath, "-C", target_dir], check=True)
+ else:
+ raise ValueError(f"Unsupported archive type: {filename}")
+
+
+def download_and_extract(url, tmp_dir, target_dir):
+ archivepath = download_file(url, tmp_dir, target_dir)
+ archivehash = compute_sha256(archivepath)
+ extract_archive(archivepath, target_dir)
+ return os.path.basename(archivepath), archivehash
+
+
+def stamp_target_dir(target_dir, downloaded_files_hashes):
+ if not downloaded_files_hashes or len(downloaded_files_hashes) == 0:
+ logger.error("No files to stamp")
+ return
+
+ stamp_path = os.path.join(target_dir, STAMP_FILE)
+ if os.path.exists(stamp_path):
+ os.remove(stamp_path)
+
+ max_filename_length = (
+ max(len(filename) for filename, _ in downloaded_files_hashes)
+ if downloaded_files_hashes
+ else 0
+ )
+
+ hash_results = "\n".join(
+ f"{filename:<{max_filename_length}} {hash}"
+ for filename, hash in downloaded_files_hashes
+ )
+ with open(stamp_path, "w") as f:
+ f.write(hash_results)
+
+ if not stamp_hashes_match(stamp_path):
+ raise ValueError("Downloaded files do not match recorded hashes!")
+
+
+def stamp_hashes_match(stamp_path):
+ if not os.path.exists(stamp_path):
+ return False
+
+ lines = []
+ with open(stamp_path, "r") as f:
+ lines = f.readlines()
+
+ expected_hashes = {}
+ for line in EXPECTED_HASHES.strip().split("\n"):
+ filename, hash = line.split()
+ expected_hashes[filename] = hash
+
+ for line in lines:
+ filename, hash = line.split()
+ if filename not in expected_hashes:
+ logger.error(f"Unexpected file in stamp: {filename}")
+ return False
+ if expected_hashes[filename] != hash:
+ logger.error(
+ f"Hash mismatch for {filename}: expected {expected_hashes[filename]}, got {hash}"
+ )
+ return False
+ return True
+
+
+def main():
+ """Main function to parse arguments and download/extract fonts."""
+
+ parser = argparse.ArgumentParser(description="Download and extract ChromeOS fonts.")
+
+ parser.add_argument("--target-dir", help="Target directory for extracted fonts.")
+ parser.add_argument(
+ "--try-symlink",
+ action="store_true",
+ help="Try to symlink test files previously downloaded to the container.",
+ )
+ args = parser.parse_args()
+
+ target_dir = args.target_dir
+
+ if args.try_symlink:
+ if os.path.exists(CONTAINER_DOWNLOAD_DIR) and stamp_hashes_match(
+ os.path.join(CONTAINER_DOWNLOAD_DIR, STAMP_FILE)
+ ):
+ try:
+ os.symlink(CONTAINER_DOWNLOAD_DIR, target_dir, target_is_directory=True)
+ except FileExistsError:
+ logger.debug(
+ f"Target directory {target_dir} already exists. Skipping symlink."
+ )
+ except OSError as e:
+ logger.warning(f"Failed to create symlink: {e}")
+ logger.info(
+ f"Symlinked test fonts directory from {CONTAINER_DOWNLOAD_DIR} to {target_dir}."
+ )
+ else:
+ logger.debug("Pre-downloaded test fonts not found.")
+
+ if stamp_hashes_match(os.path.join(target_dir, STAMP_FILE)):
+ logger.info("Fonts already downloaded and extracted.")
+ return 0
+
+ os.makedirs(target_dir, exist_ok=True)
+
+ with tempfile.TemporaryDirectory() as tmp_dir:
+ with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
+ hashes = pool.starmap(
+ download_and_extract,
+ [(source, tmp_dir, target_dir) for source in SOURCES],
+ )
+ stamp_target_dir(target_dir, hashes)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test/meson.build b/test/meson.build
index a7b2637..da5ac1f 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -1,3 +1,17 @@
+fetch_test_fonts = custom_target(
+ 'fetch_test_fonts',
+ output: 'testfonts',
+ command: [
+ python3,
+ join_paths(meson.project_source_root(), 'build-aux', 'fetch-testfonts.py'),
+ '--target-dir',
+ '@BUILD_ROOT@/testfonts',
+ '--try-symlink',
+ ],
+ build_by_default: false,
+ build_always_stale: true,
+)
+
tests = [
['test-bz89617.c', {'c_args': ['-DSRCDIR="@0@"'.format(meson.current_source_dir())]}],
['test-bz131804.c'],
@@ -59,7 +73,7 @@ endforeach
if get_option('fontations').enabled()
rust = import('rust')
- rust.test('fc_fontations_rust_tests', fc_fontations, link_with: [fc_fontations, libfontconfig_internal])
+ rust.test('fc_fontations_rust_tests', fc_fontations, link_with: [fc_fontations, libfontconfig_internal], depends: fetch_test_fonts)
endif
fs = import('fs')
More information about the Fontconfig
mailing list