From 90147b9f6cf768993db44aa57f79961ca0563453 Mon Sep 17 00:00:00 2001 From: BastienSozeau Date: Tue, 7 Jan 2025 17:36:13 +0100 Subject: [PATCH] Add missing glyphs --- .gitignore | 37 +- Makefile | 45 +- README.md | 18 +- documentation/image1.py | 137 + renovate.json | 7 + requirements-test.in | 2 + requirements-test.txt | 2 + requirements.in | 6 + requirements.txt | 125 +- scripts/customize.py | 123 + scripts/index.html | 4 +- scripts/read-config.py | 46 +- scripts/update-custom-filter.py | 8 + sources/Libertine-Super.glyphs | 144760 ++++++++++++++++++++++------- 14 files changed, 112334 insertions(+), 32986 deletions(-) create mode 100644 documentation/image1.py create mode 100644 renovate.json create mode 100644 requirements-test.in create mode 100644 requirements-test.txt create mode 100644 requirements.in create mode 100644 scripts/customize.py create mode 100644 scripts/update-custom-filter.py diff --git a/.gitignore b/.gitignore index e4bc3585..920227a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,38 @@ +*~ venv -.DS_Store +venv-test +build.stamp +node_modules +package-lock.json +package.json +master_ufo +instance_ufos .ninja_log build.ninja -build.stamp + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Autosaved by application when editing +###################### +*(تم الحفظ تلقائيًا).* +*(automaticky uloženo).* +*(Automatisch gesichert).* +*(Autosaved).* +*(guardado automáticamente).* +*(enregistré automatiquement).* +*(salvato automaticamente).* +*(自動保存).* +*(자동 저장됨).* +*(Salvo Automaticamente).* +*(Автосохранение).* +*(Otomatik Kaydedildi).* +*(自动存储).* +*(已自動儲存).* diff --git a/Makefile b/Makefile index eee66f97..07c782df 100644 --- a/Makefile +++ b/Makefile @@ -18,36 +18,53 @@ build: build.stamp venv: venv/touchfile -build.stamp: venv .init.stamp sources/config.yaml $(SOURCES) +venv-test: venv-test/touchfile + +customize: venv + . venv/bin/activate; python3 scripts/customize.py + +build.stamp: venv sources/config.yaml $(SOURCES) rm -rf fonts (for config in sources/config*.yaml; do . venv/bin/activate; gftools builder $$config; done) && touch build.stamp -.init.stamp: venv - . venv/bin/activate; python3 scripts/first-run.py - venv/touchfile: requirements.txt test -d venv || python3 -m venv venv . venv/bin/activate; pip install -Ur requirements.txt touch venv/touchfile -test: venv build.stamp - . venv/bin/activate; mkdir -p docs/ docs/fontbakery; fontbakery check-googlefonts -l WARN --full-lists --succinct --badges docs/fontbakery --html docs/fontbakery/fontbakery-report.html --ghmarkdown docs/fontbakery/fontbakery-report.md $(shell find fonts/ttf -type f) -o docs/fontbakery || echo '::warning file=sources/config.yaml,title=Fontbakery failures::The fontbakery QA check reported errors in your font. Please check the generated report.' - +venv-test/touchfile: requirements-test.txt + test -d venv-test || python3 -m venv venv-test + . venv-test/bin/activate; pip install -Ur requirements-test.txt + touch venv-test/touchfile + +test: venv-test build.stamp + TOCHECK=$$(find fonts/variable -type f 2>/dev/null); if [ -z "$$TOCHECK" ]; then TOCHECK=$$(find fonts/ttf -type f 2>/dev/null); fi ; . venv-test/bin/activate; mkdir -p docs/ docs/fontbakery; fontbakery check-googlefonts -l WARN --full-lists --succinct --badges docs/badges --html docs/fontbakery/fontbakery-report.html --ghmarkdown docs/fontbakery/fontbakery-report.md $$TOCHECK || echo '::warning file=sources/config.yaml,title=Fontbakery failures::The fontbakery QA check reported errors in your font. Please check the generated report.' + proof: venv build.stamp - . venv/bin/activate; mkdir -p docs/ docs/proof; diffenator2 proof $(shell find fonts/ttf -type f) -o docs/proof + TOCHECK=$$(find fonts/variable -type f 2>/dev/null); if [ -z "$$TOCHECK" ]; then TOCHECK=$$(find fonts/ttf -type f 2>/dev/null); fi ; . venv/bin/activate; mkdir -p docs/ docs/proof; diffenator2 proof $$TOCHECK -o docs/proof -images: venv build.stamp $(DRAWBOT_OUTPUT) - git add documentation/*.png && git commit -m "Rebuild images" documentation/*.png +images: venv $(DRAWBOT_OUTPUT) %.png: %.py build.stamp - python3 $< --output $@ + . venv/bin/activate; python3 $< --output $@ clean: rm -rf venv - find . -name "*.pyc" | xargs rm delete + find . -name "*.pyc" -delete update-project-template: npx update-template https://github.com/googlefonts/googlefonts-project-template/ -update: - pip install --upgrade $(dependency); pip freeze > requirements.txt +update: venv venv-test + venv/bin/pip install --upgrade pip-tools + # See https://pip-tools.readthedocs.io/en/latest/#a-note-on-resolvers for + # the `--resolver` flag below. + venv/bin/pip-compile --upgrade --verbose --resolver=backtracking requirements.in + venv/bin/pip-sync requirements.txt + + venv-test/bin/pip install --upgrade pip-tools + venv-test/bin/pip-compile --upgrade --verbose --resolver=backtracking requirements-test.in + venv-test/bin/pip-sync requirements-test.txt + + git commit -m "Update requirements" requirements.txt requirements-test.txt + git push diff --git a/README.md b/README.md index 01027ef0..d9655822 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,15 @@ [![][Fontbakery]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) [![][Universal]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) -[![][GF Profile]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) -[![][Outline Correctness]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) -[![][Shaping]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) - -[Fontbakery]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/fontbakery/overall.json -[GF Profile]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/fontbakery/GoogleFonts.json -[Outline Correctness]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/fontbakery/OutlineCorrectnessChecks.json -[Shaping]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/fontbakery/ShapingChecks.json -[Universal]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/fontbakery/Universal.json +[![][Outline Checks]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) +[![][Font File Checks]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) +[![][OpenType Specification Checks]](https://noirblancrouge.github.io/LibertineSuper/fontbakery/fontbakery-report.html) + +[Fontbakery]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/badges/overall.json +[Outline Checks]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/badges/OutlineChecks.json +[Font File Checks]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/badges/FontFileChecks.json +[Universal]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/badges/UniversalProfileChecks.json +[OpenType Specification Checks]: https://img.shields.io/endpoint?url=https://noirblancrouge.github.io/LibertineSuper/badges/OpenTypeSpecificationChecks.json ![Cover](https://raw.githubusercontent.com/noirblancrouge/LibertineSuper/master/documentation/images/libertinesuper.jpg) diff --git a/documentation/image1.py b/documentation/image1.py new file mode 100644 index 00000000..6670a6b5 --- /dev/null +++ b/documentation/image1.py @@ -0,0 +1,137 @@ +# This script is meant to be run from the root level +# of your font's git repository. For example, from a Unix terminal: +# $ git clone my-font +# $ cd my-font +# $ python3 documentation/image1.py --output documentation/image1.png + +# Import moduels from external python packages: https://pypi.org/ +from drawbot_skia.drawbot import * +from fontTools.ttLib import TTFont +from fontTools.misc.fixedTools import floatToFixedToStr + +# Import moduels from the Python Standard Library: https://docs.python.org/3/library/ +import subprocess +import sys +import argparse + +# Constants, these are the main "settings" for the image +WIDTH, HEIGHT, MARGIN, FRAMES = 2048, 1024, 128, 1 +FONT_PATH = "fonts/ttf/RadioCanadaDisplay-Regular.ttf" +FONT_LICENSE = "OFL v1.1" +AUXILIARY_FONT = "Helvetica" +AUXILIARY_FONT_SIZE = 48 + +BIG_TEXT = "AaBb" +BIG_TEXT_FONT_SIZE = 730 +BIG_TEXT_SIDE_MARGIN = MARGIN * 1 +BIG_TEXT_BOTTOM_MARGIN = MARGIN * 2 + +GRID_VIEW = False # Toggle this for a grid overlay + +# Handel the "--output" flag +# For example: $ python3 documentation/image1.py --output documentation/image1.png +parser = argparse.ArgumentParser() +parser.add_argument("--output", metavar="PNG", help="where to write the PNG file") +args = parser.parse_args() + +# Load the font with the parts of fonttools that are imported with the line: +# from fontTools.ttLib import TTFont +# Docs Link: https://fonttools.readthedocs.io/en/latest/ttLib/ttFont.html +ttFont = TTFont(FONT_PATH) + +# Constants that are worked out dynamically +MY_URL = subprocess.check_output("git remote get-url origin", shell=True).decode() +MY_HASH = subprocess.check_output("git rev-parse --short HEAD", shell=True).decode() +FONT_NAME = ttFont["name"].getDebugName(4) +FONT_VERSION = "v%s" % floatToFixedToStr(ttFont["head"].fontRevision, 16) + + +# Draws a grid +def grid(): + stroke(1, 0, 0, 0.75) + strokeWidth(2) + STEP_X, STEP_Y = 0, 0 + INCREMENT_X, INCREMENT_Y = MARGIN / 2, MARGIN / 2 + rect(MARGIN, MARGIN, WIDTH - (MARGIN * 2), HEIGHT - (MARGIN * 2)) + for x in range(29): + polygon((MARGIN + STEP_X, MARGIN), (MARGIN + STEP_X, HEIGHT - MARGIN)) + STEP_X += INCREMENT_X + for y in range(29): + polygon((MARGIN, MARGIN + STEP_Y), (WIDTH - MARGIN, MARGIN + STEP_Y)) + STEP_Y += INCREMENT_Y + polygon((WIDTH / 2, 0), (WIDTH / 2, HEIGHT)) + polygon((0, HEIGHT / 2), (WIDTH, HEIGHT / 2)) + + +# Remap input range to VF axis range +# This is useful for animation +# (E.g. sinewave(-1,1) to wght(100,900)) +def remap(value, inputMin, inputMax, outputMin, outputMax): + inputSpan = inputMax - inputMin # FIND INPUT RANGE SPAN + outputSpan = outputMax - outputMin # FIND OUTPUT RANGE SPAN + valueScaled = float(value - inputMin) / float(inputSpan) + return outputMin + (valueScaled * outputSpan) + + +# Draw the page/frame and a grid if "GRID_VIEW" is set to "True" +def draw_background(): + newPage(WIDTH, HEIGHT) + fill(0) + rect(-2, -2, WIDTH + 2, HEIGHT + 2) + if GRID_VIEW: + grid() + else: + pass + + +# Draw main text +def draw_main_text(): + fill(1) + stroke(None) + font(FONT_PATH) + fontSize(BIG_TEXT_FONT_SIZE) + # Adjust this line to center main text manually. + # TODO: This should be done automatically when drawbot-skia + # has support for textBox() and FormattedString + #text(BIG_TEXT, ((WIDTH / 2) - MARGIN * 4.75, (HEIGHT / 2) - MARGIN * 2.5)) + text(BIG_TEXT, (BIG_TEXT_SIDE_MARGIN, BIG_TEXT_BOTTOM_MARGIN)) + + +# Divider lines +def draw_divider_lines(): + stroke(1) + strokeWidth(5) + lineCap("round") + line((MARGIN, HEIGHT - (MARGIN * 1.5)), (WIDTH - MARGIN, HEIGHT - (MARGIN * 1.5))) + line((MARGIN, MARGIN + (MARGIN / 2)), (WIDTH - MARGIN, MARGIN + (MARGIN / 2))) + stroke(None) + + +# Draw text describing the font and it's git status & repo URL +def draw_auxiliary_text(): + # Setup + font(AUXILIARY_FONT) + fontSize(AUXILIARY_FONT_SIZE) + POS_TOP_LEFT = (MARGIN, HEIGHT - MARGIN * 1.25) + POS_TOP_RIGHT = (WIDTH - MARGIN, HEIGHT - MARGIN * 1.25) + POS_BOTTOM_LEFT = (MARGIN, MARGIN) + POS_BOTTOM_RIGHT = (WIDTH - MARGIN * 0.95, MARGIN) + URL_AND_HASH = MY_URL + "at commit " + MY_HASH + URL_AND_HASH = URL_AND_HASH.replace("\n", " ") + # Draw Text + text(FONT_NAME, POS_TOP_LEFT, align="left") + text(FONT_VERSION, POS_TOP_RIGHT, align="right") + text(URL_AND_HASH, POS_BOTTOM_LEFT, align="left") + text(FONT_LICENSE, POS_BOTTOM_RIGHT, align="right") + + +# Build and save the image +if __name__ == "__main__": + draw_background() + draw_main_text() + draw_divider_lines() + draw_auxiliary_text() + # Save output, using the "--output" flag location + saveImage(args.output) + # Print done in the terminal + print("DrawBot: Done") diff --git a/renovate.json b/renovate.json new file mode 100644 index 00000000..9f96c94f --- /dev/null +++ b/renovate.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "rangeStrategy": "bump" +} diff --git a/requirements-test.in b/requirements-test.in new file mode 100644 index 00000000..d3260664 --- /dev/null +++ b/requirements-test.in @@ -0,0 +1,2 @@ +fontbakery[googlefonts]>=0.9.2 +gftools[qa]>=0.9.23 diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 00000000..161ef17e --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,2 @@ +# Placeholder file, update the requirements by running `make update`. +-r requirements-test.in diff --git a/requirements.in b/requirements.in new file mode 100644 index 00000000..25d651b1 --- /dev/null +++ b/requirements.in @@ -0,0 +1,6 @@ +fontmake>=3.9.0 +gftools[qa]>=0.9.54 +drawbot-skia>=0.5.0 +sh>=2.0.6 +bumpfontversion>=0.4.1 +diffenator2>=0.3.8 diff --git a/requirements.txt b/requirements.txt index 8316d6d5..5dc91024 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,123 +1,2 @@ -absl-py==1.4.0 -appdirs==1.4.4 -attrs==23.1.0 -axisregistry==0.4.3 -babelfont==3.0.1 -beautifulsoup4==4.12.2 -beziers==0.5.0 -blackrenderer==0.6.0 -booleanOperations==0.9.0 -Brotli==1.0.9 -bump2version==1.0.1 -bumpfontversion==0.4.1 -cattrs==23.1.2 -certifi==2024.8.30 -cffi==1.15.1 -cffsubr==0.2.9.post1 -charset-normalizer==3.2.0 -click==8.1.6 -cmarkgfm==2022.10.27 -collidoscope==0.6.5 -colorlog==6.7.0 -commandlines==0.4.1 -compreffor==0.5.4 -cryptography==43.0.1 -cu2qu==1.6.7.post2 -defcon==0.10.2 -dehinter==4.0.0 -Deprecated==1.2.14 -diffenator2==0.2.12 -drawbot-skia==0.5.0 -exceptiongroup==1.1.3 -font-v==2.1.0 -fontbakery==0.11.2 -fontFeatures==1.8.0 -fontmake==3.7.1 -fontMath==0.9.3 -fonttools==4.43.1 -freetype-py==2.3.0 -fs==2.4.16 -gflanguages==0.5.4 -gftools==0.9.33 -gitdb==4.0.10 -GitPython==3.1.41 -glyphsets==0.6.2 -glyphsLib==6.3.0 -h11==0.14.0 -hyperglot==0.4.5 -idna==3.10 -importlib-resources==6.0.1 -Jinja2==3.1.4 -kurbopy==0.9.0 -lxml==4.9.3 -markdown-it-py==3.0.0 -MarkupSafe==2.1.3 -mdurl==0.1.2 -munkres==1.1.4 -nanoemoji==0.15.1 -ninja==1.11.1 -numpy==1.24.4 -openstep-plist==0.3.0.post1 -opentype-sanitizer==9.1.0 -opentypespec==1.9.1 -orjson==3.10.7 -outcome==1.2.0 -packaging==23.1 -picosvg==0.22.1 -pillow==10.4.0 -pip-api==0.0.30 -pngquant-cli==2.17.0.post5 -protobuf==3.20.3 -pyahocorasick==2.0.0 -pybind11==2.11.1 -pyclipper==1.3.0.post4 -pycparser==2.21 -pygit2==1.12.2 -PyGithub==1.59.1 -Pygments==2.16.1 -PyJWT==2.8.0 -PyNaCl==1.5.0 -pyparsing==3.1.1 -PySocks==1.7.1 -python-bidi==0.4.2 -python-dateutil==2.8.2 -PyYAML==6.0.1 -regex==2023.8.8 -requests==2.32.3 -resvg-cli==0.22.0.post3 -rich==13.5.2 -rstr==3.2.1 -selenium==4.11.2 -sh==2.0.6 -six==1.16.0 -skia-pathops==0.8.0 -skia-python==87.5 -smmap==5.0.0 -sniffio==1.3.0 -sortedcontainers==2.4.0 -soupsieve==2.4.1 -sre-yield==1.2 -statmake==0.6.0 -strictyaml==1.7.3 -stringbrewer==0.0.1 -tabulate==0.9.0 -toml==0.10.2 -tqdm==4.66.5 -trio==0.22.2 -trio-websocket==0.10.3 -ttfautohint-py==0.5.1 -typing_extensions==4.7.1 -ufo2ft==2.33.4 -ufoLib2==0.16.0 -ufolint==1.2.0 -uharfbuzz==0.37.2 -unicodedata2==15.0.0 -Unidecode==1.3.6 -urllib3==2.2.3 -vharfbuzz==0.2.0 -vttLib==0.12.0 -wrapt==1.15.0 -wsproto==1.2.0 -youseedee==0.3.0 -zipp==3.20.2 -zopfli==0.2.2 +# Placeholder file, update the requirements by running `make update`. +-r requirements.in diff --git a/scripts/customize.py b/scripts/customize.py new file mode 100644 index 00000000..f7feab42 --- /dev/null +++ b/scripts/customize.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +# This script is run by the user using `make customize` after the repository +# is cloned. If you are reading this because `make customize` failed, +# skip down to the section headed "INITIALIZATION STEPS". + +from sh import git +import datetime +import re +import sys +from urllib.parse import quote +import subprocess +import requests + +BASE_OWNER = "googlefonts" +BASE_REPONAME = "googlefonts-project-template" +DUMMY_URL = "https://yourname.github.io/your-font-repository-name" +LATEST_OFL = "https://raw.githubusercontent.com/googlefonts/googlefonts-project-template/main/OFL.txt" + + +def repo_url(owner, name): + return f"https://github.com/{owner}/{name}" + + +def web_url(owner, name): + return f"https://{owner}.github.io/{name}" + + +def raw_url(owner, name): + return f"https://raw.githubusercontent.com/{owner}/{name}" + + +def lose(msg, e=None): + print(msg) + print("You will need to do the initialization steps manually.") + print("Read scripts/customize.py for more instructions how to do this.") + if e: + print( + "\nHere's an additional error message which may help diagnose the problem." + ) + raise e + sys.exit(1) + + +try: + my_repo_url = git.remote("get-url", "origin") +except Exception as e: + lose("Could not use git to find my own repository URL", e) + +m = re.match(r"(?:https://github.com/|git@github.com:)(.*)/(.*)/?", str(my_repo_url)) +if not m: + lose( + f"My git repository URL ({my_repo_url}) didn't look what I expected - are you hosting this on github?" + ) + +owner, reponame = m[1], m[2] + +if owner == BASE_OWNER and reponame == BASE_REPONAME: + print("I am being run on the upstream repository; don't do that") + sys.exit() + +# INITIALIZATION STEPS + +# First, the README file contains URLs to pages in the `gh-pages` branch of the +# repo. When initially cloned, these URLs will point to the +# googlefonts/Unified-Font-Repository itself. But downstream users want links +# and badges about their own font, not ours! So any URLs need to be adjusted to +# refer to the end user's repository. + +# We will also pin the dependencies so future builds are reproducible. + +readme = open("README.md").read() +ghpages_url = web_url(owner, reponame) +project_url = repo_url(owner, reponame) + +print("Fixing URLs:", web_url(BASE_OWNER, BASE_REPONAME), "->", ghpages_url) + +readme = readme.replace(web_url(BASE_OWNER, BASE_REPONAME), ghpages_url) +# In the badges, the URLs to raw.githubusercontent.com are URL-encoded as they +# are passed to shields.io. +readme = readme.replace( + quote(raw_url(BASE_OWNER, BASE_REPONAME), safe=""), + quote(raw_url(owner, reponame), safe=""), +) + +print("Fixing URLs:", DUMMY_URL, "->", ghpages_url) +readme = readme.replace(f"`{DUMMY_URL}`", ghpages_url) + +with open("README.md", "w") as fh: + fh.write(readme) + +git.add("README.md") + +# Fix the OFL +year = datetime.date.today().year +title = reponame.title() +copyright = f"Copyright {year} The {title} Project Authors ({project_url})\n" +print("Fetching the latest OFL..") +ofl = requests.get(LATEST_OFL).text.splitlines() +print("Writing an OFL for you") +print(copyright) +with open("OFL.txt", "w") as fh: + fh.write(copyright) + fh.write("\n".join(ofl[1:])) + +git.add("OFL.txt") + +# Pin the dependencies +print("Pinning dependencies") +dependencies = subprocess.check_output(["pip", "freeze"]) +with open("requirements.txt", "wb") as dependency_file: + dependency_file.write(dependencies) +git.add("requirements.txt") + +# Did anything change? +result = git.status("--porcelain") +if any(line.startswith("M ") for line in result.splitlines()): + git.commit("-m", "Customize repository") + + print("Pushing changes to GitHub") + git.push() +else: + print("Nothing changed, no need to push") diff --git a/scripts/index.html b/scripts/index.html index d297c3c4..07bb551a 100644 --- a/scripts/index.html +++ b/scripts/index.html @@ -3,10 +3,10 @@ - LibertineSuper development + My Font development -

LibertineSuper testing pages

+

My Font testing pages