ttf-geom-hinted

LOW
maintainer gaougalos 0 votes scanned 2026-11-03 02:04:04.155120
View on AUR
Why flagged

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

Triggered rules

Low Few votes, recently uploaded zero_votes_recent

Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.

PKGBUILD

1# Maintainer: gaou-piou <i.am.piou@gmail.com>
2pkgname=ttf-geom-hinted
3_gmver=1.102
4_gfcommit=a60a77e14f28abd4ef243a1b5dfc48df0cec5205
5_nfver=3.5.1
6pkgver="${_gmver}"
7pkgrel=1
8pkgdesc='Geom (Google Fonts), a geometric sans with a wght axis and Greek, re-hinted with ttfautohint for FreeType (optionally static / Nerd Fonts patched)'
9arch=('any')
10url='https://fonts.google.com/specimen/Geom'
11license=('OFL-1.1')
12makedepends=('python' 'python-fonttools' 'fontforge' 'parallel' 'ttfautohint')
13options=(!strip)
14provides=('ttf-geom')
15conflicts=('ttf-geom' 'geom-ttf-hinted')
16source=(
17 "GeomVF.ttf::https://raw.githubusercontent.com/google/fonts/${_gfcommit}/ofl/geom/Geom%5Bwght%5D.ttf"
18 "GeomItalicVF.ttf::https://raw.githubusercontent.com/google/fonts/${_gfcommit}/ofl/geom/Geom-Italic%5Bwght%5D.ttf"
19 "OFL.txt::https://raw.githubusercontent.com/google/fonts/${_gfcommit}/ofl/geom/OFL.txt"
20 "font-patcher-${_nfver}.zip::https://github.com/ryanoasis/nerd-fonts/releases/download/v${_nfver}/FontPatcher.zip"
21 "make_statics.py"
22 "make_features.py"
23 "set_gasp.py"
24 "measure.py"
25 "README.md"
26 "FEATURES.md"
27)
28noextract=("font-patcher-${_nfver}.zip")
29sha256sums=('4509ad62e97c2e07c7fbc51180caba092b66fb2967e4de7dcba149ab3beb3b15'
30 'f448d04a281a0e8198a109e1809e145ffd5567a26299c8b2b772297de17500ad'
31 '614e89d16af045c1c32716f67d1e826c692cf643c549cba46b38d41d6919d77b'
32 '42bcb32145499a35732274c7fc48deb434ad0d2e0e118f98527c1479c6fa251a'
33 '1ad9748de7280a3f70acf49e21bfb505818db3f097f75d4fa11b8119ea03b18b'
34 '200fc13d7cf288ebd10c2832a0c9e1cf5a8b7c7e4e6283311778a2df7057581e'
35 '0b0464b268525569b5fa28b4735791efb22f22829ad178629776ae3ea82d7f99'
36 '3d45aadde50db7e27a9ff33a00de44dc8bada3f5cd6b9afb2e5344dc86efae1f'
37 'a802ddcf008a042ac2e2b0bf77c56769f61621dc5893fdb27f7e71c83fa74664'
38 '8eccb99941b863aa4070211dc2819cd829ad1b76ed1dead5e3f51eca22d9515c')
39
40# ── What this package does ──────────────────────────────────────────────────
41#
42# Geom (Thanos Poulakidas, added to Google Fonts 2025-11-14) is a geometric
43# sans shipped as two one-axis variable fonts: Geom[wght].ttf (upright) and
44# Geom-Italic[wght].ttf (-10 degrees), wght 300-900, default 400. It covers
45# Latin (incl. Latin Extended-A) and modern monotonic Greek; no Cyrillic. The
46# sources are pinned to the google/fonts commit above.
47#
48# Upstream ships NO hinting (no fpgm/cvt, glyphs without instructions, a tiny
49# prep). At hintstyle hintmedium/hintfull FreeType then treats the face as
50# hinted and does not run its autohinter: Geom renders completely unhinted and
51# the i/j/ï/ϊ dots touch the letters at small sizes (README.md section 3).
52# This package runs ttfautohint over it. See README.md for the measurements
53# and FEATURES.md for what the font can do.
54#
55# ttfautohint takes its blue zones from the default master (Regular). At
56# 700-900 a static, hinted on its own, is clearly closer to the outline than the
57# variable font (Black: dev 5.8 vs 14.4). The variable font stays the default
58# because one file keeps every weight; GM_VARIANT=static is the better choice
59# if you mostly use the heavy weights.
60#
61# FreeType only runs TrueType bytecode at hintstyle hintmedium/hintfull. The
62# package ships (not enabled) /usr/share/fontconfig/conf.avail/80-$pkgname.conf
63# that turns it on for the installed families, excluding Chromium/Electron by
64# prgname (at device scale 1 they round every advance at hintmedium).
65#
66# ── Build-time options ───────────────────────────────────────────────────────
67#
68# Run from a terminal, prepare() asks for NERD_PATCH, GM_VARIANT, FEATURE_DEFAULTS,
69# HINTING and HINT_PRESET (Enter keeps the default). Anything already set in the
70# environment is not asked. Without a TTY the environment / defaults apply.
71# Answers are saved to $srcdir/.build_opts.
72#
73# GM_VARIANT variable|static (default: variable)
74# variable the two variable fonts (upright + italic)
75# static one TTF per weight (and italic), cut with the
76# fontTools instancer and hinted on its own
77# STATIC_WEIGHTS "300 ... 900" wght values to cut (default: all seven)
78# STATIC_ITALIC true/false also cut the italic (default true)
79#
80# NERD_PATCH true/false Patch with Nerd Fonts glyphs (default: false).
81# font-patcher drops fvar/gvar, so this forces
82# GM_VARIANT=static. Family "Geom Nerd Font (Mono|Propo)".
83#
84# HINTING true/false Hint with ttfautohint (default: true).
85#
86# HINT_PRESET natural|balanced|sharp|light|custom (default: natural)
87# natural stem=nnn range 8-48 x-height 0 (closest to the
88# outline; default)
89# balanced stem=qsq range 8-48 x-height 14 (ttfautohint
90# defaults; opens
91# a few more dots,
92# same dev at 400)
93# sharp stem=sss range 6-48 x-height 14 (higher dev)
94# light stem=nnn range 12-48 x-height 0 (HiDPI)
95# custom use the HINT_* variables below verbatim
96# Individual knobs (override the preset; empty = preset value):
97# HINT_MODE HINT_RANGE_MIN HINT_RANGE_MAX HINT_LIMIT HINT_XHEIGHT
98# HINT_XSNAP_EXC HINT_DEFAULT_SCRIPT HINT_FALLBACK_SCRIPT HINT_WINCOMPAT
99# HINT_TTFA_TABLE HINT_FAMILY_SUFFIX HINT_INTEGER_PPEM (off: it grows text on
100# Linux, +16-19% ink at small sizes) GASP_MODE keep|sized|smooth|gridfit
101#
102# FEATURE_DEFAULTS "tag,tag,..." (default: empty = leave the fonts alone)
103# Bake these GSUB features into calt so EVERY renderer applies
104# them (fontconfig fontfeatures only reaches pango). Geom's
105# candidates: frac, sups, case (see FEATURES.md); liga is
106# already on in every shaper. make_features.py refuses
107# aalt/ordn/dlig. None is right for running text: frac and
108# sups fire inside ordinary words.
109# FEATURE_FAMILY "Name" Install the result under this family instead.
110#
111# Examples:
112# makepkg -si (asks, when run from a terminal)
113# makepkg -si </dev/null (never asks: defaults only)
114# GM_VARIANT=static makepkg -si
115# HINT_PRESET=balanced makepkg -si
116# NERD_PATCH=true STATIC_WEIGHTS="400 700" makepkg -si
117# ────────────────────────────────────────────────────────────────────────────
118
119_opt_keys=(GM_VARIANT FEATURE_DEFAULTS FEATURE_FAMILY
120 STATIC_WEIGHTS STATIC_ITALIC NERD_PATCH
121 HINTING HINT_PRESET HINT_MODE HINT_RANGE_MIN HINT_RANGE_MAX
122 HINT_LIMIT HINT_XHEIGHT HINT_XSNAP_EXC HINT_DEFAULT_SCRIPT
123 HINT_FALLBACK_SCRIPT HINT_WINCOMPAT HINT_TTFA_TABLE
124 HINT_FAMILY_SUFFIX HINT_INTEGER_PPEM GASP_MODE)
125
126_ask_yn() {
127 local _ans
128 read -r -p " $1? [$2] " _ans || _ans=""
129 [[ "${_ans:-$2}" =~ ^[yY] ]] && _yn=true || _yn=false
130}
131
132# _ask_choice TITLE DEFAULT KEY:description ... -> sets _choice to a KEY.
133_ask_choice() {
134 local _title="$1" _default="$2"; shift 2
135 local -a _items=("$@")
136 local _i _ans
137 echo " $_title:"
138 for _i in "${!_items[@]}"; do
139 printf " %d) %-12s %s%s\n" "$((_i + 1))" "${_items[$_i]%%:*}" "${_items[$_i]#*:}" \
140 "$([[ "${_items[$_i]%%:*}" == "$_default" ]] && echo " (default)")"
141 done
142 while :; do
143 read -r -p " > " _ans || _ans=""
144 if [[ -z "$_ans" ]]; then _choice="$_default"; return; fi
145 if [[ "$_ans" =~ ^[0-9]+$ ]] && (( _ans >= 1 && _ans <= ${#_items[@]} )); then
146 _choice="${_items[$((_ans - 1))]%%:*}"; return
147 fi
148 echo " Enter 1-${#_items[@]}, or press Enter for $_default."
149 done
150}
151
152_prompt_options() {
153 if [[ -t 0 ]]; then
154 echo ""
155 echo " $pkgname: build options (Enter = default)"
156 echo ""
157 if [[ -z "${NERD_PATCH:-}" ]]; then
158 _ask_yn "Patch with Nerd Fonts glyphs (forces static fonts)" n; NERD_PATCH=$_yn
159 fi
160 if [[ "$NERD_PATCH" != true && -z "${GM_VARIANT:-}" ]]; then
161 _ask_choice "Font set" variable \
162 "variable:two wght-axis fonts, upright + italic (recommended)" \
163 "static:one file per weight/italic, hinted per weight"
164 GM_VARIANT=$_choice
165 fi
166 if [[ "${FEATURE_DEFAULTS+set}" != set ]]; then
167 echo ""
168 echo " A font cannot declare a feature \"on by default\"; baking moves its lookups"
169 echo " into calt, which every program applies (see the header of this PKGBUILD)."
170 _ask_choice "Bake features into calt" none \
171 "none:leave the fonts as upstream ships them (default)" \
172 "custom:type the tag list yourself"
173 case $_choice in
174 none) FEATURE_DEFAULTS="" ;;
175 custom)
176 echo " Tags, comma or space separated (e.g. \"case,frac\"):"
177 read -r -p " > " _tags || _tags=""
178 _tags="${_tags//[[:space:]]/,}"
179 while [[ "$_tags" == *,,* ]]; do _tags="${_tags//,,/,}"; done
180 _tags="${_tags#,}"; _tags="${_tags%,}"
181 FEATURE_DEFAULTS="$_tags" ;;
182 esac
183 fi
184 if [[ -z "${HINTING:-}" ]]; then
185 _ask_yn "Hint with ttfautohint (n = unhinted, as upstream)" y; HINTING=$_yn
186 fi
187 if [[ "$HINTING" == true && -z "${HINT_PRESET:-}" ]]; then
188 _ask_choice "Hinting preset" natural \
189 "natural:stem n, 8-48px, no x-height boost (closest to the design)" \
190 "balanced:stem q, 8-48px (opens the dots, a few more dots open)" \
191 "sharp:stem s, 6-48px (highest contrast, higher dev)" \
192 "light:stem n, 12-48px, no x-height boost (HiDPI)" \
193 "custom:use the HINT_* environment variables"
194 HINT_PRESET=$_choice
195 fi
196 echo ""
197 else
198 echo "==> Non-interactive build (no TTY): using environment variables / defaults."
199 fi
200
201 local _k
202 : > "$srcdir/.build_opts"
203 for _k in "${_opt_keys[@]}"; do
204 # "set" rather than non-empty: HINT_XSNAP_EXC="" differs from unset.
205 if [[ "${!_k+set}" == set ]]; then
206 printf '%s=%s\n' "$_k" "${!_k}" >> "$srcdir/.build_opts"
207 fi
208 done
209}
210
211# makepkg runs build() and package() in separate shells, so both call this.
212_resolve_options() {
213 local _k _v
214 if [[ ! -f "$srcdir/.build_opts" ]]; then
215 echo "Error: $srcdir/.build_opts missing; run a full makepkg (prepare() writes it)." >&2
216 exit 1
217 fi
218 while IFS='=' read -r _k _v; do
219 if [[ " ${_opt_keys[*]} " == *" $_k "* ]]; then
220 printf -v "$_k" '%s' "$_v"
221 fi
222 done < "$srcdir/.build_opts"
223
224 GM_VARIANT="${GM_VARIANT:-variable}"
225 FEATURE_DEFAULTS="${FEATURE_DEFAULTS:-}"
226 FEATURE_FAMILY="${FEATURE_FAMILY:-}"
227 STATIC_WEIGHTS="${STATIC_WEIGHTS:-300 400 500 600 700 800 900}"
228 STATIC_ITALIC="${STATIC_ITALIC:-true}"
229 NERD_PATCH="${NERD_PATCH:-false}"
230 HINTING="${HINTING:-true}"
231 HINT_PRESET="${HINT_PRESET:-natural}"
232 GASP_MODE="${GASP_MODE:-keep}"
233 HINT_WINCOMPAT="${HINT_WINCOMPAT:-false}"
234 HINT_TTFA_TABLE="${HINT_TTFA_TABLE:-false}"
235 HINT_INTEGER_PPEM="${HINT_INTEGER_PPEM:-false}"
236 HINT_DEFAULT_SCRIPT="${HINT_DEFAULT_SCRIPT:-latn}"
237 HINT_FALLBACK_SCRIPT="${HINT_FALLBACK_SCRIPT:-latn}"
238
239 case "$GM_VARIANT" in
240 variable|static) ;;
241 *) echo "Error: GM_VARIANT='$GM_VARIANT' invalid (variable|static)." >&2; exit 1 ;;
242 esac
243 for _v in STATIC_ITALIC NERD_PATCH HINTING HINT_WINCOMPAT HINT_TTFA_TABLE HINT_INTEGER_PPEM; do
244 case "${!_v}" in
245 true|false) ;;
246 *) echo "Error: $_v='${!_v}' must be true or false." >&2; exit 1 ;;
247 esac
248 done
249 # font-patcher drops fvar/gvar, so patching always works on statics.
250 if [[ "$NERD_PATCH" == true && "$GM_VARIANT" == variable ]]; then
251 echo "==> Note: the variable font cannot be Nerd-patched; using GM_VARIANT=static."
252 GM_VARIANT=static
253 fi
254 for _v in ${FEATURE_DEFAULTS//,/ }; do
255 if [[ ! "$_v" =~ ^[A-Za-z0-9]{4}$ ]]; then
256 echo "Error: FEATURE_DEFAULTS: '$_v' is not a feature tag (e.g. case)." >&2
257 exit 1
258 fi
259 done
260 for _v in $STATIC_WEIGHTS; do
261 case "$_v" in
262 300|400|500|600|700|800|900) ;;
263 *) echo "Error: STATIC_WEIGHTS: '$_v' is not 300, 400, ... 900." >&2; exit 1 ;;
264 esac
265 done
266
267 local _m _lo _hi _xh
268 case "$HINT_PRESET" in
269 natural) _m=nnn; _lo=8; _hi=48; _xh=0 ;;
270 balanced) _m=qsq; _lo=8; _hi=48; _xh=14 ;;
271 sharp) _m=sss; _lo=6; _hi=48; _xh=14 ;;
272 light) _m=nnn; _lo=12; _hi=48; _xh=0 ;;
273 custom) _m=nnn; _lo=8; _hi=48; _xh=0 ;;
274 *)
275 echo "Error: unknown HINT_PRESET='$HINT_PRESET'." >&2
276 echo " Valid: natural balanced sharp light custom" >&2
277 exit 1 ;;
278 esac
279 HINT_MODE="${HINT_MODE:-$_m}"
280 HINT_RANGE_MIN="${HINT_RANGE_MIN:-$_lo}"
281 HINT_RANGE_MAX="${HINT_RANGE_MAX:-$_hi}"
282 HINT_LIMIT="${HINT_LIMIT:-$HINT_RANGE_MAX}"
283 HINT_XHEIGHT="${HINT_XHEIGHT:-$_xh}"
284
285 if [[ ! "$HINT_MODE" =~ ^[nqs]{3}$ ]]; then
286 echo "Error: HINT_MODE='$HINT_MODE' must be 3 chars from n/q/s (e.g. nnn)." >&2
287 exit 1
288 fi
289 for _v in HINT_RANGE_MIN HINT_RANGE_MAX HINT_LIMIT HINT_XHEIGHT; do
290 if [[ ! "${!_v}" =~ ^[0-9]+$ ]]; then
291 echo "Error: $_v='${!_v}' must be a non-negative integer." >&2; exit 1
292 fi
293 done
294 if (( HINT_RANGE_MIN > HINT_RANGE_MAX )); then
295 echo "Error: HINT_RANGE_MIN ($HINT_RANGE_MIN) > HINT_RANGE_MAX ($HINT_RANGE_MAX)." >&2
296 exit 1
297 fi
298 for _v in HINT_DEFAULT_SCRIPT HINT_FALLBACK_SCRIPT; do
299 if [[ ! "${!_v}" =~ ^[a-z0-9]{3,4}$ ]]; then
300 echo "Error: $_v='${!_v}' must be a script tag (e.g. latn, none)." >&2; exit 1
301 fi
302 done
303 case "$GASP_MODE" in
304 keep|sized|smooth|gridfit) ;;
305 *) echo "Error: GASP_MODE='$GASP_MODE' invalid (keep|sized|smooth|gridfit)." >&2; exit 1 ;;
306 esac
307}
308
309prepare() {
310 _prompt_options
311 _resolve_options # validate now, so a typo fails before the long steps
312
313 rm -rf "$srcdir/font-patcher"
314 if [[ "$NERD_PATCH" == true ]]; then
315 mkdir -p "$srcdir/font-patcher"
316 bsdtar xf "$srcdir/font-patcher-${_nfver}.zip" -C "$srcdir/font-patcher"
317 fi
318}
319
320# _bake_features SRCDIR: move the lookups of FEATURE_DEFAULTS into calt into
321# $srcdir/featured. Last step on purpose: ttfautohint never sees them.
322_bake_features() {
323 local _src="$1" _fam=()
324 [[ -n "$FEATURE_DEFAULTS" ]] || return 0
325 [[ -n "$FEATURE_FAMILY" ]] && _fam=(--family "$FEATURE_FAMILY")
326 echo "==> Baking $FEATURE_DEFAULTS into calt" \
327 "${FEATURE_FAMILY:+(installed as '$FEATURE_FAMILY')}..."
328 python "$srcdir/make_features.py" --features "$FEATURE_DEFAULTS" \
329 "${_fam[@]+"${_fam[@]}"}" -o "$srcdir/featured" "$_src"/*.ttf
330}
331
332build() {
333 _resolve_options
334
335 echo "==> Options: variant=$GM_VARIANT nerd=$NERD_PATCH hinting=$HINTING"
336 if [[ "$GM_VARIANT" == static ]]; then
337 echo "==> Statics: weights='$STATIC_WEIGHTS' italic=$STATIC_ITALIC"
338 fi
339 if [[ "$HINTING" == true ]]; then
340 echo "==> ttfautohint: preset=$HINT_PRESET stem=$HINT_MODE" \
341 "range=$HINT_RANGE_MIN-$HINT_RANGE_MAX limit=$HINT_LIMIT x-height=$HINT_XHEIGHT" \
342 "x-snap-exc='${HINT_XSNAP_EXC-<default>}' gasp=$GASP_MODE integer-ppem=$HINT_INTEGER_PPEM" \
343 "ttfa-table=$HINT_TTFA_TABLE${HINT_FAMILY_SUFFIX:+ suffix='$HINT_FAMILY_SUFFIX'}"
344 fi
345
346 rm -rf "$srcdir/selected" "$srcdir/patched" "$srcdir/hinted" "$srcdir/featured"
347 mkdir -p "$srcdir/selected" "$srcdir/patched" "$srcdir/hinted"
348
349 # ── Step 1: select ──────────────────────────────────────────────────────────
350 if [[ "$GM_VARIANT" == variable ]]; then
351 install -m644 "$srcdir/GeomVF.ttf" "$srcdir/selected/GeomVariable.ttf"
352 install -m644 "$srcdir/GeomItalicVF.ttf" "$srcdir/selected/GeomItalicVariable.ttf"
353 else
354 echo "==> Cutting static instances..."
355 local _w
356 for _w in $STATIC_WEIGHTS; do
357 python "$srcdir/make_statics.py" --wght "$_w" -o "$srcdir/selected" "$srcdir/GeomVF.ttf"
358 if [[ "$STATIC_ITALIC" == true ]]; then
359 python "$srcdir/make_statics.py" --wght "$_w" --italic -o "$srcdir/selected" "$srcdir/GeomItalicVF.ttf"
360 fi
361 done
362 fi
363 local _count
364 _count=$(find "$srcdir/selected" -name '*.ttf' | wc -l)
365 echo "==> Selected $_count font file(s)."
366 if (( _count == 0 )); then
367 echo "Error: no fonts produced." >&2; exit 1
368 fi
369
370 local _hintsrc="$srcdir/selected"
371
372 # ── Step 2: Nerd Fonts patching ─────────────────────────────────────────────
373 # Patch first, hint afterwards: font-patcher does not keep hint bytecode.
374 if [[ "$NERD_PATCH" == true ]]; then
375 echo "==> Patching with Nerd Fonts glyphs (this takes a while)..."
376 find "$srcdir/selected" -type f | sort | \
377 parallel --will-cite -j"$(nproc)" python "$srcdir/font-patcher/font-patcher" \
378 --variable-width-glyphs -q -c {} -out "$srcdir/patched" '>/dev/null'
379 _count=$(find "$srcdir/patched" -maxdepth 1 -name '*.ttf' | wc -l)
380 if (( _count == 0 )); then
381 echo "Error: font-patcher produced no output. See messages above." >&2; exit 1
382 fi
383 echo "==> Patched $_count font(s)."
384 _hintsrc="$srcdir/patched"
385 fi
386
387 if [[ "$HINTING" != true ]]; then
388 _bake_features "$_hintsrc"
389 return 0
390 fi
391
392 # ── Step 3: ttfautohint ─────────────────────────────────────────────────────
393 local -a _ta_opts=(
394 --hinting-range-min="$HINT_RANGE_MIN"
395 --hinting-range-max="$HINT_RANGE_MAX"
396 --hinting-limit="$HINT_LIMIT"
397 --increase-x-height="$HINT_XHEIGHT"
398 --stem-width-mode="$HINT_MODE"
399 --default-script="$HINT_DEFAULT_SCRIPT"
400 --ignore-restrictions
401 )
402 if [[ "$NERD_PATCH" == true ]]; then
403 _ta_opts+=(--fallback-script=none --fallback-scaling)
404 else
405 _ta_opts+=(--fallback-script="$HINT_FALLBACK_SCRIPT")
406 fi
407 if [[ "${HINT_XSNAP_EXC+set}" == set ]]; then
408 _ta_opts+=(--x-height-snapping-exceptions="$HINT_XSNAP_EXC")
409 fi
410 if [[ "$HINT_WINCOMPAT" == true ]]; then _ta_opts+=(--windows-compatibility); fi
411 if [[ -n "${HINT_FAMILY_SUFFIX:-}" ]]; then _ta_opts+=(--family-suffix="$HINT_FAMILY_SUFFIX"); fi
412 if [[ "$HINT_TTFA_TABLE" == true ]]; then _ta_opts+=(--ttfa-table); else _ta_opts+=(--no-info); fi
413
414 # Serial on purpose: GNU parallel splits arguments that contain spaces.
415 echo "==> Hinting with ttfautohint..."
416 local _f
417 for _f in "$_hintsrc"/*.ttf; do
418 ttfautohint "${_ta_opts[@]}" "$_f" "$srcdir/hinted/${_f##*/}"
419 done
420
421 if [[ "$HINT_INTEGER_PPEM" == true ]]; then
422 echo "==> Setting head.flags bit 3 (integer ppem)..."
423 python - "$srcdir/hinted/"*.ttf <<'PY'
424import sys
425from fontTools.ttLib import TTFont
426for path in sys.argv[1:]:
427 font = TTFont(path)
428 font["head"].flags |= 1 << 3
429 font.save(path)
430PY
431 fi
432
433 if [[ "$GASP_MODE" != keep ]]; then
434 echo "==> Applying gasp mode '$GASP_MODE'..."
435 python "$srcdir/set_gasp.py" "$GASP_MODE" "$srcdir/hinted/"*.ttf
436 fi
437
438 _bake_features "$srcdir/hinted"
439}
440
441package() {
442 _resolve_options
443
444 local _out="$srcdir/selected"
445 if [[ "$HINTING" == true ]]; then
446 _out="$srcdir/hinted"
447 elif [[ "$NERD_PATCH" == true ]]; then
448 _out="$srcdir/patched"
449 fi
450 if [[ -n "$FEATURE_DEFAULTS" ]]; then _out="$srcdir/featured"; fi
451 if ! compgen -G "$_out/*.ttf" >/dev/null; then
452 echo "Error: no fonts to install in $_out." >&2; exit 1
453 fi
454 local _fontdir="$pkgdir/usr/share/fonts/geom"
455 install -Dm644 -t "$_fontdir" "$_out/"*.ttf
456 install -Dm644 "$srcdir/OFL.txt" "$pkgdir/usr/share/licenses/$pkgname/OFL.txt"
457
458 # Opt-in rendering tweak: bytecode hinting for the families this build
459 # installed. Shipped in conf.avail and deliberately not enabled.
460 if [[ "$HINTING" == true ]]; then
461 local _avail="$pkgdir/usr/share/fontconfig/conf.avail"
462 install -d "$_avail"
463 local _fam _conf="$_avail/80-$pkgname.conf"
464 local _chromium_prgnames=(chrome chromium brave helium electron code slack signal-desktop vesktop)
465 local _prg _prgtests=""
466 for _prg in "${_chromium_prgnames[@]}"; do
467 _prgtests+=" <test qual=\"all\" name=\"prgname\" compare=\"not_eq\"><string>$_prg</string></test>"$'\n'
468 done
469 {
470 echo '<?xml version="1.0" encoding="UTF-8"?>'
471 echo '<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">'
472 echo "<!-- Installed by $pkgname. NOT enabled by default. Enable with:"
473 echo ""
474 echo " sudo ln -s /usr/share/fontconfig/conf.avail/80-$pkgname.conf /etc/fonts/conf.d/"
475 echo ""
476 echo " Use the ttfautohint bytecode hints in these fonts rather than"
477 echo " FreeType's light autohinter. hintmedium, not hintfull: same rendering"
478 echo " in cairo/pango, and Blink keeps subpixel positioning at hintmedium."
479 echo " Chromium and Electron apps are excluded: at device scale 1 they use"
480 echo " linear advances only for hintslight/none, so hintmedium would round"
481 echo " every glyph advance to a whole pixel (uneven letter gaps)."
482 echo " Firefox also rounds advances at hintmedium unless"
483 echo " gfx.text.subpixel-position.force-enabled is true. See README.md. -->"
484 echo '<fontconfig>'
485 while IFS= read -r _fam; do
486 _fam="${_fam//&/&amp;}"; _fam="${_fam//</&lt;}"
487 cat <<EOF
488 <match target="font">
489 <test name="family" compare="eq"><string>$_fam</string></test>
490${_prgtests%$'\n'}
491 <edit name="hinting" mode="assign"><bool>true</bool></edit>
492 <edit name="autohint" mode="assign"><bool>false</bool></edit>
493 <edit name="hintstyle" mode="assign"><const>hintmedium</const></edit>
494 </match>
495EOF
496 done < <(python - "$_fontdir/"*.ttf <<'PY' | sort -u
497import sys
498from fontTools.ttLib import TTFont
499for path in sys.argv[1:]:
500 name = TTFont(path, lazy=True)["name"]
501 print(name.getDebugName(16) or name.getDebugName(1))
502PY
503)
504 echo '</fontconfig>'
505 } > "$_conf"
506 chmod 644 "$_conf"
507 fi
508
509 install -Dm644 -t "$pkgdir/usr/share/doc/$pkgname" "$srcdir/README.md" "$srcdir/FEATURES.md"
510}
511

Scan history

Scanned at (UTC)SeverityRules
2026-11-03 02:04:04 Low 1
2026-11-03 00:04:01 Low 1

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion