O destek talebinin kısa yanıtı evet, sınırlarla. HotPDF 2.730.0, Free Pascal 3.2.2 ve Lazarus 4.6 üzerinde Win64 için derlenir ve temel oluşturma, yükleme ve kaydetme yolları çalışır. Beraberinde gelmeyen şey, statik bağlı yerli bir codec nesnesine ya da Delphi anonim yöntemlerine dayanan her şeydir
Soru genellikle aynı şekilde gelir: bir ekip platformlar arası bir araç için Lazarus üzerinde standardize olur ya da bir Free Pascal kod tabanını devralır ve Delphi için zaten lisansladığı PDF bileşeninin aynısını ister. Olgun bir Delphi kitaplığını taşımak nadiren bir söz dizimi meselesidir. İlginç olan, taşıma işleminin kitaplığın tek bir araç zincirine sessizce nereden bağlandığını açığa çıkarmasıdır; bu durumda bağlanım iki çok özel yerde durur: birlikte gelen codec dosyalarının nesne dosyası ABI katmanı ve bir sürüm simgesinin arkasına saklanan derleyici özellikleri
HPDFDoc derlenmeden önce Free Pascal 3.2.2 neye ihtiyaç duyar
HotPDF, Free Pascal altında yalnızca Delphi modunda ve yalnızca Lazarus LCL birim dizinleri arama yolundayken derlenir. İkisi de pazarlık edilemez. HotPDF.inc, {$IFDEF FPC} bloğunun içinde {$MODE DELPHI} ve {$H+} ile derleyiciyi değiştirir ve FPC_FULLVERSION 30202 altındayken {$FATAL} ile daha eskisini reddeder; böylece bir 3.0.x kurulumu bozuk bir birim üretmek yerine gürültülü biçimde başarısız olur. Lazarus çalışma zamanı paketi HotPDFLaz.lpk gerisini kodlar: gerekli paket olarak LCL ve özel seçenek olarak -Mdelphi
LCL gereksinimi, yalnızca konsol çıktısı isteyenleri şaşırtır ama yapısaldır. HPDFFPCCompat, Free Pascal tarafında karşılığı olmayan Delphi VCL türlerini sağlar: TMetafile ve TMetafileCanvas türlerini LCL bitmap ve canvas sınıflarına eşler, TRichEdit öğesini TMemo öğesine takma ad yapar; HPDFDoc ise TPNGObject öğesini Graphics.TPortableNetworkGraphic öğesine takma ad yapar. Bunları özellik eşitliği değil derleme zamanı dolgusu sayın: bir bitmap tarafından desteklenen metafile sınıfı birimi derlenebilir tutar, metafile yollarının Delphi üzerindeki gibi davranmasını sağlamaz. GUI olmayan duman testi bile Interfaces birimini içeri çeker ve derleme betiği lcl\units\x86_64-win64 ile lazutils çıktı dizini için -Fu geçer
D2009+ neden sürüm kapısı olarak kullanılamaz
Free Pascal derlemesini modern bir derleyici sayıp en yeni Delphi özellik simgesini tanımlamak caziptir. HotPDF bunu yapmaz ve nedeni açıkça söylemeye değer: D2009+ yalnızca Unicode dizgiler demek değildir; genel API kısmı anonim yöntemlerle ifade edilen birimlerin de kapısıdır. Free Pascal 3.2.2, Delphi anonim yöntemlerini de o API parçalarını da desteklemez; simgeyi ödünç almak derlenemeyecek kodu içeri sürüklerdi. HPDFDoc biriminin uses cümlesi bu yüzden iki ayrı koşullu kuyruk taşır ve aralarındaki çakışma tesadüf değil bilinçlidir
uses
// ...
HPDFJavaScript,
HPDFFormCalcGraph
{$IFDEF FPC}
, HPDFFPCCodecStubs,
HPDFCMS,
HPDFWinCertSigner
{$ENDIF}
{$IFDEF D2009+}
, HPDFXFARuntime,
HPDFCMS,
HPDFWinCertSigner,
HPDFSignVerify,
HPDFSignatureBatch
{$ENDIF};
Yerli codec bileşenleri neden bağlayıcıda durur?
Çünkü bunlar belirli bir araç zincirinin ürettiği Win64 COFF nesneleridir ve Win64 üzerindeki iki Free Pascal bağlayıcısı da bunları tüketmez: ne dahili bağlayıcı ne de harici GNU ld yolu. Bu bir Pascal sorunu değil nesne dosyası ABI sorunudur ve hiçbir miktarda koşullu kaynak bunu düzeltmez. Kitaplık mevcut tek dürüst yolu izler. Statik codec nesnesini içeri çeken her {$L} yönergesi {$IFNDEF FPC} ile sarılır; böylece Free Pascal derlemesi onları basitçe atlar ve HPDFFPCCodecStubs eksik her dış simgeyi dönmek yerine hata fırlatan bir taslak olarak sağlar
// 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;
Bu taslak tablosu uzundur ve okumak size bugün hangi yeteneklerin yalnızca Delphi tarafında olduğunu tam olarak söyler: zlib-ng ve zopfli deflate giriş noktaları, libjpeg sıkıştırma ve açma, OpenJPEG JPEG 2000 codec bileşeni, libtiff ve sıkıştırma başına başlatıcıları, JBIG2 kodlama ve çözme, Little-CMS renk dönüşümü giriş noktaları ve AES temelleri. Taslakların arkasındaki tasarım seçimi listeden daha önemlidir. Bağlama zamanında eksik bir simge, hiç dokunmadığınız bir birimden duvar gibi tanımsız başvurular verir; ENotSupportedException fırlatan bir taslak ise çalışan bir derleme, nedeni adlandıran bir ileti ve çağrı yerini gösteren bir yığın izi verir. Bu aynı zamanda Free Pascal derlemesinin, Delphi derlemesinin doğru bayt üreteceği yerde asla sessizce yanlış bayt üretmemesi demektir. İkinci dereceden etkiyi de not edin: güvenilmeyen görüntü codec bileşenlerini yalıtılmış bir işlemde çalıştırmak yalnızca Delphi derlemesinde ortaya çıkan bir karardır; çünkü Free Pascal derlemesinde baştan korumalı alana alınacak işlem içi yerli kod çözücü yoktur
Sıkıştırma: değişecek ilk satır cmNone
Başka bir şey taşımadan önce Compression değerini cmNone yapın. THPDFCompressionMethod tam olarak iki değer sunar: cmNone ve cmFlateDecode; ikincisi doğrudan Free Pascal derlemesinde taslak olan deflate giriş noktalarına gider. Önce çekirdek nesne modelini sıkıştırma kapalıyken doğrulayın, sonra başka neye ihtiyacınız olduğuna karar verin. Birlikte gelen duman testi bu sırayı kullanır: tek sayfalık sıkıştırılmamış bir belge oluştur, yeniden yükle ve sayfa sayısının bir döndüğünü doğrula. Sıkıştırılmamış çıktı daha büyüktür ve yine de tamamen geçerli bir PDF olur
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 taslaklanmış bir simgeye gider
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.
Paralel sayfa işlemeye ne olur?
Yine derlenir, yine doğru bitmap döndürür ve paralel olmaktan çıkar. THotPDF.RenderLoadedPagesParallel ve THotPDF.RenderLoadedPagesParallelOrdered, satır içi bir procedure kapanışıyla TThread.CreateAnonymousThread üzerine kuruludur; Free Pascal 3.2.2 bunu ifade edemez, bu yüzden Free Pascal dalı deterministik bir seri geri dönüş çalıştırır: sayfa dizinlerini sırayla gezer, her biri için RenderLoadedPageToBitmap çağırır ve başarıları sayar. API biçimi, dönüş değeri ve çıktı dizisi değişmez; tek bir kod tabanının iki yönde de derlenmesini sağlayan da budur
var
Bitmaps: THPDFBitmapArray;
Info: THPDFParallelRenderPipelineInfo;
Rendered: Integer;
begin
Rendered := Pdf.RenderLoadedPagesParallel([0, 1, 2, 3], 150, 4,
Bitmaps, Info);
// Delphi: Info.WorkerCount bellek bütçesinin izin verdiği kadardır
// Free Pascal: Info.WorkerCount her zaman 1, sayfalar dizin sırasında
if Info.WorkerCount = 1 then
LogSerialFallback(Rendered, Info.RequestedWorkerCount);
Geri dönüş sessiz değildir; tasarım yaparken etrafında dolaşmaya değer kısım da budur. THPDFParallelRenderPipelineInfo kaydını dürüstçe doldurur: istekten gelen PageCount, istediğinizi yansıtan RequestedWorkerCount, 1 olarak ayarlanan WorkerCount ve gerçekte dönenle eşleşen tamamlanan ve teslim edilen sayıları. İlerleme çubuğunu ya da bellek bütçesini boyutlandırmak için zaten Info kaydını inceleyen kod çalışmaya devam eder ve varsayım yerine gerçeği okur. Aktarım hızı planınız paralel işleme hattına ve geri basınç modeline dayanıyorsa o plan bir Delphi planıdır; Free Pascal üzerinde bir sayfayı bitmap olarak işlemenin tek iş parçacıklı maliyetini sayfa sayısıyla çarparak bütçeleyin
Aslında hangi derlemeyi dağıtmalısınız?
Tercihe göre değil yeteneğe göre seçin. İş akışınız belge birleştirme, metin ve vektör çizimi, form doldurma, yükleme ve kaydetme ise Win64 üzerindeki Free Pascal derlemesi bunu kapsar ve bir şeyi açmadan önce sıkıştırma kapalıyken doğrulamalısınız. İşiniz JPEG, JPEG 2000, TIFF ya da JBIG2 görüntüleri, ICC renk dönüşümleri, sıkıştırılmış çıktı ya da çok çekirdeğe dayanan aktarım hızı içeriyorsa şimdilik Delphi ya da C++Builder üzerinde kalın. Sınır bir nesne dosyası ABI katmanı ve eksik bir dil özelliği tarafından çizilir; ikisi de bir destek matrisine gömülü olmak yerine kaynakta görünür ve ikisi de yanlış sonuç yerine adlandırılmış bir hatayla başarısız olur
Free Pascal ve Lazarus paketi, Delphi ve C++Builder birimleriyle aynı dağıtımda gelir; böylece tek bir lisans ikisini de kapsar ve kendinizi bağlamadan önce Lazarus yolunu kendi belgelerinizle test edebilirsiniz. HotPDF Delphi PDF Component ürün sayfası, güncel derleyici destek matrisini ve tam API başvurusunu taşır