Demo koleksiyonu 33 konudan oluşuyor: 33 Delphi projesi, 32 C++Builder projesi ve 33 Lazarus projesi; toplamda 98 yerel proje. Her platform, ana dizininde 24 eksiksiz iş akışı demosunu bulundurur. Dokuz odaklı konu Miscellaneous altında yer alır ve üç platform genelinde 26 yerel proje kapsar; XfaLab yalnızca Delphi ve Lazarus için sunulur
Önce ana dizindeki bir iş akışını açın: özellik turu için PDFViewer, canlı belge üretimi için CreatePDF, anında envanter için ContentExtractionLab, düzenlenebilir formlar için FormFill, doğrulama ve dönüşüm için StandardsLab, otomatik intake içinse IntakeWorkbenchCli. Bu altı giriş noktası hemen çalışan sonuçlar üretir; aşağıdaki odaklı örnekler, tek bir API'yi ayrıntılı incelemeniz gerektiğinde işinize yarar
| Demo | Kullanım amacı | İlgili demolardan farkı |
|---|---|---|
PDFViewer | Genel görüntüleme ve özellik değerlendirme | Ana görüntüleyici navigasyonu, aramayı, küçük resimleri, görüntüleme modlarını, yazdırmayı ve özellik tanıtımını bir araya getirir |
MultiPageViewer | Sürekli sayfalar, yayılımlar ve kapak sayfası düzenleri | Yerleşik görüntüleyici seçim API'lerini kullanan odaklı bir düzen örneği; daha geniş görüntüleyici deneyimi için PDFViewer kullanın |
SplitView | Sayfaları ya da belgeleri ayrı bölmelerde karşılaştırma | Tek görünümde iki sayfalı düzen yerine bağımsız görünüm konumlarını ve komutların aktif bölmeye yönlendirilmesini gösterir |
SearchAndSelect | Sayfalar arası arama sonuçları ve seçim | Bir sonuç listesi ve arama seçenekleri, arama iş akışını görüntüleyici araç çubuğundan daha doğrudan ortaya koyar |
PrintPDF | Önizleme ve sıradan yazdırma işleri | Sayfa aralıkları, ölçekleme, ilerleme ve iptal ana yazdırma iş akışını sağlar |
ContentExtractionLab | Birkaç içerik kategorisini birlikte inceleme | TXT/JSON envanterleri nesneleri tanımlar ve metni önizler; tam metin ya da görüntü dosyası dışa aktarmanın yerine geçmez |
ExtractImages | Gömülü görüntü nesnelerini dışa aktarma | Tüm sayfanın ekran görüntüsü yerine görüntü bitmap'lerini çıkarır; yerleşik örnek belge iki sayfanın her birinde iki gerçek görüntü nesnesi içerir |
TableExtractionLab | Tablo algılama ve CSV/JSON dışa aktarma | Çizgili ve boşluk hizalı tablolar, birleşik hücreler, devam grupları ve güven denetimleri düz metin çıkarmadan bağımsızdır |
Attachment | Gömülü ekleri okuma, ekleme ve dışa aktarma | Ek yükü işlemleri, ContentExtractionLab'deki ad ve boyut listelemesinin ötesine geçer |
BatchExport | Birden çok belgeden sayfa görüntülerini dışa aktarma | Akış halinde çıktı, dosya başına durum ve yalıtılmış hatalar tek bir dönüşüm yerine toplu işlemeyi gösterir |
CreatePDF | Canlı önizlemeyle sayfa içeriği oluşturma | Üç yerel varyant da aranabilir metin, vektör şekilleri, gerçek bir raster görüntü, tablolar ve bir inceleme ek açıklaması oluşturur; seçenekler açık bir kaydetmeden önce önizlemeyi yeniden oluşturur |
ImageToPDF | Girdi görüntü dosyalarından sayfa oluşturma | Görüntü yerleşimi, sığdırma, sıralama ve JPEG işleme bir belge dönüşüm iş akışı sunar |
MergePDF | Birkaç PDF'den sayfaları bir araya getirme | Belge içe aktarımını ve sıralı kompozisyonu gösterir; bölme ise ters iş akışını çözer |
SplitPDF | Seçili sayfa gruplarını ayrı PDF'lere yazma | Çıktı adlandırması ve sayfa grubu doğrulaması, birleştirme ya da sayfa görüntüsü render etmeden farklıdır |
WatermarkStamp | Mevcut sayfalara yinelenen kaplamalar uygulama | Yerleşim ve toplu sayfa damgalama temel üretim API'lerini tamamlar |
FormFill | Etkileşimli AcroForm girişi ve düzleştirme | Alan girişi ve kaydedilen görünümler, XFDF veri alışverişinden ve XFA'ya özgü davranıştan farklıdır |
AccessibilityReader | Etkileşimli okuma ve konuşma | GUI okuyucu, uyumluluk denetimi yerine okuma navigasyonunu ve vurgulamayı gösterir |
AccessibilityWorkbenchCli | Toplu erişilebilirlik incelemesi ve rapor üretimi | Bulgular, özetler ve inceleme geçitleri otomasyona hizmet eder; bulgular, elle yapılan erişilebilirlik incelemesinin yerine geçmez |
StandardsLab | Standartlara özgü doğrulama ve dönüşüm | Etkileşimli lab, yalnızca toplu bir rapor üretmek yerine işlemleri ve seçenekleri ortaya koyar |
PreflightReport | Etkileşimli standart raporları | GUI, elle incelemeyi ve rapor dışa aktarmayı destekler |
PreflightReportCli | Otomatik standart raporları | Toplu girdiler, rapor biçimleri ve çıkış kodu geçitleri PreflightReport'un otomasyon karşılığını sağlar |
IntakeWorkbenchCli | Toplu intake, triyaj ve yönlendirme | Toplu raporlar, hata geçitleri ve yönlendirme kararları onu SecurityAudit GUI'sinin ötesinde bir işleme iş akışı haline getirir |
Bu projeleri Demo\Delphi\Miscellaneous, Demo\CBuilder\Miscellaneous ya da Demo\Lazarus\Miscellaneous dizinlerinden açın. Ana dizin eksiksiz deneyimlere odaklanırken bu projeler, işe yarar API tariflerini ve dar kapsamlı dışa aktarma görevlerini korur. Temel Unicode yazma ve yeniden okuma kontrolleri, belge üretimi ile çıkarma iş akışları tarafından karşılanır; bu kontroller için artık ayrı demo projeleri yok
| Demo | Kullanım amacı | İlgili demolardan farkı |
|---|---|---|
SecurityAudit | Güvenlik duruşunu etkileşimli inceleme | GUI, dosya yönlendirme yerine izinleri, betikleri, imzaları ve güvenlik ayrıntılarını öne çıkarır |
XfdfLab | XFDF verilerini içe ve dışa aktarma | Veri alışverişi ve içe aktarılan PDF'nin açıkça kaydedilmesi kalıcılığı gösterir; yalnızca XFDF dışa aktarmak değiştirilmiş PDF'yi kaydetmez |
AccessibilityLab | Okuyucu API'lerini konsolda gezme | Kompakt, çalıştırılabilir bir tur; okuma birimlerini, sözcük kutularını, yapıyı ve konuşma betiği çıktısını ortaya koyar |
ExtractText | Seçili sayfalardan tam metni dışa aktarma | Metin katmanı çıktısı, sayfa ayırıcıları ve iptal, envanter önizlemelerinden ve tablo algılamasından farklıdır; OCR yapılmaz |
FontProperties | Yazı tipi ve karakter metriklerini inceleme | İlk metin nesnesi için gerçek yazı tipi ve karakter metrikleriyle açılır; belge yüklerini dışa aktarmadan yazı tiplerini karşılaştırmak için başka bir satır seçin |
NavigationLab | Yer imleri, hedefler ve navigasyon eylemleri | Kompakt API turu, PDFViewer'daki görünür navigasyon denetimlerini tamamlar |
PDFtoJpg | Tek bir belgeyi sayfa görüntülerine render etme | Kompakt bir tek belge render örneği; Delphi ayrı sayfa aralıkları sunarken BatchExport çoklu giriş belgelerine odaklanır |
PrintPreferences | N-up sayfaları ve PDF yazarının yazdırma tercihleri | Kopyalar, tek/çift filtreleme ve yazarın sağladığı tercihler öğretim odağıdır; bu, PrintPDF'e yardımcı bir örnektir |
ViewerInteractionLab | Fare, klavye ve koordinat etkileşimlerini teşhis etme | Etkileşim günlüğü ile sayfa/cihaz koordinat dönüşümü onu bir API teşhis aracı yapar |
XfaLab | Statik XFA paketleri ve runtime yetenekleri | Template ve datasets paketlerini sıradan runtime ile açar; etkileşimli XFA render'ı XFA etkin bir runtime gerektirir; Delphi ve Lazarus varyantları mevcuttur |
PDFViewer, paketiyle birlikte gelen PDFiumDemoShowcase.pdf belgesini açar; bu altı sayfalık belgede aranabilir metin, vektör grafikleri, iki gömülü görüntü, bir tablo, dört AcroForm alanı, bölüm yer imleri, bağlantılar, bir inceleme notu ve iki dosya eki bulunur. Deneyim çubuğu Restart showcase, Find live text, 2-page spread, Night reading, Inspect this PDF ve Explore forms eylemlerini sunar; her eylem geçerli belge üzerinde çalışır
CreatePDF iki sayfalık canlı bir rapor önizlemesi açar. Başlığını ve yazarını düzenleyin ya da gerçek sayfa içeriğini yeniden oluşturmak için şekilleri, tabloyu ve filigranı açıp kapatın; Unicode seçeneği üçüncü bir sayfa ekler. Siz kaydedene kadar hiçbir şey yazılmaz ve kaydedilen PDF aranabilir kalır
MultiPageViewer, SearchAndSelect, ContentExtractionLab ve FormFill kendi iş akışları için aynı belgeyi açar; arama sonuçları, bir çıkarma envanteri ve düzenlenebilir alanlar hemen hazırdır. Miscellaneous\NavigationLab ise yer imi ve hedef API turu için kendi yerel kopyasını kullanır
Attachment iki gerçek gömülü dosyayla başlar. PrintPreferences dört sayfayla ve iki kopya, seçili sayfa aralıkları, ölçekleme ile dupleks için yazar tercihleriyle başlar; geçerli yazdırma iş akışı kopyaları ve sayfa aralıklarını uygular, ölçekleme ve dupleks ise incelenip raporlanır. XfaLab statik XFA incelemesi için gerçek template ve datasets paketleriyle başlar; etkileşimli XFA render'ı uygun bir runtime gerektirir ve ayrı bir yetenektir
Her görüntüleme, form, çıkarma ve navigasyon projesi kendi PDFiumDemoShowcase.pdf dosyasını içerir. Proje dizinini kopyalayın ve bu paketlenmiş girdiyi dağıtılan çalıştırılabilir dosyanın yanında tutun; Lazarus derlemeleri bu dosyayı otomatik olarak çalıştırılabilirin yanına yerleştirir. Tur çevrimdışı çalışır; genel görüntüleyiciler ve çıkarma örnekleri, yerel PDF kullanılamadığında üretilen yedek içerik de sağlar
Her yerel demo kendi örnek uygulamasını içerir. AccessibilityLab, AccessibilityWorkbenchCli, IntakeWorkbenchCli ve PreflightReportCli için Delphi ve Lazarus giriş noktaları, derleyiciye özgü başlatma ve JPEG yazımı dahil olmak üzere tam iş akışını proje dizininde barındırır. Attachment, yazdırma tercihi ve XFA örnekleri de özelliklerine özgü girdilerini yerel olarak üretir. Kopyalanan projenin dışında yalnızca kitaplık, eşleşen yerel runtime ve normal derleyici çerçeve bağımlılıkları gerekir
Gömülü bitmap'lere ihtiyacınız varsa görüntü nesnesi çıkarmayı, görünür sayfaya ihtiyacınız varsa sayfa render etmeyi, PDF'nin zaten bir metin katmanı varsa metin çıkarmayı seçin. Bu kategorileri listeleyen bir rapor, tam yüklerini dışa aktarmaz. Bu sınırlar, her demoyu bir genel amaçlı görüntüleyiciye ya da workbench'e dönüştürmeden odaklı örnekleri yararlı tutar
Pdf1.FileName := 'C:\MyDocument.pdf';
Pdf1.Active := True;
ShowMessage('Pages: ' + IntToStr(Pdf1.PageCount));
ShowMessage('Title: ' + Pdf1.Title);
ShowMessage('Author: ' + Pdf1.Author);
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
Stream.LoadFromFile('C:\MyDocument.pdf');
Pdf1.LoadDocument(Stream, True);
Pdf1.Active := True;
ShowMessage('PDF loaded from stream');
finally
Stream.Free;
end;
end;
Pdf1.CreateDocument;
Pdf1.Active := True;
Pdf1.AddPage(0, 612, 792);
Pdf1.PageNumber := 1;
Pdf1.AddText('Hello World!', 'Arial', 12, 100, 700, clBlack, $FF, 0.0);
Pdf1.UpdatePage;
Pdf1.SaveAs('C:\NewDocument.pdf');
Pdf1.Active := False;
var
PageText: WString;
RectText: WString;
begin
Pdf1.PageNumber := 1;
PageText := Pdf1.Text;
Memo1.Text := PageText;
RectText := Pdf1.TextInRectangle(100, 100, 500, 200);
ShowMessage('Text in rectangle: ' + RectText);
end;
var
Position: Integer;
begin
Position := Pdf1.FindFirst('Hello', [seCaseSensitive]);
while Position >= 0 do
begin
ShowMessage('Found at character: ' + IntToStr(Position));
Position := Pdf1.FindNext;
end;
end;
Pdf1.PageNumber := 1;
Pdf1.AddText('Document Title', 'Times New Roman', 16, 100, 750, clBlue);
Pdf1.AddText('This is the document content.', 'Arial', 12, 100, 700, clBlack);
Pdf1.UpdatePage;
var
I: Integer;
MetricSize: Single;
FontBytes: TBytes;
begin
Pdf1.PageNumber := 1;
for I := 0 to Pdf1.ObjectCount - 1 do
if Pdf1.ObjectType[I] = otText then
begin
MetricSize := 12.0;
FontBytes := Pdf1.FontData[I];
Memo1.Lines.Add('Object ' + IntToStr(I));
Memo1.Lines.Add('Base name: ' + Pdf1.FontBaseName[I]);
Memo1.Lines.Add('Family: ' + Pdf1.FontFamilyName[I]);
Memo1.Lines.Add('Embedded: ' + BoolToStr(Pdf1.FontIsEmbedded[I], True));
Memo1.Lines.Add('Weight: ' + IntToStr(Pdf1.FontWeight[I]));
Memo1.Lines.Add('Italic angle: ' + IntToStr(Pdf1.FontItalicAngle[I]));
Memo1.Lines.Add('Ascent: ' + FloatToStr(Pdf1.FontAscent[I, MetricSize]));
Memo1.Lines.Add('Descent: ' + FloatToStr(Pdf1.FontDescent[I, MetricSize]));
Memo1.Lines.Add('Font data bytes: ' + IntToStr(Length(FontBytes)));
end;
if Pdf1.CharacterCount > 0 then
begin
Memo1.Lines.Add('First character size: ' + FloatToStr(Pdf1.CharacterFontSize[0]));
Memo1.Lines.Add('First character weight: ' + IntToStr(Pdf1.CharacterFontWeight[0]));
Memo1.Lines.Add('First character angle: ' + FloatToStr(Pdf1.CharacterAngle[0]));
end;
end;
Demo\Delphi\Miscellaneous\FontProperties, Demo\CBuilder\Miscellaneous\FontProperties ve Demo\Lazarus\Miscellaneous\FontProperties projeleri aynı metaveriyi hem TPdf hem de TPdfView aracılığıyla gösterir
Demo\Delphi\ContentExtractionLab, Demo\CBuilder\ContentExtractionLab ve Demo\Lazarus\ContentExtractionLab projeleri içerik çıkarmayı tek bir iş akışına dönüştürür. Bir PDF açar veya oluşturur; kullanıcıların metaveri, sayfa metni, sayfa nesneleri, görüntüler, ekler, bağlantılar, ek açıklamalar, yer imleri ve yazı tipi / karakter metrikleri arasında seçim yapmasına izin verir; ardından bir özet ve ayrıntılı bir TXT veya JSON raporu üretir. Lab ayrıca tüm / hiçbiri kategori seçimini, raporu panoya kopyalamayı ve kullanıcıların üretilen örnek PDF'yi çıkarma raporunun yanında tutabilmesini sağlayan kaynak-PDF kaydetme eylemlerini içerir. ExtractImages ve Attachment yük dışa aktarma iş akışlarını sağlarken Miscellaneous\ExtractText ile Miscellaneous\FontProperties odaklı API örnekleri olarak varlığını sürdürür; ExtractText, Delphi, C++Builder ve Lazarus genelinde sayfa başına metin çıktısı üretmek için sayfa aralığı ve sayfa ayırıcı seçeneklerini desteklerken ContentExtractionLab kapsayıcı envanter örneğidir
Demo\Delphi\TableExtractionLab, Demo\CBuilder\TableExtractionLab ve Demo\Lazarus\TableExtractionLab projeleri tablo algılamayı tek bir iş akışına dönüştürür. Laboratuvar, birleştirilmiş başlık hücreleri olan çizgili bir tablo, çizgi olmadan boşluklarla hizalanmış bir tablo ve bir sayfa sınırında kırılan uzun bir tablo içeren örnek bir belge oluşturur, ardından geçerli sayfa için ExtractTables ya da tüm belge için ExtractDocumentTables çalıştırır ve satırları, sütunları, RowSpan ve ColumnSpan değerlerini, başlık bayraklarını, algılama modunu, güven puanını ve devam gruplarını raporlar. DetectRuledTables, DetectWhitespaceTables, DetectContinuations, DetectFilledRulings ve MinConfidence seçenekleri arayüzde düzenlenebilir ve seçilen tablo TPdfTable.ToCsv ile TPdfTable.ToJson üzerinden dışa aktarılır. Laboratuvar ayrıca bütün bir klasörü toplu işler: Batch folder her PDF için ExtractDocumentTables çalıştırır, belge başına tablo sayılarını raporlar, metin katmanı olmayan taramaları işaretler ve boş belgeleri kompakt sütun ön ayarıyla yeniden dener; Export all CSV algılanan her tabloyu kaynak dosyaların yanına yazar. Her belge kendi TPdf örneğinde açılır, böylece okunamayan tek bir dosya grubun kalanını etkileyemez
var
I: Integer;
FieldInfo: TPdfFormFieldInfo;
begin
Pdf1.FormField[0] := 'John';
for I := 0 to Pdf1.FormFieldCount - 1 do
begin
FieldInfo := Pdf1.FormFieldInfo[I];
ShowMessage(FieldInfo.Name + ': ' + Pdf1.FormField[I]);
end;
end;
// Without flattening, FormField[i] := value writes only the /V entry —
// the visible appearance comes from the /AP stream and may not refresh
// GenerateFormAppearances regenerates /AP for every widget, then
// FlattenAllPages bakes every page's annotations and widgets into
// permanent, non-editable content
Pdf1.FileName := 'C:\Application.pdf';
Pdf1.Active := True;
Pdf1.FormField[0] := 'John Smith';
Pdf1.FormField[1] := '[email protected]';
Pdf1.GenerateFormAppearances;
if Pdf1.FlattenAllPages then
Pdf1.SaveAs('C:\Application.flat.pdf');
Pdf1.Active := False;
var
I: Integer;
Bitmap: TBitmap;
begin
for I := 0 to Pdf1.BitmapCount - 1 do
begin
Bitmap := Pdf1.Bitmap[I];
try
Bitmap.SaveToFile('C:\ExtractedImage' + IntToStr(I) + '.bmp');
finally
Bitmap.Free;
end;
end;
end;
var
JpegStream: TFileStream;
begin
JpegStream := TFileStream.Create('C:\MyImage.jpg', fmOpenRead or fmShareDenyWrite);
try
Pdf1.AddJpegImage(JpegStream, 100, 500, 200, 150);
finally
JpegStream.Free;
end;
Pdf1.AddPicture(Image1.Picture, 100, 300, 150, 100);
Pdf1.UpdatePage;
end;
var
I: Integer;
Annotation: TPdfAnnotation;
begin
for I := 0 to Pdf1.AnnotationCount - 1 do
begin
Annotation := Pdf1.Annotation[I];
ShowMessage('Annotation ' + IntToStr(I) + ': ' + Annotation.ContentsText);
end;
end;
Pdf1.CreatePath(100, 100, 200, 150, fmAlternate, clYellow, $FF, True, clBlack, $FF, 2.0);
Pdf1.AddPath;
Pdf1.CreatePath(100, 100, fmNone, clBlack, $FF, True, clRed, $FF, 3.0);
Pdf1.LineTo(200, 100);
Pdf1.LineTo(150, 200);
Pdf1.ClosePath;
Pdf1.AddPath;
Pdf1.UpdatePage;
var
I: Integer;
Bookmarks: TBookmarks;
begin
Bookmarks := Pdf1.Bookmarks;
for I := 0 to Length(Bookmarks) - 1 do
ShowMessage(Bookmarks[I].Title + ' -> Page ' + IntToStr(Bookmarks[I].PageNumber));
end;
var
I: Integer;
Destination: TDestination;
begin
for I := 0 to Pdf1.DestinationCount - 1 do
begin
Destination := Pdf1.Destination[I];
if Destination.Name = 'Chapter1' then
begin
Pdf1.PageNumber := Destination.PageNumber;
Break;
end;
end;
end;
var
I: Integer;
AttachmentData: TBytes;
AttachmentName: WString;
FileStream: TFileStream;
begin
for I := 0 to Pdf1.AttachmentCount - 1 do
begin
AttachmentName := Pdf1.AttachmentName[I];
AttachmentData := Pdf1.Attachment[I];
FileStream := TFileStream.Create('C:\Extracted_' + string(AttachmentName), fmCreate);
try
if Length(AttachmentData) > 0 then
FileStream.WriteBuffer(AttachmentData[0], Length(AttachmentData));
finally
FileStream.Free;
end;
end;
if Pdf1.CreateAttachment('MyFile.txt') then
Pdf1.Attachment[Pdf1.AttachmentCount - 1] := TFile.ReadAllBytes('C:\MyFile.txt');
end;
Pdf1.AddPage(Pdf1.PageCount + 1, 612, 792);
Pdf1.AddPage(Pdf1.PageCount + 1, 595, 842);
Pdf1.AddPage(Pdf1.PageCount + 1, 400, 600);
var
SourcePdf: TPdf;
begin
SourcePdf := TPdf.Create(nil);
try
SourcePdf.FileName := 'C:\SourceDocument.pdf';
SourcePdf.Active := True;
Pdf1.ImportPages(SourcePdf, '1', Pdf1.PageCount + 1);
finally
SourcePdf.Free;
end;
end;
if Pdf1.PageCount > 1 then
Pdf1.DeletePage(Pdf1.PageCount);
// Create a compressed PDF document
Pdf1.CreateDocument;
Pdf1.Compressed := True; // ensure all streams are FlateDecode compressed (default)
Pdf1.Active := True;
Pdf1.AddPage(0, 595, 842); // A4 size
Pdf1.AddText('Hello World!', 'Arial', 24, 100, 700, clBlack, $FF, 0.0);
Pdf1.SaveAs('C:\Compressed.pdf');
Pdf1.Active := False;
// Save with options
Pdf1.SaveAs('C:\Output.pdf', saIncremental); // incremental save
Pdf1.SaveAs('C:\NoSecurity.pdf', saRemoveSecurity); // remove security
// Save to a specific PDF version target. The PDF version validator rejects
// any feature introduced after the chosen target (JBIG2Decode, MarkInfo,
// AES encryption, Polygon / Caret / Watermark / Redact annotations, ...)
if not Pdf1.SaveAs('C:\Legacy15.pdf', saNone, pv15) then
ShowMessage('Save rejected: document contains features newer than PDF 1.5');
// SaveAsPdfA post-processes the base save with an incremental update that
// injects an XMP metadata stream, an sRGB ICC OutputIntent, and an updated
// document catalog so the result is PDF/A-1b conformant. The bundled
// sRGB IEC61966-2.1 profile is used automatically when no custom profile
// is supplied
Pdf1.FileName := 'C:\Report.pdf';
Pdf1.Active := True;
if Pdf1.SaveAsPdfA('C:\Report.pdfa.pdf', pac1b) then
ShowMessage('Saved PDF/A-1b archive');
// PDF/A with a custom ICC profile (CMYK printing pipelines for example)
var
Opts: TPdfASaveOptions;
begin
Opts := Default(TPdfASaveOptions);
Opts.Conformance := pac1b;
Opts.IccProfileData := TFile.ReadAllBytes('C:\Profiles\Coated_GRACoL_2006.icc');
Pdf1.SaveAsPdfA('C:\Report.cmyk.pdfa.pdf', Opts);
end;
// In-memory PDF/A output
var
Stream: TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
Opts := Default(TPdfASaveOptions);
Opts.Conformance := pac1b;
if Pdf1.SaveAsPdfAToStream(Stream, Opts) then
UploadToArchive(Stream);
finally
Stream.Free;
end;
end;
var
Validation: TPdfAValidationResult;
Issue: TPdfAValidationIssue;
begin
Pdf1.FileName := 'C:\Incoming\report.pdf';
Pdf1.Active := True;
// Cheap header-style probe — reads the conformance without iterating
// the full validator. Result: pacNone, pac1a, pac1b, pac2b, pac3b, or
// pacUnknown
case Pdf1.PdfAConformance of
pac1b: Status.Caption := 'PDF/A-1b';
pac2b: Status.Caption := 'PDF/A-2b';
pacNone: Status.Caption := 'Not PDF/A';
else
Status.Caption := 'Unknown conformance';
end;
// Full validator with per-issue diagnostics
Validation := Pdf1.ValidatePdfA;
Memo1.Lines.Add('Conformance: ' + GetEnumName(TypeInfo(TPdfAConformance),
Ord(Validation.Conformance)));
for Issue in Validation.Issues do
Memo1.Lines.Add('- ' + Issue.Description);
end;
Demo\Delphi\StandardsLab, Demo\CBuilder\StandardsLab ve Demo\Lazarus\StandardsLab projeleri bir PDF yükler veya oluşturur, ValidatePdfA, ValidatePdfUa, ValidatePdfE, ValidatePdfX, ValidatePdfR ve ValidatePdfVT çalıştırır, ardından algılanan her uyumluluk seviyesini ve sorun sayısını tek bir ızgarada gösterir. Kaydet düğmeleri SaveAsPdfA, SaveAsPdfUa, SaveAsPdfE, SaveAsPdfX, SaveAsPdfR ve SaveAsPdfVT çağırır; böylece işaretleyici çıktı iş akışı özel bir koşum yazmadan görünür olur
FPdfPreflightReport birimi; ValidatePdfA, ValidatePdfUa, ValidatePdfE, ValidatePdfX, ValidatePdfR ve ValidatePdfVT yöntemlerini Info / Warning / Error önem düzeyi, durum ve sorun toplama, arama, sorgulama, filtreleme ve kararlı SHA-256 parmak izleriyle tek bir sorgulanabilir rapor nesnesinde toplar. Raporlar metin, HTML, Markdown, JSON, CSV, SARIF 2.1.0, JUnit XML, NDJSON veya native XML olarak üretilebilir. Demo\Delphi\PreflightReport, Demo\Lazarus\PreflightReport ve Demo\CBuilder\PreflightReport etkileşimli seçim ve önizleme iş akışları sunarken Demo\Delphi\PreflightReportCli; betiklenebilir giriş / çıkış argümanları, standart filtreleme, isteğe bağlı rapor eki gömme, CI çıkış kodu kısıtlaması, toplu liste ve dizin işleme, çarpışmasız yönlendirme, toplu özetler ve CSV manifestoları ekler. Üretilen rapor, yerleşik doğrulayıcıların işaretleyici düzeyindeki ve seçilmiş dosya düzeyindeki kontrolleri kapsadığını belirtir; böylece tam içerik düzeyi preflight yine de özel bir doğrulama motoruna devredilebilir
// LoadCustomDocument lets PDFium pull blocks from any seekable TStream on
// demand. The stream is NOT copied into memory, so multi-GB PDFs, remote
// HTTP body streams, and database-backed sources are all viable without
// an up-front buffer
var
FileStream: TFileStream;
begin
// Read-from-file streaming (no in-memory copy)
FileStream := TFileStream.Create('C:\Huge.pdf',
fmOpenRead or fmShareDenyWrite);
Pdf1.LoadCustomDocument(FileStream, True{AOwnsStream});
// ^^ ownership transferred — Pdf1 frees FileStream on UnloadDocument
Pdf1.Active := True;
ShowMessage('Pages: ' + IntToStr(Pdf1.PageCount));
end;
// Externally-owned stream (caller frees it after UnloadDocument)
var
Stream: TFileStream;
begin
Stream := TFileStream.Create('C:\Live.pdf',
fmOpenRead or fmShareDenyNone);
try
Pdf1.LoadCustomDocument(Stream, False);
Pdf1.Active := True;
DoWork;
Pdf1.Active := False;
finally
Stream.Free;
end;
end;
// FPdfAsync exposes IPdfCancellationToken /
// IPdfCancellationTokenSource for cancel-from-UI semantics that work
// across the long-running export and render paths
uses FPdfAsync;
var
CancelSource: IPdfCancellationTokenSource;
CancelToken: IPdfCancellationToken;
begin
CancelSource := PdfCancellationTokenSource;
CancelToken := CancelSource.Token;
// user clicks Cancel
CancelSource.Cancel;
// The worker periodically checks CancelToken.IsCancelled, or the render
// path polls it through PDFium's IFSDK_PAUSE callback
if CancelToken.IsCancelled then
Memo1.Lines.Add('Cancelled by user');
end;
// RenderPageProgressive lets a long high-DPI render abort mid-page when
// the user clicks Cancel, instead of blocking the caller until done
var
Status: TPdfProgressiveStatus;
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32bit;
Bitmap.SetSize(2480, 3508); // A4 @ 300 DPI
Status := Pdf1.RenderPageProgressive(Bitmap, 0, 0, Bitmap.Width,
Bitmap.Height, CancelToken, ro0, [reAnnotations], clWhite);
case Status of
prsDone: SaveBitmap(Bitmap);
prsCancelled: Memo1.Lines.Add('Render cancelled — partial result available');
prsFailed: Memo1.Lines.Add('PDFium reported FPDF_RENDER_FAILED');
end;
finally
Bitmap.Free;
end;
end;
// TPdfFuture<T> spins up a worker on a background thread and posts a
// TPdfFutureResult<T> envelope back to the main thread
//
// Important: TPdf serializes render calls per instance, but the worker still
// owns dispatch and document lifetime. Do not mutate a TPdf while a render is
// in flight; batch export usually keeps one TPdf per file
type
TRenderResult = record
Bitmap : TBitmap;
PageNo : Integer;
end;
var
Future: TPdfFuture<TRenderResult>;
begin
Future := TPdfFuture<TRenderResult>.Create(
function (const ACancelToken: IPdfCancellationToken): TRenderResult
var
LocalPdf: TPdf;
begin
LocalPdf := TPdf.Create(nil);
try
LocalPdf.FileName := 'C:\Huge.pdf';
LocalPdf.Active := True;
LocalPdf.PageNumber := 1;
Result.Bitmap := LocalPdf.RenderPage(0, 0, 2480, 3508);
Result.PageNo := 1;
finally
LocalPdf.Free;
end;
end,
procedure (const AResult: TPdfFutureResult<TRenderResult>)
begin
case AResult.State of
pfsSuccess: PaintBitmapToView(AResult.Value.Bitmap);
pfsCancelled: Log.Add('Cancelled');
pfsFailed: Log.Add('Worker failed: ' + AResult.ErrorMessage);
end;
end);
end;
// FPdfMatrix wraps PDFium's FS_MATRIX so callers can build a transform
// declaratively and hand it to FPDFPageObj_SetMatrix
uses FPdfMatrix, FPdfView;
var
M: TPdfMatrix;
RawMatrix: FS_MATRIX;
PageObj: FPDF_PAGEOBJECT;
begin
M := TPdfMatrix.Create;
try
M.Translate(72, 200); // move 1in right, ~2.8in up
M.Scale(0.5, 0.5); // half-size stamp
M.Rotate(15); // 15-degree CCW rotation
// M.HorizontalFlip;
// M.VerticalFlip;
// M.CentralFlip;
// M.Skew(10, 5);
// M.Multiply(Other); // post-multiply with another matrix
// Apply to any PDFium page object (text / path / image / form XObject)
RawMatrix := M.Handle;
FPDFPageObj_SetMatrix(PageObj, RawMatrix);
finally
M.Free;
end;
end;
// ImportPagesByIndex copies an explicit zero-based index array from a
// source PDF into this document. InsertAt = 0 inserts before page 1;
// PageCount appends
var
Source: TPdf;
begin
Source := TPdf.Create(nil);
try
Source.FileName := 'C:\Report.pdf';
Source.Active := True;
// Import pages 0, 2, 4 (one-based: pages 1, 3, 5) from Source
// and append them at the end of Pdf1
Pdf1.ImportPagesByIndex(Source, [0, 2, 4], Pdf1.PageCount);
// Empty array imports every source page
// Pdf1.ImportPagesByIndex(Source, [], 0);
finally
Source.Free;
end;
end;
// ImportNPagesToOne returns a brand-new TPdf whose pages are NumX*NumY
// composites of THIS document. OutputWidth/Height are PDF user units
// (1 unit = 1/72 in)
var
Composite: TPdf;
begin
Pdf1.FileName := 'C:\Slides.pdf';
Pdf1.Active := True;
// 4-up A4 landscape: 842 x 595 pt, 2 columns x 2 rows
Composite := Pdf1.ImportNPagesToOne(842, 595, 2, 2);
try
if Composite <> nil then
Composite.SaveAs('C:\Slides_4up.pdf');
finally
Composite.Free;
end;
end;
// MovePages takes the zero-based indices of the pages to move plus the
// destination index for the first moved page after the move completes
// Other pages shift around the moved block so the document length stays
// the same
//
// Example: in a 5-page document with pages numbered [0,1,2,3,4],
// MovePages([2, 3], 0) reorders to [2, 3, 0, 1, 4]
if not Pdf1.MovePages([2, 3], 0) then
ShowMessage('Invalid indices passed to MovePages');
// CreateXObjectFromPage manufactures a reusable Form XObject handle from
// any page of any other TPdf. Stamp that handle onto as many pages of
// THIS document as you want — each stamp is a single PDFium page object
// that can be positioned, scaled, and rotated through the matrix API
uses FPdfMatrix, FPdfView;
var
WatermarkSource: TPdf;
XObj: TPdfXObject;
PageObj: FPDF_PAGEOBJECT;
M: TPdfMatrix;
RawMatrix: FS_MATRIX;
I: Integer;
begin
WatermarkSource := TPdf.Create(nil);
try
WatermarkSource.FileName := 'C:\Watermarks\Confidential.pdf';
WatermarkSource.Active := True;
// Wrap page 0 of WatermarkSource as a reusable XObject
XObj := Pdf1.CreateXObjectFromPage(WatermarkSource, 0);
try
for I := 1 to Pdf1.PageCount do
begin
Pdf1.PageNumber := I;
PageObj := Pdf1.InsertFormObjectFromXObject(XObj);
if PageObj = nil then Continue;
// Centre the watermark on the page
M := TPdfMatrix.Create;
try
M.Scale(0.5, 0.5);
M.Translate(0.25 * Pdf1.PageWidth, 0.5 * Pdf1.PageHeight);
RawMatrix := M.Handle;
FPDFPageObj_SetMatrix(PageObj, RawMatrix);
finally
M.Free;
end;
Pdf1.UpdatePage;
end;
finally
XObj.Free; // closes the FPDF_XOBJECT handle
end;
Pdf1.SaveAs('C:\Watermarked.pdf');
finally
WatermarkSource.Free;
end;
end;
Demo\Delphi\WatermarkStamp, Demo\Lazarus\WatermarkStamp ve Demo\CBuilder\WatermarkStamp projeleri bu deseni çalışır bir iş akışına dönüştürür: bir hedef PDF ve yeniden kullanılabilir bir damga PDF oluşturur, damga sayfasını CreateXObjectFromPage ile sarmalar, aynı Form XObject'i her hedef sayfaya ekler, ortalanmış filigranlar ve sağ üst damgaları için TPdfMatrix dönüşümleri uygular ve sonucu kaydetmeden önce isteğe bağlı sayfa numarası etiketleri ekler
// AddImage(FileName) accepts any format registered with the VCL or LCL
// graphics units (BMP, PNG via PngImage, JPG, ...)
Pdf1.AddImage('C:\Photo.png', 100, 500, 200, 150);
// AddImage(TBitmap) skips the TPicture intermediary, ideal when the
// bitmap already comes from rendering or batch generation work
var
Bitmap: TBitmap;
begin
Bitmap := Pdf1.RenderPage(0, 0, 595, 842);
try
Pdf1.PageNumber := 2;
Pdf1.AddImage(Bitmap, 50, 50, 250, 350);
Pdf1.UpdatePage;
finally
Bitmap.Free;
end;
end;
Demo\Delphi\ImageToPDF, Demo\CBuilder\ImageToPDF ve Demo\Lazarus\ImageToPDF projeleri bunu eksiksiz bir toplu iş akışına dönüştürür: birden çok görüntü dosyası seçin, seçili öğeyi önizleyin, görüntü başına bir PDF sayfası oluşturun, her görüntüyü A4 dikey veya yatay bir sayfaya ölçeklendirin, sonucu kaydedin ve üretilen PDF'yi açın
var
MatchCount: Integer;
begin
// Paint a clYellow mask over every match on the view's current page
// Switching to a different page clears the highlight automatically
PdfView1.HighlightColor := clYellow;
MatchCount := PdfView1.HighlightSearchText('invoice', False{Case}, True{Word});
Status.Caption := Format('%d match(es) on this page', [MatchCount]);
// Programmatically remove the overlay before the page changes
PdfView1.ClearHighlight;
end;
// FitMode keeps long documents framed during Resize or page changes
// Setting Zoom directly cancels FitMode (it reverts to pfmNone)
PdfView1.FitMode := pfmFitPage; // whole page in viewport
// PdfView1.FitMode := pfmFitWidth; // page width matches viewport width
// PdfView1.FitMode := pfmActualSize; // 100%
// PageColor decouples the rendered PDF page from the host control's Color
// — typical dark-mode viewer setup keeps the scroll area dark while the
// PDF page stays paper-white
PdfView1.Color := clBlack; // scroll area
PdfView1.PageColor := clWhite; // PDF page background
// Optional drop shadow and page border to lift the page off a dark bg
PdfView1.PageShadowSize := 6;
PdfView1.PageShadowColor := $00404040;
PdfView1.PageBorderColor := clGray;
Demo\Delphi\Miscellaneous\ViewerInteractionLab, Demo\CBuilder\Miscellaneous\ViewerInteractionLab ve Demo\Lazarus\Miscellaneous\ViewerInteractionLab projeleri modern TPdfView etkileşim yüzeyini tek bir kompakt formda tutar: bir örnek PDF açın veya oluşturun, DisplayMode değiştirin, FitMode uygulayın, PageColor değiştirin, sayfaları döndürün, geçerli sayfa arama isabetlerini HighlightSearchText ile vurgulayın, kullanıcı metin seçimini açıp kapatın, SelectedText inceleyin, SelectAll, CopySelectionToClipboard ve ClearSelection çağırın ve fare sayfa üzerinde gezinirken durum çubuğunda DeviceToPage koordinatlarının güncellenmesini izleyin
Demo\Delphi\SearchAndSelect, Demo\CBuilder\SearchAndSelect ve Demo\Lazarus\SearchAndSelect projeleri arama ve seçim görüntüleyici iş akışını bağımsız örneklere dönüştürür. Bir PDF açarlar veya oluştururlar; sayfa numarası, karakter indeksi ve önizleme metniyle tüm sayfa arama sonuçlarını listelerler; Önceki / Sonraki navigasyonu ve çift tıklamayla sonuca atlamayı desteklerler; geçerli sayfa eşleşmelerini HighlightSearchText ile vurgularlar; büyük/küçük harf ve tam sözcük seçeneklerini sunarlar; AllowUserTextSelection'ı açıp kapatırlar; SelectedText önizlerler; SelectAll, CopySelectionToClipboard ve ClearSelection düğmelerden yönetilir ve kullanıcılar tek ile yayılım görüntüleme modları arasında geçiş yapabilir
Demo\Delphi\Miscellaneous\PrintPreferences, Demo\CBuilder\Miscellaneous\PrintPreferences ve Demo\Lazarus\Miscellaneous\PrintPreferences projeleri yazdırmadan önce yazarın yazdırma tercihlerini okur. PrintCopies, PrintPageRanges, PrintScaling ve PrintPaperHandling gösterirler; yazarın sağladığı kopya ve aralıkları yazdırma girişlerine kopyalayabilirler ve SetPdfPrintPaperHandlingDevMode'un PDF dupleks amacını bir Windows DEVMODE'a nasıl eşlediğini gösterirler
Demo\Delphi\PrintPDF, Demo\CBuilder\PrintPDF ve Demo\Lazarus\PrintPDF projeleri standart yazdırma iş akışını gösterir: bir PDF açın, sayfaları önizleyin, platform yazdırma penceresinde sayfa aralıklarını ve kopyaları seçin, harmanlama moduna uyun, her sayfayı TPdf.RenderPage ile render edin ve iptal desteğiyle yazdırma ilerlemesini sunun. Delphi örneği ayrıca hızlı yükleme için bırakılan PDF dosyalarını kabul eder
Demo\Delphi\MultiPageViewer, Demo\CBuilder\MultiPageViewer ve Demo\Lazarus\MultiPageViewer projeleri düzenli sayfa navigasyonu ve yakınlaştırma iş akışlarıyla sürekli, yayılım ve kapak duyarlı görüntülemeyi çalıştırır. Çok büyük PDF'lerde ilk sayfaya açılma hızını ve render duyarlılığını test etmek için de yararlıdırlar: büyük dosya testlerinde, Acrobat veya Foxit'in ilk görünüm öncesinde 20-30 saniye harcayabildiği 2.x GB belgeler PDFium Delphi Component görüntüleyici yoluyla neredeyse anında kullanılabilir hale gelebilir
Demo\Delphi\SplitView, Demo\CBuilder\SplitView ve Demo\Lazarus\SplitView projeleri yan yana PDF incelemesini gösterir. C++Builder ve Lazarus örnekleri iki veya üç bölmeli karşılaştırmaya, aktif görünüm seçimine, isteğe bağlı senkronize navigasyon komutlarına, paylaşılan yakınlaştırma ön ayarlarına ve seçili görünüm ya da tüm yüklenmiş görünümler için döndürmeye odaklanır. İlk kullanılabilir görünümü ve sonraki sayfa render'ını duyarlı tutarken büyük belgeleri karşılaştırmak için bu örnekleri kullanın; Acrobat veya Foxit'in açması 20-30 saniye sürebilen aynı 2.x GB PDF dosyaları PDFium Delphi Component görüntüleyici yolunda neredeyse anında kullanılabilir hale gelebilir
Demo\Delphi\SecurityAudit, Demo\CBuilder\SecurityAudit ve Demo\Lazarus\SecurityAudit projeleri bir PDF'yi salt okunur açar ve izin durumunu, gömülü ekleri, belge JavaScript eylemlerini, URI ve Launch bağlantı ek açıklamalarını, web bağlantılarını, imza özetlerini, XFA durumunu, V8 yardımcı kullanılabilirliğini ve desteklenmeyen özellik geri çağrılarını listeler. Aynı özet ve bulgu satırları bir TXT denetim raporu olarak kaydedilebilir veya kopyalanabilir ya da yapılandırılmış JSON olarak kaydedilebilir. Bunlar kötü amaçlı yazılım algılaması değil, host uygulama risk panelleri olarak tasarlanmıştır
// LinkOptions controls automatic handling of the four PDF link action
// types. Defaults enable goto and URI only; launch (run a program) and
// embedded GotoR (jump to another file) stay OFF so a stray click cannot
// run arbitrary code
PdfView1.LinkOptions :=
[loAutoGoto, loAutoOpenURI]; // safe defaults
// OnAnnotationLinkClick fires for in-document destinations (page jumps,
// named destinations, action chains). Mark Handled = True to prevent the
// view from auto-following the link
procedure TForm1.PdfView1AnnotationLinkClick(Sender: TObject;
LinkIndex: Integer; const Action: TPdfAction;
var Handled: Boolean);
begin
if Action.Kind = paUri then
begin
if MessageDlg('Open ' + Action.Uri + '?', mtConfirmation, [mbYes, mbNo], 0)
<> mrYes then
Handled := True; // suppress auto-handling
end;
end;
// OnWebLinkClick fires for URI strings discovered by PDFium's web-link
// scanner (auto-detected URLs in the text stream, even without an
// /A <</S/URI...>> annotation)
procedure TForm1.PdfView1WebLinkClick(Sender: TObject;
WebLinkIndex: Integer; const Url: WString;
var Handled: Boolean);
begin
Log.Add('Web link clicked: ' + string(Url));
end;
// On the focused AcroForm widget, six new methods drive PDFium's form
// edit history. All six short-circuit safely if no widget is focused or
// the document carries no AcroForm
procedure TForm1.btnSelectAllClick(Sender: TObject);
begin
PdfView1.SelectAllFormText;
EditMenuCopy.Caption := 'Copy: ' + string(PdfView1.GetSelectedFormText);
end;
procedure TForm1.btnUndoClick(Sender: TObject);
begin
btnUndo.Enabled := PdfView1.FormCanUndo;
btnRedo.Enabled := PdfView1.FormCanRedo;
if PdfView1.FormCanUndo then
PdfView1.FormUndo;
end;
procedure TForm1.btnRedoClick(Sender: TObject);
begin
if PdfView1.FormCanRedo then
PdfView1.FormRedo;
end;
// All three default to True so existing apps upgrade with no behaviour
// change. Flip them False for kiosks, preview panes, or read-only
// embeddings without subclassing TPdfView
PdfView1.AllowUserPageChange := False; // PgUp/PgDn/Ctrl+Home/End
PdfView1.ChangePageOnMouseScrolling := False; // wheel up/down jumps
PdfView1.AllowUserTextSelection := False; // mouse/keyboard text selection
// Ctrl+wheel is reserved for zoom and is skipped by the navigation
// handler regardless of ChangePageOnMouseScrolling.
// TPdfThumbnailView (unit FPdfThumbnail) renders one page thumbnail per
// row in a scrollable side panel
uses FPdfThumbnail;
procedure TForm1.FormCreate(Sender: TObject);
begin
ThumbView.Pdf := Pdf1;
ThumbView.ThumbnailWidth := 120;
ThumbView.ThumbnailHeight := 160;
ThumbView.SelectionColor := $00CFA85F; // warm highlight
ThumbView.OnPageClick := ThumbViewPageClick;
end;
procedure TForm1.ThumbViewPageClick(Sender: TObject; PageIndex: Integer);
begin
PdfView1.PageNumber := PageIndex + 1; // PageIndex is zero-based
end;
procedure TForm1.PdfView1PageNumberChanged(Sender: TObject);
begin
ThumbView.CurrentPageIndex := PdfView1.PageNumber - 1;
end;
// Pattern used by Demo\Delphi\BatchExport, Demo\CBuilder\BatchExport,
// and Demo\Lazarus\BatchExport. One TPdf per file, IPdfCancellationToken
// for cancel-from-UI, TPdfStreamAdapter for buffered file load
uses FPdfAsync;
procedure ExportBatch(const Files: TArray<string>;
const OutDir: string; DPI: Integer; Quality: Integer;
const ACancelToken: IPdfCancellationToken);
var
I, J: Integer;
Job: TPdf;
Bmp: TBitmap;
Jpeg: TJPEGImage;
begin
for I := 0 to High(Files) do
begin
if ACancelToken.IsCancelled then Break;
OverallProgress.Position := I;
Job := TPdf.Create(nil);
try
Job.FileName := Files[I];
Job.Active := True;
PageProgress.Max := Job.PageCount;
for J := 1 to Job.PageCount do
begin
if ACancelToken.IsCancelled then Break;
PageProgress.Position := J;
Job.PageNumber := J;
Bmp := Job.RenderPage(
0, 0,
Round(Job.PageWidth * DPI / 72),
Round(Job.PageHeight * DPI / 72));
try
Jpeg := TJPEGImage.Create;
try
Jpeg.CompressionQuality := Quality;
Jpeg.Assign(Bmp);
Jpeg.SaveToFile(Format('%s\%s.p%.3d.jpg',
[OutDir, ExtractFileName(Files[I]), J]));
finally
Jpeg.Free;
end;
finally
Bmp.Free;
end;
end;
finally
Job.Free;
end;
end;
end;
procedure FitCurrentPage;
begin
PdfView1.Zoom := PdfView1.PageZoom[PdfView1.PageNumber];
end;
procedure InspectViewerPoint(X, Y: Integer);
var
PageNo: Integer;
PageX, PageY: Double;
CharIndex: Integer;
Ch: WString;
begin
PageNo := PdfView1.PageNumber;
if not PdfView1.DeviceToPage(X, Y, PageNo, PageX, PageY) then
Exit;
CharIndex := PdfView1.CharacterIndexAtPos(X, Y, 8, 8);
if CharIndex >= 0 then
begin
Ch := PdfView1.Text(CharIndex, 1);
ShowMessage(Format('Page %d, X %.2f, Y %.2f, character %s',
[PageNo, PageX, PageY, string(Ch)]));
end;
end;
function LoadPdfSafely(const FileName: string): Boolean;
begin
Result := False;
if not FileExists(FileName) then
Exit;
try
Pdf1.FileName := FileName;
Pdf1.Active := True;
Result := Pdf1.Active;
except
Result := False;
end;
end;
function ExtractTextSafely(PageNo: Integer): WString;
begin
Result := '';
if not Pdf1.Active then
Exit;
if (PageNo < 1) or (PageNo > Pdf1.PageCount) then
Exit;
Pdf1.PageNumber := PageNo;
Result := Pdf1.Text;
end;
// IsTagged is a cheap catalog probe — True when /StructTreeRoot exists
// StructureElements materialises the tree into a flat array of
// TPdfStructureElement records with type, title, alternate text, actual
// text, expansion text, language, level, parent index, and child / marked
// content / attribute counts
var
Elements: TPdfStructureElements;
I: Integer;
begin
if not Pdf1.IsTagged then
begin
Log.Add('Document is NOT tagged — accessibility tools may struggle.');
Exit;
end;
if Pdf1.Language = '' then
Log.Add('Tagged PDF without /Lang — fails PDF/UA.');
Elements := Pdf1.StructureElements;
for I := 0 to High(Elements) do
Log.Add(StringOfChar(' ', Elements[I].Level * 2)
+ Elements[I].StructType + ' "' + Elements[I].Title + '"');
end;
// SetPdfPrintMode is a global function that maps to PDFium's
// FPDF_SetPrintMode. Use the matching TPdfPrintMode value for the
// printer driver in use
SetPdfPrintMode(pmEmf); // GDI EMF (default)
// SetPdfPrintMode(pmTextOnly); // text-only rendering
// SetPdfPrintMode(pmPostScript2); // PostScript Level 2
// SetPdfPrintMode(pmPostScript3); // PostScript Level 3
// SetPdfPrintMode(pmPostScript2PassThrough);
// SetPdfPrintMode(pmPostScript3PassThrough);
// SetPdfPrintMode(pmEmfImageMasks); // EMF + image masks
// SetPdfPrintMode(pmPostScript3Type42); // PostScript 3 + Type 42 fonts
// PrintCopies, PrintPageRanges, PrintScaling, and PrintPaperHandling are
// the viewer-preference dictionary entries — they encode what the
// document author wanted PDF readers to default to
var
Ranges: TPrintPageRanges;
Range: TPrintPageRange;
begin
ShowMessage('Suggested copies: ' + IntToStr(Pdf1.PrintCopies));
ShowMessage('Print scaling: ' + GetEnumName(TypeInfo(TPrintScaling),
Ord(Pdf1.PrintScaling)));
Ranges := Pdf1.PrintPageRanges; // one-based ranges
for Range in Ranges do
Log.Add(Format('Pages %d..%d', [Range.First, Range.Last]));
if SetPdfPrintPaperHandlingDevMode(PrinterDevMode, Pdf1.PrintPaperHandling) then
ApplyPrinterDevMode(PrinterDevMode);
end;
// Document-level JavaScript is stored in the /Names /JavaScript name
// tree. JavaScriptAction[i] returns one entry; JavaScriptActions returns
// the full array
var
I: Integer;
Action: TPdfJavaScriptAction;
begin
for I := 0 to Pdf1.JavaScriptActionCount - 1 do
begin
Action := Pdf1.JavaScriptAction[I];
Memo1.Lines.Add('Name: ' + string(Action.Name));
Memo1.Lines.Add('Script: ' + string(Action.Script));
Memo1.Lines.Add('---');
end;
end;
procedure ProcessMultiplePages;
var
I: Integer;
PageText: WString;
begin
for I := 1 to Pdf1.PageCount do
begin
Pdf1.PageNumber := I;
PageText := Pdf1.Text;
ProcessPageText(PageText);
end;
end;
procedure SetOptimalRenderOptions;
begin
PdfView1.Options := [reAnnotations, reLcd];
end;
// Zero-copy render path (default since v1.21.0): RenderPage writes
// directly into the destination TBitmap's DIB buffer when callers pass a
// pre-allocated bitmap, avoiding one width * height * 4 bytes copy
procedure RenderIntoCallerBitmap(Bitmap: TBitmap);
begin
Bitmap.PixelFormat := pf32bit;
Bitmap.SetSize(2480, 3508); // A4 @ 300 DPI
Pdf1.RenderPage(Bitmap, 0, 0, Bitmap.Width, Bitmap.Height);
end;