PDF Library for Delphi hyväksyy fontit, jotka web-projekti jo toimittaa. Se tuo WOFF2-säiliöitä, luetteloi muuttujafontin suunnitteluakselit JSON:na, ja instantioi valitun akselikoordinaattijoukon staattiseksi fontiksi, jonka tavallinen upotus-, osittamis- ja poimintareitit käsittelevät tietämättä mitään variaatioista. Sekä TrueType- että CFF2-ääriviivat on katettu
Tilanne, jota tämä käsittelee, on yleinen ja ärsyttävä. Brändin typografia on määritelty suunnittelujärjestelmässä, suunnittelujärjestelmä toimittaa muuttuja-WOFF2-tiedostoja, eikä PDF-generaattori pysty lukemaan säiliötä eikä variaatiodataa. Tavallinen kiertotie — staattisten TTF-instanssien pyytäminen valimolta jokaisesta käytössä olevasta painosta — vie viikkoja ja tuottaa tiedostoja, joita kukaan ei pidä synkronissa
Miksi WOFF2 ei ole vain pakattu fontti?
WOFF2:n käsittely Brotli-kääreenä ja sen purkaminen antaa sinulle tavuja, jotka eivät ole kelvollinen sfnt. Muoto sallii myös muunnettuja ja uudelleenjärjestettyjä taulukoita: glyf, loca ja hmtx voidaan tallentaa uudelleenjärjestetyssä muodossa, joka täytyy kääntää takaisin ennen kuin fontti on jäsennettävissä. Yleiskäyttöinen purkaja ei pysty siihen
Windowsilla alustassa on ollut säiliöanalyysi ja purku Windows 10 -versiosta 1703 lähtien, joten kirjasto käyttää järjestelmätoteutusta sen sijaan, että toimittaisi toisen dekooderin. Tuo päätös pitää käyttöönoton vapaana ylimääräisestä DLL:stä ja tarkoittaa, että muunnoksen kääntäminen hoidetaan samalla koodilla, jota käyttöjärjestelmän oma tekstipino käyttää. Muilla alustoilla WOFF1 kulkee edelleen puhdasta Pascal-reittiä ja WOFF2 raportoi eksplisiittisesti tukemattomaksi, mikä on rehellinen vastaus sen sijaan, että se olisi hiljaisesti turmeltunut fontti
Tuontireitti validoi ennen dekoodausta ja sen jälkeen: 48-tavuinen otsikko, säiliön pituus, varatut kentät, ilmoitettu sfnt-koko ja 512 MiB:n katto tarkistetaan kaikki ensin, ja dekoodatun virran koko verrataan julistukseen jälkikäteen. Verkkofontti on ladattua sisältöä, ja kaksi estämisen arvoista epäonnistumistilaa ovat koon poikkeama ja purkupommi
uses
PDFlibrary;
var
Lib: TPDFlib;
FontID, InstanceID: Integer;
AxesJSON: WideString;
begin
Lib := TPDFlib.Create;
try
Lib.NewDocument;
Lib.SetPageSize('A4');
Lib.NewPage;
// WOFF2, WOFF1, TTF, OTF ja TTC tulevat kaikki saman kutsun kautta
FontID := Lib.AddOpenTypeFontFromFile('Inter.woff2', 0);
if FontID <= 0 then
raise Exception.Create('font could not be imported');
// Mitä tämä fontti oikeasti osaa?
if Lib.GetFontVariationAxes(FontID, AxesJSON) = 1 then
Log(AxesJSON); // tunnisteet, minimi, oletus, maksimi per akseli
// Leipoi yksi suunnittelusijainti staattiseksi fontiksi
InstanceID := Lib.CreateOpenTypeFontVariation(FontID,
'wght=620,wdth=87.5');
Lib.DrawOpenTypeText(56, 760, InstanceID, 24, 'Quarterly results', 0);
Lib.SaveToFile('report.pdf');
finally
Lib.Free;
end;
end;
Mitä instantiointi joutuu rakentamaan uudelleen, ja mitä se poistaa
Muuttujafontti tallentaa yhden oletusääriviivan per glyfi sekä delta-arvot indeksoituna suunnittelutilan positiolla. Staattisen instanssin tuottaminen tarkoittaa noiden deltojen interpolointia pyydetyissä koordinaateissa, pisteiden siirtämistä, ja sitten kaiken niistä johdetun uudelleenlaskemista
TrueType-ääriviivoille se tarkoittaa fvar:n, avar:n, gvar:n, HVAR:n ja MVAR:n jäsentämistä, tuple-deltojen soveltamista jaetulla ja yksityisellä pistenumeroinnilla, ja pisteiden interpolointia, joilla ei ole eksplisiittistä deltaa. Vaakasuuntaiset haamupisteet yhdessä HVAR:n kanssa määrittävät etenemäleveyden ja vasemman sivureunuksen. Yhdistelmäglyfit tarvitsevat komponenttiriippuvuutensa ja pistekuvauksensa ratkaistuna ensin, sitten käännös-, skaalaus-, matriisi- ja kiinnitysoffsetit sovellettuina — syvyysrajoilla ja syklien tunnistuksella, koska pahantahtoinen komponenttigraafi muuten rekursoituisi loputtomiin
Metatieto siirtyy myös, ja tämä on osa, jonka useimmat toteutukset ohittavat. MVAR päivittää globaalit mitat kentissä hhea, OS/2 ja post, joten riviväli, alleviivauksen sijainti ja kursiivikulma täsmäävät instanssia eivätkä oletusta. wght-, wdth-, ital- ja slnt-akselit lisäksi päivittävät painoluokan, leveysluokan, valintaliput, macStyle:n ja kursiivikulman, joten työkalu, joka tarkastaa staattisen fontin, raportoi pyytämäsi tyylin. Fontti, jonka geometria on lihavoitu ja jonka metatieto sanoo normaali, on väärin nimetty kaikkialla jatkokäytössä
Tuloste litistää sitten yhdistelmäääriviivat ja poistaa taulukot, joita ei enää sovelleta: variaatiotaulukot, vihjeet, laitetaulukot ja kaikki allekirjoitukset. Glyfirajat, hhea:n yhteenvetomitat, maxp:n vihjekatot, taulukkokohtaiset tarkistussummat ja koko fontin tarkistussumma kaikki lasketaan uudelleen
CFF2 kulkee eri reittiä samaan paikkaan
CFF2:ta ei voi upottaa suoraan PDF-fonttiohjelmana: sen merkkijonoilla ei ole leveyksiä, ja se nojaa ympäröiviin OpenType-taulukoihin glyfijärjestyksen ja mittojen suhteen. Joten CFF2-fontin instantiointi tuottaa sen sijaan CID-avaimistetun CFF-OpenType-fontin, jota olemassa olevat piirto-, upotus- ja osittamisreitit jo käsittelevät
Muuttujafontin lataaminen tuottaa heti oletuskoordinaattisen staattisen instanssin nykyiselle asiakirjalle, kun taas alkuperäinen CFF2-sfnt säilyy fonttiobjektissa, joten akseliluettelointi ja myöhempi instantiointi näkevät yhä koko suunnittelutilan. Jokainen glyfi de-alirutiinoidaan yksitellen instantioinnin aikana, mikä poistaa variaatiolaskennan kokonaan ja antaa olemassa olevan osittajan toimia muuttumattomana. Kompromissi on, että staattinen instanssi voi olla hieman suurempi kuin sellainen, joka säilytti jaetut alirutiinit — kohtuullinen hinta siitä, ettei tarvitse toista osittamistoteutusta
Instanssin varmentaminen ennen kuin luotat siihen
Instantiointi on sellainen ominaisuus, joka voi olla hienovaraisesti väärin tavoilla, joita mikään poikkeus ei raportoi. Kolme tarkistusta napsauttaa lähes kaiken
Vie instanssi ja avaa se fonttityökalussa. SaveFontToFile kirjoittaa säilytetyn fonttiohjelman, joten muistissa oleva instanssi voidaan tyhjentää tuottamatta PDF:ää ensin. Viedyn tiedoston pitäisi jäsentyä puhtaasti, sisältää ei variaatiotaulukoita, ja raportoida pyytämäsi tyylimetatieto
Vertaa etenemiä muussa kuin oletussijainnissa. Jos putkesi voi tuottaa saman instanssin toisella tavalla, vertaa etenemäleveyksiä ja käyrärajoja glyfi glyfiltä; vertailutoteutus tässä täsmäsi riippumattoman instantioinnin kanssa 313-glyfisellä kaksiakselisella fontilla, suurimman eron ollessa nolla jokaisella glyfillä
Ja poimi teksti takaisin ulos generoidusta PDF:stä. Instanssi, joka upottuu mutta ei tuota poimittavaa tekstiä, on menettänyt ToUnicode-kuvauksensa, millä on merkitystä haulle ja saavutettavuudelle kauan sen jälkeen kun visuaalinen tarkistus meni läpi. Laajempi poimintareitti on käsitelty artikkelissa tekstin, kuvien ja fonttien poiminta
// Vedä generoitu instanssi ulos tarkastelua tai uudelleenkäyttöä varten
Lib.SaveFontToFile('Inter-620-87.ttf');
// Pyydä koordinaatteja ilmoitetun alueen ulkopuolelta, ja ne leikataan,
// joten lue akseli-JSON sen sijaan että olettaisit fontin rajat
// {"axes":[{"tag":"wght","min":100,"default":400,"max":900}, ...]}
Käytännön huomioita brändifonttiputkelle
Välimuistita instanssit koordinaattijoukon mukaan. Jokainen erillinen koordinaattijoukko on erillinen fonttiohjelma, joten asiakirja, joka sekoittaa painoa 400 ja painoa 620, upottaa kaksi osajoukkoa yhden jaetun kirjasimen sijaan. Saman instanssin toistuva generointi on turhaa työtä; kymmenien lähes identtisten painojen generointi on turhaa tiedostokokoa
Mittaa sillä instanssilla, jolla piirrät. Kapealla instanssilla on kapeammat etenemät kuin oletuksella, joten mikä tahansa asettelu, joka mittasi ennen instantiointia, mittasi väärät leveydet. Tämä on yleisin yksittäinen syy tekstille, joka ylittää laatikkonsa vain tuotannossa
Pidä varareitti glyfeille, joita brändifontistasi puuttuu. Muuttuja brändifontti kattaa tyypillisesti latinalaiset merkit ja vähän muuta, ja raportti, joka sisältää kyrillisen asiakasnimen, näyttäisi muuten puuttuvia glyfejä; automaattinen varamekanismi on kuvattu artikkelissa automaattinen fontin varaminen puuttuville glyfeille. Ja kun tavoitteena on pienempi tiedosto tietyn painon sijaan, osittaminen tekee enemmän työtä kuin instantiointi, käsitelty artikkelissa PDF-tiedostokoon optimointi ja fontin osittaminen
Verkkofonttien tuonti, muuttujainstantiointi, osittaminen ja varaus ovat osa samaa fonttiputkea Delphille, C++Builderille ja Free Pascalille; täydellinen ominaisuusluettelo löytyy sivulta PDF Library for Delphi -sivu