Lyhyt vastaus siihen tukipyyntöön on kyllä, rajoituksin. HotPDF 2.730.0 toimii Free Pascal 3.2.2:lla ja Lazarus 4.6:lla Win64:llä, ja ydinluonti-, lataus- ja tallennuspolut toimivat. Mikä ei kulje mukana, on kaikki, mikä nojaa staattisesti linkitettyyn natiiviin kodekkiobjektiin tai Delphin anonyymeihin metodeihin
Kysymys saapuu yleensä samalla tavalla: tiimi vakioituu Lazaruksiin alustariippumattoman työkalun vuoksi tai perii Free Pascal -koodikannan ja haluaa saman PDF-komponentin, jota se jo lisensoi Delphille. Kypsän Delphi-kirjaston siirtäminen on harvoin syntaksiasia. Kiinnostava osa on se, mitä siirto paljastaa siitä, missä kirjasto oli hiljaa kytketty yhteen työkaluketjuun, ja tässä tapauksessa kytkös istuu kahdessa hyvin tarkassa paikassa: mukana tulevien kodekkien objektitiedosto-ABI:ssa ja versiosymbolin taakse kätkeytyneissä kääntäjäominaisuuksissa
Mitä Free Pascal 3.2.2 vaatii, ennen kuin HPDFDoc kääntyy
HotPDF kääntyy Free Pascalilla vain Delphi-tilassa, ja vain silloin, kun Lazarusin LCL-yksikköhakemistot ovat hakupolussa. Kumpikaan ei ole neuvoteltavissa. HotPDF.inc vaihtaa kääntäjän tilan {$MODE DELPHI}llä ja {$H+}llä {$IFDEF FPC}-lohkonsa sisällä ja kieltäytyy kaikesta vanhemmasta {$FATAL}illa, kun FPC_FULLVERSION on alle 30202, joten 3.0.x-asennus epäonnistuu äänekkäästi eikä tuota rikkinäistä yksikköä. Lazarusin ajopaketti HotPDFLaz.lpk koodaa loput: LCL vaadittavana pakettina ja -Mdelphi mukautettuna valintana
LCL-vaatimus yllättää ne, jotka haluavat vain konsolitulosteen, mutta se on rakenteellinen. HPDFFPCCompat toimittaa Delphin VCL-tyypit, joilla ei ole Free Pascal -vastinetta, yhdistämällä TMetafilen ja TMetafileCanvasin LCL:n bittikartta- ja piirtoalustaluokkiin ja aliasoimalla TRichEditin TMemoksi, kun taas HPDFDoc aliasoi TPNGObjectin Graphics.TPortableNetworkGraphicksi. Käsittele niitä käännösaikaisina shimmeinä, ei ominaisuuspariteettina: bittikarttaan tukeutuva metafile-luokka pitää yksikön kääntyvänä, se ei tee metafile-poluista Delphin kaltaisia. Jo ei-GUI-smoketestaus vetää Interfacesin mukaan, ja koontiskripti antaa -Fulle arvot lcl\units\x86_64-win64 ja lazutils-tulostehakemisto
Miksi D2009+ ei voi toimia myös versioporttina
On houkuttelevaa käsitellä Free Pascal -rakennusta nykyaikaisena kääntäjänä ja yksinkertaisesti määritellä uusin Delphi-ominaisuussymboli. HotPDF ei tee niin, ja syy kannattaa sanoa suoraan: D2009+ ei tarkoita pelkkää Unicode-merkkijonoja, se portittaa myös yksiköt, joiden julkinen API on ilmaistu anonyymeillä metodeilla. Free Pascal 3.2.2 ei tue Delphin anonyymejä metodeja eikä niitä API:ja, joten symbolin lainaaminen raahaisi mukaan koodia, joka ei voi kääntyä. HPDFDocin uses-lause kantaa siksi kahta erillistä ehdollista häntää, ja niiden välinen päällekkäisyys on tahallista, ei sattumaa
uses
// ...
HPDFJavaScript,
HPDFFormCalcGraph
{$IFDEF FPC}
, HPDFFPCCodecStubs,
HPDFCMS,
HPDFWinCertSigner
{$ENDIF}
{$IFDEF D2009+}
, HPDFXFARuntime,
HPDFCMS,
HPDFWinCertSigner,
HPDFSignVerify,
HPDFSignatureBatch
{$ENDIF};
Miksi natiivit kodekit pysähtyvät linkittimeen?
Koska ne ovat yhden tietyn työkaluketjun emittoimia Win64-COFF-objekteja, eikä kumpikaan Free Pascal -linkittäjä kuluta niitä Win64:llä: ei sisäinen linkittäjä, ei ulkoinen GNU ld -polku. Tämä on objektitiedoston ABI-ongelma, ei Pascal-ongelma, eikä mikään määrä ehdollista lähdekoodia korjaa sitä. Kirjasto ottaa ainoan rehellisen käytettävissä olevan reitin. Jokainen staattisen kodekkiobjektin mukaan vetävä {$L}-direktiivi on kääritty {$IFNDEF FPC}iin, joten Free Pascal -rakennus jättää ne yksinkertaisesti pois, ja HPDFFPCCodecStubs toimittaa sitten jokaisen puuttuvan ulkoisen symbolin stubina, joka nostaa poikkeuksen palauttamisen sijaan
// HPDFFPCCodecStubs.pas
function HPDFFPCNativeCodecUnavailable: PtrUInt;
begin
raise ENotSupportedException.Create(
'This native codec is not available in the Free Pascal build');
end;
function HPDFFPCStub_deflate: PtrUInt; cdecl;
public name 'deflate';
begin
Result := HPDFFPCNativeCodecUnavailable;
end;
Tuo stubitaulukko on pitkä, ja sen lukeminen kertoo tarkalleen, mitkä ominaisuudet ovat tänään vain Delphille: zlib-ng:n ja zopflin deflate-aloituspisteet, libjpegin pakkaus ja purku, OpenJPEG:n JPEG 2000 -kodekki, libtiff ja sen pakkauskohtaiset alustajat, JBIG2-koodaus ja -purku, Little-CMS:n värimuunnoksen aloituspisteet ja AES-primitiivit. Stubien takana oleva suunnitteluratkaisu merkitsee enemmän kuin lista. Puuttuva symboli linkityshetkellä antaa sinulle seinän täynnä määrittelemättömiä viittauksia yksiköstä, jota et koskaan koskenut; poikkeuksen nostava ENotSupportedException-stub antaa sinulle rakennuksen, joka toimii, viestin, joka nimeää syyn, ja pinolistausen, joka osoittaa kutsupaikkaan. Se tarkoittaa myös, ettei Free Pascal -rakennus koskaan tuota hiljaa vääriä tavuja, joissa Delphi-rakennus tuottaisi oikeat. Huomaa myös toisen asteen vaikutus: epäluotettavien kuvakodekkien ajaminen eristetyssä prosessissa on päätös, joka herää vain Delphi-rakennuksessa, koska Free Pascal -rakennuksella ei ole prosessin sisäistä natiivipurkajaa, joka voitaisiin eristää hiekkalaatikkoon
Pakkaus: ensimmäinen muutettava rivi on cmNone
Ennen kuin siirrät mitään muuta, aseta Compression arvoon cmNone. THPDFCompressionMethod tarjoaa täsmälleen kaksi arvoa, cmNone ja cmFlateDecode, ja jälkimmäinen ohjautuu suoraan niihin deflate-aloituspisteisiin, jotka ovat stubit Free Pascal -rakennuksessa. Varmista ydinobjektimalli ensin pakkauksen ollessa pois päältä ja päätä sitten, mitä muuta tarvitset. Se on järjestys, jota mukana toimitettu smoketestaus noudattaa: luo yhden sivun pakkaamaton dokumentti, lataa se uudelleen ja varmista, että sivumäärä palasi ykkösenä. Pakkaamaton tuloste on suurempi, ja se on silti täysin kelvollinen PDF
program HotPDFLazarusSmoke;
{$mode delphi}
{$H+}
uses
Interfaces, SysUtils, HPDFDoc;
var
Pdf, Reloaded: THotPDF;
OutputFile: string;
PageCount: Integer;
begin
OutputFile := IncludeTrailingPathDelimiter(GetTempDir) +
'HotPDF-FPC-Smoke.pdf';
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := OutputFile;
Pdf.Compression := cmNone; // cmFlateDecode päätyy stubattuun symboliin
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 12);
Pdf.CurrentPage.TextOut(72, 72, 0, 'HotPDF Free Pascal smoke test');
Pdf.EndDoc;
finally
Pdf.Free;
end;
Reloaded := THotPDF.Create(nil);
try
PageCount := Reloaded.LoadFromFile(OutputFile);
if PageCount <> 1 then
raise Exception.CreateFmt('Expected one page, got %d', [PageCount]);
finally
Reloaded.Free;
end;
end.
Mitä tapahtuu rinnakkaiselle sivunpiirrolle?
Se kääntyy yhä, palauttaa yhä oikeita bittikarttoja ja lakkaa olemasta rinnakkainen. THotPDF.RenderLoadedPagesParallel ja THotPDF.RenderLoadedPagesParallelOrdered rakentuvat TThread.CreateAnonymousThreadin päälle sisäänrakennetulla procedure-sulkeumalla, jota Free Pascal 3.2.2 ei osaa ilmaista, joten Free Pascal -haara ajaa deterministisen sarjallisen varatoiminnon: se kulkee sivuindeksit järjestyksessä, kutsuu RenderLoadedPageToBitmapia jokaiselle ja laskee onnistumiset. API:n muoto, paluuarvo ja tulostetaulukko ovat muuttumattomia, mikä mahdollistaa saman koodikannan rakentamisen molemmilla tavoilla
var
Bitmaps: THPDFBitmapArray;
Info: THPDFParallelRenderPipelineInfo;
Rendered: Integer;
begin
Rendered := Pdf.RenderLoadedPagesParallel([0, 1, 2, 3], 150, 4,
Bitmaps, Info);
// Delphi: Info.WorkerCount on se, minkä muistibudjetti salli
// Free Pascal: Info.WorkerCount on aina 1, sivut indeksijärjestyksessä
if Info.WorkerCount = 1 then
LogSerialFallback(Rendered, Info.RequestedWorkerCount);
Varatoiminto ei ole hiljainen, ja juuri se on osa, joka kannattaa ottaa suunnittelun lähtökohdaksi. Se täyttää THPDFParallelRenderPipelineInfon rehellisesti: PageCountin pyynnöstä, RequestedWorkerCountin kaikuna siitä, mitä pyysit, WorkerCountin arvolla 1 sekä valmistuneiden ja toimitettujen lukumäärät täsmäämässä sen kanssa, mikä oikeasti palasi. Koodi, joka jo tarkastelee Infoa mitoittaakseen edistymispalkin tai muistibudjetin, jatkaa toimimistaan ja lukee totuuden oletuksen sijaan. Jos läpivirtaussuunnitelmasi nojaa rinnakkaispiirtoputkeen ja sen takapainemalliin, kyseinen suunnitelma on Delphi-suunnitelma; Free Pascalilla budjetoi sivun piirtämisen bittikartaksi yksisäikeisenä kustannuksena kerrottuna sivumäärällä
Mitä rakennusta sinun oikeasti kannattaa toimittaa?
Valitse ominaisuuksien, eivät mieltymysten, perusteella. Jos työnkulkusi on dokumenttien kokoamista, tekstin ja vektorien piirtämistä, lomakkeiden täyttöä, lataamista ja tallentamista, Free Pascal -rakennus Win64:llä kattaa sen, ja sinun kannattaa validoida pakkaus pois päältä ennen kuin kytket mitään päälle. Jos siihen kuuluu JPEG-, JPEG 2000-, TIFF- tai JBIG2-kuvia, ICC-värimuunnoksia, pakattua tulostetta tai useisiin ytimiin nojaavaa läpivirtausta, pysy toistaiseksi Delphissä tai C++Builderissa. Rajan vetää objektitiedoston ABI ja puuttuva kielen ominaisuus, molemmat näkyvissä lähdekoodissa sen sijaan, että ne olisi haudattu tukimatriisiin, ja molemmat epäonnistuvat nimetyllä virheellä väärän tuloksen sijaan
Free Pascal- ja Lazarus-paketti toimitetaan samassa jakelussa kuin Delphi- ja C++Builder-yksiköt, joten lisenssi kattaa molemmat ja voit testata Lazarus-polun omilla dokumenteillasi ennen kuin sitoudut siihen; tuotesivu HotPDF Delphi PDF Component kantaa ajantasaisen kääntäjätukimatriisin ja täyden API-referenssin