# BST-TIMEOUT: 600 # 55 cases, FOUR of them runs of the 7.8 MB # # data/freetype-probe. MEASURED at elapsed=37s on a fresh # # guest (2026-08-25, local runner, unloaded), reproduced # # exactly on two independent clean boots. Set from the # # ==BST-SUITE elapsed= line, not guessed. That is the same # # figure as 99-ttf-bitstream-vera, which runs the probe ten # # times over thirteen smaller files where this runs it four # # times over 1.36 MB, and the bound is vera's and # # 99-ttf-inconsolata's for the reason vera's header gives: # # all three drive the SAME probe binary, and a suite whose # # cost is dominated by one binary should not claim a # # different bound for it. 16x the measurement, so a hung # # suite costs ten minutes of a sweep rather than thirty -- # # which is not academic here, see the consumer block. # # ttf-gentium 1.02 -- Gentium, SIL's serif family for extended Latin, Greek and # Cyrillic. meta-openembedded meta-oe/recipes-graphics/ttf-fonts/ttf-gentium_1.02.bb. # # WHAT THIS IMAGE ACTUALLY INSTALLS, MEASURED OFF THE BUILT PACKAGES, NOT # ASSUMED: SIX files in TWO packages, and there is no -doc package anywhere. # # FILES_INFO:ttf-gentium {"/usr/share/doc/ttf-gentium/OFL": 4428, # ".../truetype/GenI102.ttf": 314476, # ".../truetype/GenR102.ttf": 362664} # FILES_INFO:ttf-gentium-alt {"/usr/share/doc/ttf-gentium-alt/OFL": 4428, # ".../truetype/GenAI102.ttf": 315860, # ".../truetype/GenAR102.ttf": 364056} # # THE PACKAGING DECISION IS THE EXACT OPPOSITE OF ttf-inconsolata'S, WHICH IS # WHY IT IS WORTH STATING RATHER THAN INHERITING. That recipe names the licence # text in FILES:${PN} and does not get it, because the default ${PN}-doc is # ordered first and packaging is first-match-wins. This recipe cannot lose it the # same way: `PACKAGES = "${PN} ${PN}-alt"` is an ASSIGNMENT that drops ${PN}-doc # from the list entirely, so no -doc package exists to claim ${docdir} and each # FILES:${PN}[-alt] keeps its own ${datadir}/doc/... entry. Two packages, two # licence copies, no third package -- and `pkg-no-doc-package` asserts that # absence, because "the -doc line was forgotten" and "there is no -doc package by # design" look identical from the file layer alone. # # ONE SOURCE FILE, TWO INSTALLED COPIES, AND THAT IS DELIBERATE. # do_install:append installs ${S}/OFL into both doc directories, so the two # entries share a sha256. Each package is separately installable and OFL-1.0 # permits redistribution only with the notice included, so neither copy is # redundant. Both faces additionally carry name IDs 13 and 14 in their own name # tables -- unlike Inconsolata, whose OFL.txt is the only copy of its licence on # the image -- so here the file is the belt to the name table's braces. # # FOUR LAYERS, AND A RED IN AN EARLIER ONE LOCALISES A RED IN A LATER ONE: # # file-*, ttf-*, the payload arrived intact -- size, bytes, mode, type -- # doc-*, cotenant-* and the directories this port shares were not disturbed. # No font machinery involved at all. # pkg-*, postinst-* the two packages the image really installs, the fontcache # class's RDEPENDS, and the deferred first-boot scriptlet. # ft-* the image's OWN freetype PARSES all four faces through its # TrueType driver and agrees about num_faces, num_glyphs, # units_per_EM, family and style. This is the layer the # ticket asks for by name. # fcq-*, fc-* fontconfig's independent parse (fc-scan, against a native # x86-64 control), then discovery and matching THROUGH THE # CACHE, which is a different path again. # # THIS IS THE FIRST PACKAGE ON THIS IMAGE TO SHARE A FONT DIRECTORY. Every # earlier font port owned its directory outright. /usr/share/fonts/truetype was # created by ttf-inconsolata one ticket ago and this port moves in beside it, so # the co-tenant risk here is not a filename collision -- there is none, the four # Gen*.ttf names are unique -- but a do_install or packaging change that made one # package claim the whole directory. ttf.inc's do_install is a bare # `find -exec install` into that shared path, so `cotenant-inconsolata` is a real # guard rather than a theoretical one, and 99-ttf-inconsolata asserts its own # file from the other side so a disagreement is visible. # # ONE NEIGHBOUR HAD TO BE AMENDED, AND IT IS THE ONE THAT AMENDED ITS OWN # NEIGHBOURS LAST TICKET. 99-ttf-inconsolata's `ttf-no-extras` read # `base(p) != "Inconsolata.ttf"` -- red on ANY co-tenant -- under a comment # claiming it was scoped so that "the day a second Debian-layout font lands this # case reports on Inconsolata rather than on its new co-tenant". The comment # described the intent; the code did the opposite. It is now scoped to # Inconsolata's own basenames, which is what the comment always said it was. # # THIS PORT TAKES OVER NO GENERIC, AND THAT IS ASSERTED RATHER THAN ASSUMED. # ttf-inconsolata took `monospace` from Liberation Mono because fontconfig's # shipped 60-latin.conf ranks Inconsolata third among monospace families. # Gentium appears on NO generic's preference list in that file -- not serif, not # sans-serif, not monospace -- so `fc-match serif` stays Liberation Serif, which # reaches the generic through 30-metric-aliases.conf binding it to Times New # Roman at rank 3. `fc-match-serif` asserts that from this side, so this port # cannot silently move a generic the way the last one did. # # THE EXPECTED ANSWER MOVED TO Kinnari FOR BRINTOS-1729, AND THE CASE WAS RENAMED # WITH IT. ttf-tlwg's do_install:append ships /etc/fonts/conf.d/64-01-tlwg- # kinnari.conf, whose for serif PREPENDS Kinnari ahead of the # generic -- while 30-liberation-aliases.conf only s Liberation Serif # behind it. So the generic is Kinnari's, Gentium is still on no preference list, # and what this case is worth is unchanged: it reds if GENTIUM ever takes serif. # "-unchanged" was dropped from the name because it is no longer what the case # says. # # THE fontcache POSTINST IS THE THING THE TICKET SAYS TO CHECK RATHER THAN # ASSUME, AND IT IS CHECKED IN THE ONE FORM THAT IS BOOT-MODE INDEPENDENT. # fontcache.bbclass appends fontconfig-utils to RDEPENDS -- read back off the # target here, not off the recipe -- and registers an update_font_cache intercept # that runs fc-cache under qemu-user. There is no wasm32 qemu-user, so it is # deferred to run-postinsts at first boot, which /etc/inittab does run # (BRINTOS-53). Whether it HAS run depends on the pid 1 the harness booted -- the # local runner goes straight to a shell -- so asserting the configured state # would report the runner's choice as a package red. What is asserted instead is # boot-mode independent and is the actual risk the ticket names: the scriptlet is # on the image for BOTH packages, it calls fc-cache, and fc-cache is present, so # the deferred run cannot fail for want of the tool. . "$BST_LIB" S=ttf-gentium # THE CANARY, which asserts nothing about ttf-gentium. # # A suite's FIRST BST result line is lost between the guest's printf and the # host's read -- per-suite, deterministic, and NOT a defect in the host tool # (BRINTOS-1149 established that and filed it as linux-in-the-browser#177). # The harness reports the deficit but computes its pass count as total-minus- # failures, so THE DROPPED LINE IS COUNTED AS A PASS. A nothing-case therefore # stands in that position and the eaten line costs nothing; every real case below # is still counted. It sits ahead of the `require` guards deliberately, because a # `require` that skips would emit its skip as the first line and be eaten too. # # Remove this case when linux-in-the-browser#177 is fixed. bst_ok $S/suite-canary D=$BST_DATA REF=$D/ttf-gentium-manifest.txt FACTS=$D/ttf-gentium-fontfacts.txt FACES=$D/ttf-gentium-fcfaces.txt PROBE_SRC=$D/freetype-probe TTFDIR=/usr/share/fonts/truetype DOCDIR=/usr/share/doc/ttf-gentium DOCDIRA=/usr/share/doc/ttf-gentium-alt COTDIR=/usr/share/fonts/ttf POSTINST=/var/lib/dpkg/info/ttf-gentium.postinst POSTINSTA=/var/lib/dpkg/info/ttf-gentium-alt.postinst tmp=${TMPDIR:-/tmp} W=$tmp/bst-ttf-gentium.$$ require gawk $S/gawk-present require sha256sum $S/sha256sum-present require find $S/find-present # fc-scan runs in the payload block, ahead of the consumer block's own check, so # its absence is guarded here. It is NOT a `require`: fontconfig-utils is a hard # Depends of both packages, so an absent fc-scan is a defect in the port rather # than a legitimately absent tool, and a skip would report it green. if [ -x /usr/bin/fc-scan ]; then bst_ok $S/fc-scan-present else bst_notok $S/fc-scan-present "fontconfig-utils is a Depends of ttf-gentium but /usr/bin/fc-scan is absent"; fi if [ ! -f "$REF" ] || [ ! -f "$FACTS" ] || [ ! -f "$FACES" ]; then bst_notok $S/ref-present "the reference data did not ship: $REF / $FACTS / $FACES" exit 0 fi bst_ok $S/ref-present # ------------------------------------------------------------- payload shape # One find over the shared font directory, BOTH doc directories, AND the other # font directory, so every count is a measurement from the same pass. %y catches # a symlink where a regular file is meant and %m the mode -- neither of which # `test -f` can see. find "$TTFDIR" "$DOCDIR" "$DOCDIRA" "$COTDIR" \ -maxdepth 1 -printf '%p %y %s %m %l\n' 2>/dev/null | LC_ALL=C sort > "$W.inv" # One sha256sum over all six payload files. Named explicitly rather than globbed: # the manifest is the list, and a glob over a SHARED directory would digest # Inconsolata too and report it as an unexpected entry. sha256sum "$TTFDIR"/GenAI102.ttf "$TTFDIR"/GenAR102.ttf \ "$TTFDIR"/GenI102.ttf "$TTFDIR"/GenR102.ttf \ "$DOCDIR"/OFL "$DOCDIRA"/OFL > "$W.sums" 2>&1 # One fc-scan over all four installed faces. fontconfig opens them through # FreeType, so this is a second, independent parse -- and it reads fields # freetype's own API does not name (the PostScript name, the derived # slant/weight/spacing, the format, the charset). It reads the FILES, not the # cache, so it is independent of the fc-cache in the consumer block below. LC_ALL=C fc-scan --format '%{file|basename}|%{family}|%{style}|%{slant}|%{weight}|%{spacing}|%{postscriptname}|%{fontformat}|%{scalable}|%{outline}|%{charset}\n' \ "$TTFDIR"/GenAI102.ttf "$TTFDIR"/GenAR102.ttf \ "$TTFDIR"/GenI102.ttf "$TTFDIR"/GenR102.ttf 2>/dev/null | LC_ALL=C sort > "$W.scan" LC_ALL=C gawk -v REF="$REF" -v SUMS="$W.sums" -v INV="$W.inv" \ -v FACES="$FACES" -v SCAN="$W.scan" \ -f "$D/ttf-gentium-verify.awk" "$REF" "$W.sums" "$W.inv" "$FACES" "$W.scan" # ---------------------------------------------------- the packaging on target # THE PACKAGE DATABASE IS THE ONLY PLACE THE SPLIT IS VISIBLE ON TARGET. The # file-* cases would look identical if do_install had written all six files into # one package, so they cannot say that ttf-gentium-alt is a real package the # image installs rather than an IMAGE_INSTALL line that resolved to nothing. One # sed pulls both stanzas; the loop is shell builtins. The stanzas are read from a # tmpfs copy, never redirected from the rootfs (brintos/linux#73). sed -n '/^Package: ttf-gentium$/,/^$/p; /^Package: ttf-gentium-alt$/,/^$/p; /^Package: ttf-gentium-doc$/,/^$/p' \ /var/lib/dpkg/status > "$W.st" 2>/dev/null _pkg=""; _main=0; _alt=0; _doc=0; _dep=0; _depa=0; _arch=0; _archa=0 while IFS= read -r l; do case "$l" in "Package: ttf-gentium") _pkg=main; _main=1 ;; "Package: ttf-gentium-alt") _pkg=alt; _alt=1 ;; "Package: ttf-gentium-doc") _pkg=doc; _doc=1 ;; "Architecture: all") [ "$_pkg" = main ] && _arch=1 [ "$_pkg" = alt ] && _archa=1 ;; "Depends: "*) case "$l" in *fontconfig-utils*) [ "$_pkg" = main ] && _dep=1 [ "$_pkg" = alt ] && _depa=1 ;; esac ;; esac done < "$W.st" if [ "$_main" -eq 1 ]; then bst_ok $S/pkg-known else bst_notok $S/pkg-known "dpkg does not know the package ttf-gentium"; fi # THE -alt PACKAGE IS HALF THE PORT, NOT AN EXTRA. Two of the four faces and one # of the two licence copies are its; a dropped IMAGE_INSTALL line would take # file-GenAI102.ttf, file-GenAR102.ttf and file-ttf-gentium-alt-OFL with it, and # this case says the cause is a missing package rather than missing files. if [ "$_alt" -eq 1 ]; then bst_ok $S/pkg-alt-known else bst_notok $S/pkg-alt-known "dpkg does not know the package ttf-gentium-alt"; fi # THERE IS NO -doc PACKAGE, AND ITS ABSENCE IS THE PACKAGING DECISION. `PACKAGES` # is an assignment that omits ${PN}-doc, which is exactly why the licence text # reaches the two main packages here and did NOT reach ttf-inconsolata's. A # future recipe revision restoring the default PACKAGES would move both OFL # copies into a third package and leave every file-* case red with no # explanation; this case names the cause. if [ "$_doc" -eq 0 ]; then bst_ok $S/pkg-no-doc-package else bst_notok $S/pkg-no-doc-package "dpkg knows a ttf-gentium-doc package -- PACKAGES no longer omits \${PN}-doc"; fi # `allarch` reached the package metadata, which is what makes the byte-identity # reference in the manifest a statement about this build rather than a # coincidence. Asserted for both packages: they are built by one recipe but # packaged separately, and a class that reached one need not have reached both. if [ "$_arch" -eq 1 ]; then bst_ok $S/pkg-arch-all else bst_notok $S/pkg-arch-all "ttf-gentium is not Architecture: all"; fi if [ "$_archa" -eq 1 ]; then bst_ok $S/pkg-alt-arch-all else bst_notok $S/pkg-alt-arch-all "ttf-gentium-alt is not Architecture: all"; fi # THE fontcache CLASS'S RDEPENDS, READ BACK OFF THE TARGET. The recipe declares # no runtime dependency at all and INHIBIT_DEFAULT_DEPS is set -- fontcache.bbclass # appends fontconfig-utils to each FONT_PACKAGES entry -- so these are the cases # that say the class did its half for BOTH packages and that the dependency # resolved against a package this image already carried (fontconfig-utils has # been here since BRINTOS-1032). if [ "$_dep" -eq 1 ]; then bst_ok $S/pkg-depends-fontconfig else bst_notok $S/pkg-depends-fontconfig "ttf-gentium does not Depend on fontconfig-utils"; fi if [ "$_depa" -eq 1 ]; then bst_ok $S/pkg-alt-depends-fontconfig else bst_notok $S/pkg-alt-depends-fontconfig "ttf-gentium-alt does not Depend on fontconfig-utils"; fi # ------------------------------------------------- the deferred fontcache hook # BOTH packages are in FONT_PACKAGES, so both get a scriptlet. Asserted # separately for the same reason as the RDEPENDS above. if [ -f "$POSTINST" ]; then bst_ok $S/postinst-present else bst_notok $S/postinst-present "$POSTINST is absent -- the fontcache postinst did not reach the image"; fi if [ -f "$POSTINSTA" ]; then bst_ok $S/postinst-alt-present else bst_notok $S/postinst-alt-present "$POSTINSTA is absent -- the fontcache postinst did not reach the image"; fi # They call fc-cache on the branch run-postinsts takes ($D unset at first boot). check_out $S/postinst-runs-fc-cache "fc-cache" cat "$POSTINST" check_out $S/postinst-alt-runs-fc-cache "fc-cache" cat "$POSTINSTA" # ...and the tool that branch needs is present, so the deferred run cannot fail # for want of it. This is the ticket's stated risk, and it is a shell builtin. if [ -x /usr/bin/fc-cache ]; then bst_ok $S/fc-cache-present else bst_notok $S/fc-cache-present "fontconfig-utils is a Depends of ttf-gentium but /usr/bin/fc-cache is absent"; fi # ------------------------------------------------------ freetype parses them # The rootfs is read-only at browser runtime and data/ arrives 0644, so the probe # is copied to /tmp (mode=1777 tmpfs, no noexec) and the bit is set there. Never # `test -x` the shipped payload: that passes against a hand-placed copy and fails # against every image that ever built the package. if [ ! -f "$PROBE_SRC" ]; then bst_notok $S/probe-present "$PROBE_SRC did not ship" rm -f "$W.inv" "$W.sums" "$W.scan" "$W.st" 2>/dev/null exit 0 fi bst_ok $S/probe-present probe=$tmp/bst-ttfgent-probe.$$ if cp "$PROBE_SRC" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then bst_ok $S/probe-stage else bst_notok $S/probe-stage "cannot stage $PROBE_SRC" rm -f "$probe" "$W.inv" "$W.sums" "$W.scan" "$W.st" 2>/dev/null exit 0 fi # The face list comes from the FACTS file rather than from a glob, so a face the # manifest knows about but the image lost is reported as "the probe was never run # over X" instead of silently dropping out of the loop. A glob would additionally # pick up Inconsolata.ttf out of this shared directory. # # NO TRAILING == ON THE FENCE. `==FONT GenR102.ttf==` puts "GenR102.ttf==" in # awk's $2, which matches no key in the facts table, and every per-face case then # reds with "the probe was never run over ..." while ft-ran stays green. : > "$W.ft" _faces=$(LC_ALL=C gawk '!/^#/ && NF >= 5 { print $1 }' "$FACTS") for _f in $_faces; do printf '==FONT %s\n' "$_f" >> "$W.ft" "$probe" "$TTFDIR/$_f" >> "$W.ft" 2>&1 _rc=$? printf '==RC %s %d\n' "$_f" "$_rc" >> "$W.ft" done rm -f "$probe" 2>/dev/null LC_ALL=C gawk -v FACTS="$FACTS" -v FT="$W.ft" \ -f "$D/ttf-gentium-ftverify.awk" "$FACTS" "$W.ft" # --------------------------------------------------------- the consumer block # # EVERYTHING BELOW THIS LINE CAN COST THE GUEST, AND THAT IS WHY IT IS LAST. # fc-cache mmaps each face it walks, and file-backed mmap on this arm is REFUSED # above a mapping-length threshold (linux-in-the-browser#165) -- and the consumer # does not get a failed mmap and fall back, it PARKS, beyond the reach of both # SIGTERM and SIGKILL, taking the guest and every suite behind it in the same # boot. Ordering this block last is the only thing that actually protects the # evidence: every case above has already been emitted by the time the first # mapping happens. # # THE FOUR GENTIUM FACES SIT INSIDE THE UNRESOLVED PART OF THAT BRACKET, which is # the honest statement of this port's risk. BRINTOS-1450 bracketed the threshold # between ~66 kB (ttf-bitstream-vera's largest face, never trips) and ~578 kB # (ttf-dejavu's first face, wedges deterministically). These are 314,476 / # 315,860 / 362,664 / 364,056 -- squarely between. What makes the port landable # anyway is that the image ALREADY scans twelve Liberation faces of 281,536 to # 415,816 bytes on every fc-cache, four of them LARGER than anything this port # adds, and #165 records those parking on roughly half of boots. So this package # does not introduce a new failure mode or a new maximum; it adds four more # mappings to a band the image already lives in. # # THE BOUND IS BEST-EFFORT AND IS NOT WHAT MAKES THIS SAFE. #165 measured that a # parked fc-cache survives SIGKILL, so `timeout` cannot reclaim it and will # itself hang when the park is the unkillable kind. It is here for the case where # the call merely runs long, and the ordering above is here for the case where it # does not come back at all. Recorded rather than dressed up, because a bound # that looks protective and is not is worse than none. # # BRINTOS-WORKAROUND: linux-in-the-browser#165 remove -- bound the fc-cache call # and order the consumer block last; both go when the mmap population path # tolerates a parking read. # `fc-cache`, NOT `fc-cache -f`, SINCE BRINTOS-1725. The -f rebuilt every # directory whether or not its cache was valid, which means mapping every face on # the image; a file-backed mapping above roughly 578 kB is REFUSED over the cloud # FUSE bridge and the caller PARKS, beyond SIGKILL (linux-in-the-browser#165, # bracketed by BRINTOS-1450). Before ttf-pt-sans the image's largest face was # Ubuntu-L.ttf at 415,552 bytes, under the bracket, and this call was harmless; # that port adds four faces above it, the largest 584,812, and MEASURED on the # resulting image this suite parked here -- reaching 47 of its 55 cases against # 55/55 in 28 s on the same base pin without the port. Without -f, fc-cache rebuilds # only what is stale, and nothing is: /var/cache/fontconfig ships populated, and # `fc-cache` returns 0 in 3 s on that image where `timeout -k 5 150 fc-cache -f` # never returned. The case still asserts what it always did -- fc-cache runs and # returns 0. # # BRINTOS-WORKAROUND: linux-in-the-browser#165 revisit -- drop -f so only a stale # cache is rebuilt; it goes back in when the mmap population path tolerates a # parking read. # BST-TIMEOUT-OK: fc-cache walks the font dirs and exits; -k 5 90 is belt-and-braces. timeout -k 5 90 fc-cache > "$W.cache" 2>&1 _rc=$? if [ "$_rc" -eq 0 ]; then bst_ok $S/fc-cache-rc elif [ "$_rc" -eq 124 ] || [ "$_rc" -eq 137 ]; then bst_notok $S/fc-cache-rc "fc-cache did not return within 90s -- linux-in-the-browser#165 (mmap population parked)" else bst_notok $S/fc-cache-rc "fc-cache exited $_rc: $(_bst_1line "$(cat "$W.cache")")"; fi # One fc-list for the whole consumer read; the parsing below is shell builtins. fc-list : file family > "$W.list" 2>&1 # THE FACES ARE DISCOVERABLE, not merely present on disk. A cache that serialised # wrongly, or a FreeType that refused the outlines, shows up here while every # file-* case above stays green -- which is the split that says where to look. for _pair in "GenI102.ttf:Gentium" "GenR102.ttf:Gentium" \ "GenAI102.ttf:GentiumAlt" "GenAR102.ttf:GentiumAlt"; do _bn=${_pair%%:*}; _wantfam=${_pair#*:} _seen=0; _fam="" while IFS= read -r l; do case "$l" in "$TTFDIR/$_bn":*) ;; *) continue ;; esac _seen=$((_seen+1)) _fam=${l#*: } done < "$W.list" if [ "$_seen" -eq 1 ] && [ "$_fam" = "$_wantfam" ]; then bst_ok "$S/fc-list-$_bn" else bst_notok "$S/fc-list-$_bn" "fc-list reports $_seen entries for $TTFDIR/$_bn family '$_fam', want 1 of '$_wantfam'" fi done # ...AND EACH FAMILY RESOLVES BACK TO OUR REGULAR FACE. fc-match never fails -- # it always returns some face -- so this is real only because 27 other faces are # installed alongside: a family name that did not reach the cache falls through # to Liberation, which is exactly what 99-terminus-font's first on-target run # reported for its own family. for _pair in "Gentium:GenR102.ttf" "GentiumAlt:GenAR102.ttf"; do _fam=${_pair%%:*}; _wantf=${_pair#*:} _out=$(fc-match --format '%{file} %{family}\n' "$_fam" 2>&1) case "$_out" in "$TTFDIR/$_wantf $_fam") bst_ok "$S/fc-match-$_fam" ;; *) bst_notok "$S/fc-match-$_fam" "fc-match $_fam => '$(_bst_1line "$_out")', want '$TTFDIR/$_wantf $_fam'" ;; esac done # THE GENERIC THIS PORT DOES **NOT** TAKE OVER, ASSERTED FROM THIS SIDE. # fontconfig's shipped 60-latin.conf ranks serif as Noto Serif, DejaVu Serif, # Times New Roman, Thorndale AMT, Luxi Serif, Nimbus Roman No9 L, Nimbus Roman, # Times -- Gentium is on that list nowhere, nor on the sans-serif or monospace # lists. Liberation Serif therefore keeps the generic, reaching it through # 30-metric-aliases.conf's binding to Times New Roman at rank 3. This is NOT a # restatement of fc-match-Gentium: that case would stay green if installing this # family had ALSO displaced the serif generic, which is precisely what installing # ttf-inconsolata did to monospace one ticket ago, and ttf-tlwg has since done to # serif and sans-serif (BRINTOS-1729) -- which is why the wanted family below is # Kinnari and not Liberation Serif. 99-liberation-fonts and 99-ttf-tlwg assert the # same fact from the other two sides, so a disagreement between the three suites # is visible rather than silent. _out=$(fc-match --format '%{family}\n' serif 2>&1) case "$_out" in "Kinnari") bst_ok $S/fc-match-serif ;; *) bst_notok $S/fc-match-serif "fc-match serif => '$(_bst_1line "$_out")', want 'Kinnari' -- ttf-tlwg owns the serif generic; this port must still not take it" ;; esac rm -f "$W.inv" "$W.sums" "$W.scan" "$W.st" "$W.ft" "$W.cache" "$W.list" 2>/dev/null