Krátky odpoveď na ten support ticket je áno, s limitmi. HotPDF 2.730.0 sa zostavuje na Free Pascale 3.2.2 a Lazare 4.6 pre Win64 a jadrové cesty vytvorenia, načítania a uloženia fungujú. Čo nenasleduje, je čokoľvek spočívajúce na staticky linkovanom natívnom kodekovom objekte alebo na Delphi anonymných metódach
Otázka zvyčajne prichádza rovnako: tím štandardizuje na Lazare pre cross-platformový nástroj, alebo zdedí Free Pascal kódex a chce ten istý PDF komponent, ktorý už licencujú pre Delphi. Portácia zrelej Delphi knižnice je zriedka záležitosť syntaxe. Zaujímavá časť je, čo portácia odhalí o tom, kde bola knižnica potichu spojená s jedným toolchainom, a v tomto prípade spojenie sedí na dvoch veľmi špecifických miestach: ABI objektových súborov priložených kodekov a kompilátorové vlastnosti skryté za verziovým symbolom
Čo Free Pascal 3.2.2 potrebuje, kým HPDFDoc skompiluje
HotPDF sa kompiluje pod Free Pascalom len v Delphi režime a len keď sú adresáre jednotiek Lazarus LCL na search path. Ani jedno sa nedá vyjednať. HotPDF.inc prepína kompilátor s {$MODE DELPHI} a {$H+} vo vnútri svojho bloku {$IFDEF FPC} a odmieta čokoľvek staršie s {$FATAL}, keď FPC_FULLVERSION je pod 30202, takže inštalácia 3.0.x zlyhá nahlas namiesto produkcie rozbitnej jednotky. Lazarus runtime balík HotPDFLaz.lpk kóduje zvyšok: LCL ako povinný balík a -Mdelphi ako vlastná voľba
Požiadavka LCL prekvapí ľudí, ktorí chcú len výstup do konzoly, ale je štrukturálna. HPDFFPCCompat dodáva Delphi VCL typy, pre ktoré Free Pascal nemá ekvivalent, mapujúc TMetafile a TMetafileCanvas na LCL bitmapové a canvas triedy a aliasujúc TRichEdit na TMemo, zatiaľ čo HPDFDoc aliasuje TPNGObject na Graphics.TPortableNetworkGraphic. Považujte tie za kompilačné shimy, nie paritu vlastností: trieda metafilu podložená bitmapou drží jednotku kompilujúcu, nerobí cesty metafilu správať sa tak, ako na Delphi. Aj non-GUI smoke test ťahá Interfaces a build skript posiela -Fu pre lcl\units\x86_64-win64 a výstupný adresár lazutils
Prečo D2009+ nemôže slúžiť ako verzióva brána
Je lákavé považovať Free Pascal zostavu za moderný kompilátor a jednoducho definovať najnovší symbol vlastností Delphi. HotPDF to nerobí a dôvod stojí za to povedať priamo: D2009+ neznamená len Unicode reťazce, taktiež bráni jednotkám, ktorých verejné API je vyjadrené anonymnými metódami. Free Pascal 3.2.2 nepodporuje ani Delphi anonymné metódy, ani tie API, takže požičanie symbolu by vtiahlo kód, ktorý sa nedá skompilovať. Uses klauzula HPDFDoc preto nesie dva samostatné kondicionálne chvosty a ich prekrytie je zámerne, nie náhodné
uses
// ...
HPDFJavaScript,
HPDFFormCalcGraph
{$IFDEF FPC}
, HPDFFPCCodecStubs,
HPDFCMS,
HPDFWinCertSigner
{$ENDIF}
{$IFDEF D2009+}
, HPDFXFARuntime,
HPDFCMS,
HPDFWinCertSigner,
HPDFSignVerify,
HPDFSignatureBatch
{$ENDIF};
Prečo sa natívne kodeky zastavia pri linkeri?
Pretože sú to Win64 COFF objekty emitované jedným konkrétnym toolchainom a ani jeden Free Pascal linker na Win64 ich nespotrebuje: ani interný linker, ani externá GNU ld cesta. Toto je problém ABI objektových súborov, nie Pascal problém a žiadne množstvo kondicionálneho zdroja to neopraví. Knižnica berie jedinú úprimnú cestu dostupnú. Každá direktíva {$L}, ktorá ťahá statický kodekový objekt, je zabalená v {$IFNDEF FPC}, takže Free Pascal zostava ich jednoducho vynechá a HPDFFPCCodecStubs potom dodá každý chýbajúci externý symbol ako stub, ktorý vyvolá výnimku namiesto vrátenia
// 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;
Tá stubová tabuľka je dlhá a jej čítanie vám povie presne, ktoré schopnosti sú dnes Delphi-only: vstupné body deflate zlib-ng a zopfli, kompresia a dekompresia libjpeg, kodek OpenJPEG JPEG 2000, libtiff a jeho per-kompresné inicializátory, JBIG2 encode a decode, farebné transformačné vstupné body Little-CMS a AES primitívy. Dizajnová voľba za stubmi záleží viac než zoznam. Chýbajúci symbol v čase linku vám dá stenu nedefinovaných referencií z jednotky, ktorej ste sa nikdy nedotkli; stub, ktorý vyvolá ENotSupportedException, vám dá zostavu, ktorá beží, správu pomenuvajúcu dôvod a stack trace ukazujúci na miesto volania. Znamená to tiež, že Free Pascal zostava nikdy mlčky neprodukuje zlé bajty tam, kde by Delphi zostava produkovala správne. Všimnite si efekt druhého rádu tiež: behanie nedôveryhodných obrazových kodekov v izolovanom procese je rozhodnutie, ktoré vzniká len na Delphi zostave, pretože Free Pascal zostava nemá v procese natívny dekodér, ktorý by bolo treba sandboxovať
Kompresia: prvý riadok na zmenu je cmNone
Skôr než portujete čokoľvek iné, nastavte Compression na cmNone. THPDFCompressionMethod ponúka presne dve hodnoty, cmNone a cmFlateDecode a druhá smeruje rovno do vstupných bodov deflate, ktoré sú stubmi vo Free Pascal zostave. Overte najprv jadrový objektový model s kompresiou vypnutou, potom si rozhodnite, čo iné potrebujete. To je poradie, ktoré dodávaný smoke test používa: vytvoriť jednostranový nekomprimovaný dokument, znova ho načítať a asertovať, že počet strán sa vrátil ako jedna. Nekomprimovaný výstup je väčší a je to stále úplne platné 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 dosahuje stubovaný symbol
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.
Čo sa stane s paralelným renderovaním strán?
Stále sa kompiluje, stále vracia správne bitmapy a prestáva byť paralelné. THotPDF.RenderLoadedPagesParallel a THotPDF.RenderLoadedPagesParallelOrdered sú postavené na TThread.CreateAnonymousThread s inline procedure uzáverom, ktorý Free Pascal 3.2.2 nedokáže vyjadriť, takže Free Pascal vetva beží deterministický sekvenčný fallback: prechádza indexy strán v poradí, volá RenderLoadedPageToBitmap pre každý a počíta úspechy. Tvar API, návratová hodnota a výstupné pole sú nezmenené, čo je to, čo dovoľuje jedinému kódexu stavať sa obojsmerne
var
Bitmaps: THPDFBitmapArray;
Info: THPDFParallelRenderPipelineInfo;
Rendered: Integer;
begin
Rendered := Pdf.RenderLoadedPagesParallel([0, 1, 2, 3], 150, 4,
Bitmaps, Info);
// Delphi: Info.WorkerCount je to, čo pamäťový rozpočet dovolil
// Free Pascal: Info.WorkerCount je vždy 1, strany v poradí indexov
if Info.WorkerCount = 1 then
LogSerialFallback(Rendered, Info.RequestedWorkerCount);
Fallback nie je tichý, čo je časť, ktorú stojí za to navrhnúť okolo. Napĺňa THPDFParallelRenderPipelineInfo úprimne: PageCount z žiadosti, RequestedWorkerCount odrážajúci to, čo ste požiadali, WorkerCount nastavený na 1 a dokončené a doručené počty zodpovedajúce tomu, čo skutočne prišlo späť. Kód, ktorý už inšpektuje Info na rozmery progres baru alebo pamäťového rozpočtu, funguje ďalej a číta pravdu namiesto predpokladu. Ak váš throughput plán závisí na paralelnej renderovacej pipeline a jej modeli backpressure, ten plán je Delphi plán; na Free Pascale rozpočítajte jednovláknové náklady renderovania strany na bitmapu vynásobené počtom strán
Ktorú zostavu by ste mali naozaj odoslať?
Vyberajte podľa schopností, nie podľa preferencie. Ak váš workflow je skladanie dokumentov, textové a vektorové kreslenie, plnenie formulárov, načítanie a uloženie, Free Pascal zostava na Win64 to pokrýva a mali by ste validovať s kompresiou vypnutou, než čokoľvek zapnete. Ak zahŕňa JPEG alebo JPEG 2000 alebo TIFF alebo JBIG2 obrázky, ICC farebné transformácie, komprimovaný výstup alebo throughput závislý na veľa jadrách, ostávajte zatiaľ na Delphi alebo C++Builder. Hranica je nakreslená ABI objektového súboru a chýbajúcou jazykovou vlastnosťou, obe viditeľné v zdroji namiesto zakopaných v support matici a obe zlyhávajú s pomenovanou chybou namiesto zlého výsledku
Free Pascal a Lazarus balík sa dodáva v tej istej distribúcii ako jednotky Delphi a C++Builder, takže licencia pokrýva oboje a môžete testovať Lazarus cestu proti vlastným dokumentom skôr, než sa ju zavážete; produktová stránka HotPDF Delphi PDF Component nesie aktuálnu maticu podpory kompilátorov a kompletnú API referenciu