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