Lettertypen: het lastige deel
ISO 32000-2 §9 Evidence: Mixed evidence
In het kort
Sectie met titel “In het kort”Lettertypen zijn het punt waarop een PDF er volledig correct kan uitzien en toch ongemerkt kapot kan zijn. Een pagina kan de juiste glyphs weergeven en tegelijk niet te doorzoeken zijn, niet als tekst te kopiëren zijn en niet conform zijn aan een archiveringsprofiel. Dat kan allemaal tegelijk gebeuren, zonder zichtbare waarschuwing. Deze pagina gaat over de drie dingen die goed moeten gaan — inbedden, subsetten, codering — en wat NextPDF voor elk daarvan doet.
Waarom dit belangrijk is
Sectie met titel “Waarom dit belangrijk is”“Het ziet er prima uit” is de gevaarlijkste zin bij PDF-werk, en lettertypen zijn het punt waarop die zin de meeste schade aanricht. Drie onafhankelijke dingen moeten kloppen:
- Inbedden — het lettertypeprogramma wordt in het bestand meegestuurd, zodat de weergave hetzelfde blijft op een machine waarop het lettertype niet is geïnstalleerd.
- Subsetten — alleen de glyphs die daadwerkelijk worden gebruikt, worden meegenomen, zodat een CJK-lettertype van 20 MB niet elk document opblaast.
- Codering — de tekencodes op de pagina worden correct terug naar Unicode afgebeeld, zodat de tekst kan worden doorzocht, gekopieerd, geïndexeerd en gelezen door ondersteunende technologie.
Visuele weergave bewijst hooguit een deel van het eerste punt. Een document kan perfecte glyphs tonen en toch volledig falen op het derde punt — de tekst is een afbeelding van woorden, niet de woorden zelf. Dit is het soort falen dat elke “ziet er prima uit”-beoordeling doorstaat en pas daarna een nalevingsaudit of een discovery-verzoek onderuit haalt.
De korte versie
Sectie met titel “De korte versie”- Een lettertype in een PDF is een dictionary plus, doorgaans, een stream met een ingebed lettertypeprogramma.
- Subsetten herschrijft dat programma zodat het alleen de gebruikte glyphs bevat. De naam van een subset-lettertype krijgt een tag van zes hoofdletters en een
+zodat lezers het als afzonderlijk behandelen. - Codering is het afzonderlijke probleem van het afbeelden van tekencodes op Unicode. Een
/ToUnicode-CMap is wat tekst doorzoekbaar en kopieerbaar maakt — en die staat los van de vraag of de glyphs er juist uitzien. - Goed ogende tekst zonder (of met een verkeerde)
/ToUnicodeis het klassieke stille falen: perfect op het scherm, in de praktijk onvindbaar. - NextPDF maakt subsets van TrueType-lettertypen, behoudt de glyph-identiteit voor correcte weergave en genereert een
/ToUnicode-CMap zodat extractie werkt — en kan de PDF 2.0-inbeddingsregel afdwingen in plaats van er alleen voor te waarschuwen.
Hoe NextPDF dit aanpakt
Sectie met titel “Hoe NextPDF dit aanpakt”Subsetten. FontSubsetter (src/Typography/FontSubsetter.php) ontleedt de oorspronkelijke TrueType-tabeldirectory en leest de cmap om Unicode-codepunten af te beelden op glyph-ID’s. Het verwerkt zowel BMP-formaat 4 als volledig-Unicode-formaat 12, dat nodig is voor CJK. Vervolgens doet het de stap die naïeve subsetters missen: het lost samengestelde glyph-afhankelijkheden op via transitieve afsluiting. Een glyph met een accent die is opgebouwd uit een basisletter plus een combinerend teken, verwijst naar andere glyphs als componenten. Als die componenten worden weggelaten, wordt de glyph verkeerd weergegeven. De subsetter doorloopt die graaf totdat er geen nieuwe component meer verschijnt, met beveiliging tegen cycli zodat hij bij een misvormd lettertype niet eindeloos blijft lopen.
Twee technische keuzes in dat bestand zijn het benoemen waard. Ten eerste worden glyph-ID’s behouden, niet opnieuw toegewezen — ongebruikte posities worden met nullen gevuld in glyf/loca zodat de oorspronkelijke glyph-indices van de contentstream geldig blijven onder CIDToGIDMap /Identity. Opnieuw toewijzen zou kleiner zijn, maar dan zou elke glyph-verwijzing moeten worden herschreven. Door de identiteit te behouden, is dit per constructie correct. Ten tweede is de iteratie gesorteerd (oplopend op gid) zodat de subset byte-deterministisch is — hetzelfde lettertype en dezelfde gebruikte glyphs leveren dezelfde subset-bytes op, wat reproduceerbare builds vereisen. Als subsetten minder dan ~10% van het bestand zou besparen, wordt het origineel ongewijzigd teruggegeven. Voor een marginale winst is die overhead het niet waard.
Inbedden. Een expliciet beleid bepaalt of een lettertypeprogramma überhaupt wordt meegenomen — zonder giswerk. Pdf20FontEmbeddingPolicy (src/Writer/Pdf20FontEmbeddingPolicy.php) heeft twee modi. Binnen het PDF 2.0-profiel weigert Strict een niet-ingebedde standaard-Type 1-verwijzing (“Base14”) met een getypeerde uitzondering — het gedrag dat voor conformiteit correct is. AllowBase14 houdt het historische waarschuwingspad in stand. Tijdens een migratievenster schrijft het de minimale lettertypedescriptor weg die de standaard nog steeds vereist en geeft het een waarschuwing af in plaats van een uitzondering te werpen. De aanroeper maakt de keuze expliciet op het document; die wordt nooit afgeleid uit het lettertype.
Codering. Voor samengestelde (Type 0) lettertypen genereert EmbeddedTtfFontDictBuilder (src/Writer/EmbeddedTtfFontDictBuilder.php) de CIDFontType2-afstammeling, de Type0-ouder en een /ToUnicode-CMap-stream zodat tekencodes terug naar Unicode worden herleid. De /ToUnicode-stream mag terecht maar in één geval ontbreken: wanneer een zelfbeschrijvende, voorgedefinieerde CJK-CMap de lezer de teken-naar-Unicode-afbeelding al geeft. In dat geval is de CMap de codering, dus laat het eenvoudige profiel een overbodige /ToUnicode-stream weg om bytes te besparen. Buiten dat geval is de /ToUnicode-stream wat tekst tekst houdt.
| Aspect | Wat het garandeert | Wat het niet garandeert | Stil falen bij fouten |
|---|---|---|---|
| Inbedden | Dezelfde weergave zonder dat het lettertype is geïnstalleerd | Dat tekst doorzoekbaar is | Vervangend lettertype; verkeerde metriek op een andere machine |
| Subsetten | Klein bestand; alleen gebruikte glyphs | Niets over codering | Ontbrekende samengestelde componenten → kapotte glyphs met accent |
Codering (/ToUnicode) | Doorzoekbare, kopieerbare, toegankelijke tekst | Dat glyphs correct worden weergegeven | Perfect ogende pagina, onvindbaar / verminkt bij kopiëren |
De drie lettertype-aspecten staan los van elkaar. Inbedden en subsetten gaan over weergave en grootte; codering gaat over betekenis. Een pagina kan de eerste twee doorstaan en op de derde falen zonder dat daar zichtbaar iets op wijst.
Wat het bewijs zegt
Sectie met titel “Wat het bewijs zegt”De regel voor subset-naamgeving is normatief en precies.
Spec: ISO 32000-2, §9.9.2 ISO 32000-2 §9.9.2 vereist dat de PostScript-naam van een
lettertype-subset — de BaseFont en de FontName van de descriptor —
begint met een tag van precies zes hoofdletters, gevolgd door een plusteken
en daarna de PostScript-naam van het oorspronkelijke lettertype. Het vereist ook dat verschillende
subsets van hetzelfde lettertype in één bestand verschillende tags gebruiken. Die regel stelt
een lezer in staat twee subsets uit elkaar te houden en documenten correct samen te voegen. Evidence: Standard-backed
Codering staat in een aparte clausule en is losgekoppeld van weergave.
Spec: ISO 32000-2, §9.10.3 ISO 32000-2 §9.10.3 definieert /ToUnicode
als een stream die een CMap bevat die tekencodes afbeeldt op Unicode-waarden,
en de tekstextractieprocedure in
Spec: ISO 32000-2, §9.10.2 ISO 32000-2 §9.10.2 gebruikt die CMap om
tekencodes naar Unicode te converteren voor zoekopdrachten en indexering. Het mechanisme
dat glyphs tekent, raakt /ToUnicode niet — precies daarom kan
tekst er juist uitzien en verkeerd kan extraheren.
Voor inbedden stelt de standaard dat de meeste lettertype-dictionary’s een lettertypedescriptor hebben met een ingebedde stream met het lettertypebestand die optioneel maar sterk aanbevolen is. PDF 2.0 scherpt dit specifiek aan voor de veertien standaard-Type 1-lettertypen. Het Strict-beleid van NextPDF is de conformiteitscorrecte lezing van die aanscherping. AllowBase14 is de expliciete opt-in route voor achterwaartse compatibiliteit — de engine downgradet nooit ongemerkt.
| Edition | Availability |
|---|---|
| Core | Beschikbaar. Subsetten, het genereren van |
| Pro | Voegt diepere conformiteitshandhaving en rapportage rond lettertype-inbedding toe op profielniveau. |
| Enterprise | Voegt dezelfde conformiteitshandhaving toe binnen het operationele enterprise-oppervlak. |
Praktijkvoorbeeld
Sectie met titel “Praktijkvoorbeeld”Dit zijn de twee helften van een correct ingebed, gesubset en doorzoekbaar samengesteld lettertype. De subset-tag volgt de zesletterregel van de standaard; de /ToUnicode-verwijzing houdt de tekst extraheerbaar.
% The Type 0 (composite) font dictionary20 0 obj<< /Type /Font /Subtype /Type0 /BaseFont /ABCDEF+NotoSans % six-letter subset tag + '+' /Encoding /Identity-H /DescendantFonts [21 0 R] /ToUnicode 23 0 R >> % the map that makes text searchableendobj
% The descendant CIDFontType2 (carries the subsetted program)21 0 obj<< /Type /Font /Subtype /CIDFontType2 /BaseFont /ABCDEF+NotoSans /CIDToGIDMap /Identity % glyph IDs preserved, not remapped /FontDescriptor 22 0 R >>endobjDe /ToUnicode 23 0 R van object 20 is het verschil tussen een doorzoekbaar document en een afbeelding ervan. Laat die weg (buiten het geval van een voorgedefinieerde CMap), en elke glyph wordt nog steeds perfect getekend, maar een zoekopdracht naar een willekeurig woord op de pagina levert niets op.
Veelvoorkomend misverstand
Sectie met titel “Veelvoorkomend misverstand”De valkuil, kort gezegd: glyphs die correct worden weergegeven zeggen niets over de vraag of de tekst ook echt tekst is. Weergave volgt het pad van codering naar glyph. Zoeken en kopiëren volgen het pad van code naar Unicode (/ToUnicode). Het zijn verschillende mechanismen die verschillende delen van de lettertype-dictionary lezen. Een document kan daarom een onberispelijk visueel resultaat hebben en toch een ontbrekende of verkeerde /ToUnicode. Het resultaat is een pagina die er gezaghebbend uitziet en functioneel onvindbaar is — het soort falen dat elke visuele beoordeling overleeft, omdat er per definitie niets te zien is.
Een verwante valkuil: aannemen dat “het lettertype is ingebed, dus we zitten goed voor archivering.” Inbedden is noodzakelijk maar niet voldoende. Een profiel zoals PDF/A verwacht ook dat subsets volgens de zesletterregel zijn benoemd en dat de codering correct is. Een document dat ingebed maar onvindbaar is, faalt nog steeds.
Grenzen en beperkingen
Sectie met titel “Grenzen en beperkingen”De subsetter van NextPDF is specifiek een TrueType-subsetter. Het vereist de essentiële TrueType-tabellen en geeft het oorspronkelijke lettertype ongewijzigd terug wanneer die ontbreken of de winst onder de drempel van ~10% ligt. Subsetten en een /ToUnicode-CMap maken tekst extraheerbaar, maar ze kunnen geen bronlettertype redden dat de informatie mist om een glyph terug te leiden naar een betekenisvol teken. Waar geen Unicode-waarde kan worden bepaald, kan geen enkele CMap-uitgifte die waarde verzinnen.
Deze pagina gaat over het produceren van een correcte lettertypestructuur in documenten die NextPDF schrijft. Het is geen tool voor lettertypereparatie voor willekeurige binnenkomende PDF’s. En het uitgeven van een conforme subset en codering certificeert een document op zichzelf niet voor een volledig archiveringsprofiel — dat is een afzonderlijke, bredere controle.
Mini-FAQ
Sectie met titel “Mini-FAQ”Waarom de zesletter-tag — waarom niet de lettertypenaam? Zodat een lezer twee verschillende subsets van hetzelfde lettertype uit elkaar kan houden en documenten kan samenvoegen zonder dat hun glyph-sets botsen. Verschillende subsets krijgen volgens de regel verschillende tags.
Wanneer is het aanvaardbaar om geen /ToUnicode te hebben? Wanneer een zelfbeschrijvende, voorgedefinieerde CJK-CMap de teken-naar-Unicode-afbeelding al biedt. Daar is de CMap de codering. Een aparte /ToUnicode zou overbodig zijn. Daarbuiten is het ontbreken ervan een gebrek.
Doet subsetten ooit kwaad? Alleen als het verkeerd gebeurt. Het weglaten van samengestelde glyph-componenten maakt glyphs met accent kapot. Glyph-ID’s opnieuw afbeelden zonder verwijzingen te herschrijven maakt de weergave kapot. NextPDF vermijdt beide door de componentafsluiting op te lossen en de glyph-identiteit te behouden.
Verwante documenten
Sectie met titel “Verwante documenten”- Streams en filters — ingebedde lettertypeprogramma’s zijn gefilterde stream-objecten met hun eigen decodecontract.
- Wat een PDF eigenlijk is — het objectmodel waarin de lettertype-dictionary’s en programmastreams zich bevinden.
- PDF 2.0: wat er is veranderd — inclusief de aangescherpte verwachtingen voor lettertype-inbedding van de 2.0-basislijn.
Woordenlijst
Sectie met titel “Woordenlijst”- Ingebed lettertypeprogramma — het eigenlijke lettertypebestand (TrueType/CFF/Type 1) dat als stream binnen de PDF wordt meegedragen, zodat de weergave niet afhangt van de lettertypen die op de reader zijn geïnstalleerd.
- Subsetten — het herschrijven van een lettertypeprogramma zodat het alleen de glyphs bevat die het document gebruikt, om de grootte te verkleinen.
- Subset-tag — het verplichte voorvoegsel van zes hoofdletters plus
+op de naam van een subset-lettertype (bijvoorbeeldABCDEF+NotoSans). /ToUnicode— een CMap-stream die tekencodes afbeeldt op Unicode-waarden; de laag die PDF-tekst doorzoekbaar, kopieerbaar en toegankelijk maakt.- Samengestelde glyph — een glyph die is opgebouwd door naar andere glyphs te verwijzen als componenten; de componenten moeten bij het subsetten behouden blijven.
CIDToGIDMap /Identity— de modus waarin de glyph-indices van de contentstream ongewijzigd overeenkomen met de eigen glyph-ID’s van het lettertype; NextPDF behoudt de glyph-identiteit om dit geldig te houden.- Base14 — de veertien standaard-Type 1-lettertypen; PDF 2.0 verwacht dat lettertypen worden ingebed in plaats van er alleen op naam naar te verwijzen.