Fonts: a declared package is not a drawn glyph #74
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#74
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Observation
Raised while doing #70. Adding the African languages meant adding Arabic and Ethiopic, and
the container could not draw either: it installed
fonts-dejavu-core, which covers Latin,Greek and Cyrillic and stops there. An Amharic CV rendered in that image would have been a
page of empty boxes, and a box on somebody's CV is worse than the same CV in English —
one is a missing translation, the other looks like the applicant sent a broken file.
That immediate hole is fixed:
fonts-noto-coreis installed, andtests/test_fonts.pyreads
postulo.core.languages.SCRIPTSand the Dockerfile and insists they agree, so alanguage added in a later phase cannot quietly ship a PDF nobody can read.
What is left is everything that fix does not cover.
Why 0.4.0
Two of the five points below are live gaps today; the other three are forced by #71, which
brings Chinese, Japanese, Korean, Devanagari, Thai, Khmer, Burmese and Sinhala. Doing them
separately would mean touching the image, the themes and the checks twice. If the two live
gaps should be pulled forward into 0.3.0 instead, say so and they will be — they are marked
below.
Shape
1. The scripts #71 needs, and the size they cost
fonts-noto-coredoes not include CJK: that isfonts-noto-cjk, and it is a differentorder of size (tens of megabytes against a few). Some of the South and South-East Asian
scripts are their own packages too. Each is a deliberate decision, not an apt line:
fonts-noto-cjkfonts-noto-corefonts-noto-corefonts-noto-coreWhether the image carries CJK by default is the decision this issue exists to make.
Doubling an image so that every installation can render a language almost none of them will
use is a real cost; so is a Japanese CV coming out as boxes. A middle answer exists — a
POSTULO_EXTRA_PACKAGES-style hook already exists in the Dockerfile for plugins, and fontscould use the same door — but it has to be chosen rather than fallen into.
2. Nobody checks that the fonts are actually there (live gap, could move to 0.3.0)
tests/test_fonts.pychecks a declaration. It reads the Dockerfile. It does not check arunning system, and it cannot: an operator running Postulo from a virtualenv under systemd,
or on a distribution whose font packages are named differently, gets whatever that machine
has, and nothing tells them. The first sign is a CV that went out full of boxes.
Wanted: something that reports, at runtime, which of the scripts this instance offers it can
actually draw. WeasyPrint exposes the font configuration Pango resolved, so this is
answerable without shelling out to
fc-list. It belongs on Server settings → Overviewbeside the other facts about the instance, and probably in a
manage.pycommand so it canbe checked before anything is sent.
3. The interface, not only the documents (live gap, could move to 0.3.0)
Everything above is about WeasyPrint. The browser side has the same problem and no
mitigation at all:
--font-sansis a system stack, so an Amharic interface on a machinewith no Ethiopic font is boxes too. The person reading it is the account holder rather than
a recruiter, which makes it less damaging and not less broken.
Postulo bundles no webfonts today, deliberately — no request, nothing for
font-srctoallow, and the strict content security policy stays as it is. Adding subsetted Noto faces
for the non-Latin scripts would change that; so would doing nothing. Decide.
4. The document themes name fonts that cannot draw these scripts
classicasks for"Palatino Linotype", Palatino, Georgia, "Times New Roman", serifandplainfor"Helvetica Neue", Helvetica, Arial, sans-serif. None of those has Ethiopic orCJK, so an Arabic CV in the classic theme falls all the way through to the generic
serifand gets whatever fontconfig picks — which may be fine and may be a face that looks nothing
like the rest of the document.
A theme should state a per-script fallback rather than land on one by accident.
5. The check should be about scripts, not about a hard-coded map
tests/test_fonts.py::COVERAGEmaps a script to the Debian packages that draw it, by hand.That is honest and small today. If it grows past about a dozen entries it should be derived
from what the packages actually contain rather than from what somebody believed they
contained.
Classification
Enhancement, with a bug's consequences: a missing glyph is not a degraded experience but a
document that cannot be read. Not breaking.
Depends on
#71, which brings the scripts that force most of this. #70 is where the first hole was
found and fixed.
Open question
Does the default image carry CJK, or is it an opt-in through a build argument? Proposal:
opt-in, documented in Installing Postulo, with the runtime check from point 2 saying
plainly which scripts the running instance can and cannot draw — so somebody who needs it
finds out before a recruiter does, not after.
Landed on
mainasd88715901, with two follow-ups (b47674329,d4becf269) that made the probe work against the HarfBuzz and Pango the image actually carries. Closing; the five points, against what is in the tree:manage.py check_fonts, and a row on Server settings → Overview, say which of the scripts the offered languages need this instance can draw. It asks the running system, not the Dockerfile.font-srcto allow; the reasoning is written down inassets/css/app.css.tests/test_fonts.pyholds the probe table to the languages the declaration knows and checks the cmap parsers against synthetic tables. The hand-written package map stays while it is under a dozen entries, which is what this point asked for.The issue says it depends on #71. It does not any more: the decisions are taken and the check is about whatever scripts the instance offers, so the day #71 adds Han or Devanagari the check reports on them without being changed.