Kratki odgovor na taj zahtjev za podrškom glasi da, uz ograničenja. HotPDF 2.730.0 gradi se na Free Pascalu 3.2.2 i Lazarusu 4.6 za Win64, a osnovni putevi stvaranja, učitavanja i spremanja rade. Ono što ne slijedi je sve što počiva na statički povezanom objektu nativnog kodeka ili na Delphi anonimnim metodama
Pitanje obično stiže na isti način: tim se standardizira na Lazarusu za alat na više platformi, ili nasljeđuje Free Pascal bazu koda, i želi istu PDF komponentu koju već licencira za Delphi. Prenošenje zrele Delphi knjižnice rijetko je pitanje sintakse. Zanimljiv je dio što prijenos otkriva o mjestima gdje je knjižnica tiho bila vezana uz jedan alatni lanac, a u ovom je slučaju ta veza na dva vrlo konkretna mjesta: ABI objektnih datoteka priloženih kodeka i jezične mogućnosti skrivene iza verzijske oznake
Što Free Pascal 3.2.2 treba prije nego što se HPDFDoc kompilira
HotPDF se pod Free Pascalom kompilira samo u Delphi načinu rada, i to samo kada su direktoriji jedinica Lazarus LCL-a na putu pretraživanja. Ništa od toga nije podložno pregovaranju. HotPDF.inc prebacuje kompilator s {$MODE DELPHI} i {$H+} unutar svog bloka {$IFDEF FPC} i odbija sve starije s {$FATAL} kada je FPC_FULLVERSION ispod 30202, pa instalacija 3.0.x glasno propada umjesto da proizvede neispravnu jedinicu. Runtime paket za Lazarus HotPDFLaz.lpk kodira ostalo: LCL kao obavezan paket i -Mdelphi kao prilagođenu opciju
Zahtjev za LCL iznenađuje one koji žele samo konzolni izlaz, ali on je strukturan. HPDFFPCCompat dostavlja Delphi VCL tipove za koje Free Pascal nema ekvivalent, preslikavajući TMetafile i TMetafileCanvas na LCL klase bitmapa i platna te aliasirajući TRichEdit na TMemo, dok HPDFDoc aliasira TPNGObject na Graphics.TPortableNetworkGraphic. Tretirajte to kao kompilacijske podloške, a ne kao paritet mogućnosti: metafile klasa koju nosi bitmapa održava jedinicu kompilabilnom, ali ne čini da se putevi metafilea ponašaju kako se ponašaju na Delphiju. Čak i negrafički smoke test povlači Interfaces, a skripta za gradnju predaje -Fu za lcl\units\x86_64-win64 i za izlazni direktorij lazutils
Zašto D2009+ ne može biti i granica verzije
Primamljivo je tretirati Free Pascal izgradnju kao moderni kompilator i jednostavno definirati najnoviji Delphi simbol mogućnosti. HotPDF to ne čini, a razlog vrijedi izreći jasno: D2009+ ne znači samo Unicode nizove, on je također kapija jedinicama čiji je javni API izražen anonimnim metodama. Free Pascal 3.2.2 ne podržava ni Delphi anonimne metode ni te API-je, pa bi posuđivanje simbola uvlaklo kod koji se ne može kompilirati. Uses klauzula HPDFDoc-a stoga nosi dva odvojena uvjetna repa, a njihovo preklapanje namjerno je, a ne slučajno
uses
// ...
HPDFJavaScript,
HPDFFormCalcGraph
{$IFDEF FPC}
, HPDFFPCCodecStubs,
HPDFCMS,
HPDFWinCertSigner
{$ENDIF}
{$IFDEF D2009+}
, HPDFXFARuntime,
HPDFCMS,
HPDFWinCertSigner,
HPDFSignVerify,
HPDFSignatureBatch
{$ENDIF};
Zašto se nativni kodeci zaustavljaju na linkaru?
Jer su to Win64 COFF objekti koje je emitirao jedan konkretan alatni lanac, a nijedan Free Pascal linkar na Win64 neće ih konzumirati: ni interni linkar, ni vanjski put s GNU ld. To je ABI problem objektnih datoteka, a ne Pascal problem, i nijedna količina uvjetnog koda to ne rješava. Knjižnica bira jedini pošten dostupan put. Svaka direktiva {$L} koja uvlači statički objekt kodeka obavijena je s {$IFNDEF FPC}, pa Free Pascal izgradnja jednostavno izostavlja te objekte, a HPDFFPCCodecStubs zatim svaki nedostajući vanjski simbol dostavlja kao stub koji podiže iznimku umjesto da vrati
// 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;
Ta je tablica stubova dugačka, a njezino čitanje točno vam kaže koje su mogućnosti danas samo za Delphi: ulazne točke deflate od zlib-ng i zopfli, kompresija i dekompresija libjpega, OpenJPEG JPEG 2000 kodek, libtiff s njegovim inicijalizatorima po kompresiji, JBIG2 kodiranje i dekodiranje, ulazne točke pretvorbi boja Little-CMS-a i AES primitivi. Dizajnerska odluka iza stubova važnija je od popisa. Nedostajući simbol u trenutku povezivanja donosi zid nedefiniranih referenci iz jedinice koju nikada niste dirnuli; stub koji podiže ENotSupportedException donosi izgradnju koja radi, poruku koja imenuje razlog i stack trace koji pokazuje na mjesto poziva. To također znači da Free Pascal izgradnja nikada tiho ne proizvodi pogrešne bajtove tamo gdje bi Delphi izgradnja proizvela ispravne. Uočite i učinak drugog reda: izvođenje nepouzdanih kodeka slika u izoliranom procesu odluka je koja se javlja samo na Delphi izgradnji, jer Free Pascal izgradnja nema in-process nativni dekoder koji bi se uopće mogao izolirati
Kompresija: prvi red koji treba promijeniti je cmNone
Prije nego što prenesete bilo što drugo, postavite Compression na cmNone. THPDFCompressionMethod nudi točno dvije vrijednosti, cmNone i cmFlateDecode, a druga vodi ravno u ulazne točke deflate koje su u Free Pascal izgradnji stubovi. Prvo provjerite temeljni objektni model uz isključenu kompresiju, a zatim odlučite što još trebate. To je redoslijed koji koristi priloženi smoke test: stvorite jednostranični nekompresirani dokument, ponovno ga učitajte i provjerite da se broj stranica vratio kao jedan. Nekompresirani izlaz je veći, a i dalje je sasvim valjani 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 završava na stubiranom simbolu
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.
Što se događa s paralelnim renderiranjem stranica?
I dalje se kompilira, i dalje vraća ispravne bitmape, i prestaje biti paralelno. THotPDF.RenderLoadedPagesParallel i THotPDF.RenderLoadedPagesParallelOrdered građeni su na TThread.CreateAnonymousThread s inline procedure zatvaranjem koje Free Pascal 3.2.2 ne može izraziti, pa Free Pascal grana izvodi deterministički serijski fallback: prolazi indekse stranica redom, poziva RenderLoadedPageToBitmap za svaki i broji uspjehe. Oblik API-ja, povratna vrijednost i izlazno polje nepromijenjeni su, što omogućuje da jedna baza koda gradi u oba smjera
var
Bitmaps: THPDFBitmapArray;
Info: THPDFParallelRenderPipelineInfo;
Rendered: Integer;
begin
Rendered := Pdf.RenderLoadedPagesParallel([0, 1, 2, 3], 150, 4,
Bitmaps, Info);
// Delphi: Info.WorkerCount je ono što je budžet memorije dopustio
// Free Pascal: Info.WorkerCount je uvijek 1, stranice u redoslijedu indeksa
if Info.WorkerCount = 1 then
LogSerialFallback(Rendered, Info.RequestedWorkerCount);
Fallback nije tih, i to je dio vrijedan oblikovanja oko njega. THPDFParallelRenderPipelineInfo popunjava pošteno: PageCount iz zahtjeva, RequestedWorkerCount koji odjekuje ono što ste tražili, WorkerCount postavljen na 1, te brojače dovršenih i dostavljenih koji odgovaraju onome što je stvarno stiglo. Kod koji već pregledava Info da dimenzionira traku napretka ili budžet memorije i dalje radi i čita istinu umjesto pretpostavke. Ako vaš plan propusnosti ovisi o paralelnoj rendererskoj cjevovodnoj liniji i njezinu modelu povratnog tlaka, taj plan je Delphi plan; na Free Pascalu računajte trošak renderiranja stranice u bitmapu u jednoj niti pomnožen brojem stranica
Koju izgradnju biste stvarno isporučili?
Birajte prema mogućnostima, ne prema sklonostima. Ako je vaš tok rada sastavljanje dokumenata, crtanje teksta i vektora, popunjavanje obrazaca, učitavanje i spremanje, Free Pascal izgradnja na Win64 to pokriva, i trebali biste provjeriti uz isključenu kompresiju prije nego što išta uključite. Ako uključuje JPEG ili JPEG 2000 ili TIFF ili JBIG2 slike, ICC pretvorbe boja, kompresirani izlaz ili propusnost koja ovisi o mnogim jezgrama, za sada ostanite na Delphiju ili C++Builderu. Granicu crtaju ABI objektnih datoteka i nedostajuća jezična mogućnost, obje vidljive u izvornom kodu umjesto zakopane u matricu podrške, i obje propadaju s imenovanom pogreškom umjesto pogrešnim rezultatom
Free Pascal i Lazarus paket isporučuje se u istoj distribuciji kao Delphi i C++Builder jedinice, pa jedna licenca pokriva oboje i možete isprobati Lazarus put na svojim dokumentima prije nego što mu se obvežete; stranica proizvoda HotPDF Delphi PDF Component nosi trenutnu matricu podrške kompilatora i potpunu API referencu