Migrare da Quick PDF Library e PdfiumViewer a sgcPDF

Foxit ha dismesso Quick PDF Library il 13 dicembre 2021, e il repository di PdfiumViewer è di sola lettura dal 2 agosto 2019. sgcPDF sostituisce entrambi: Pascal puro compilato nel tuo exe Delphi, e C# gestito per WinForms, senza DLL PDF da distribuire. Questo kit mappa le funzioni di Quick PDF Library e le classi di PdfiumViewer su sgcPDF, con codice tratto da due esempi che compilano e superano il proprio autotest.

Applicazioni basate su una libreria PDF che non evolve più

Due casi comuni: un'applicazione Delphi che crea, unisce, compila e renderizza file PDF con Quick PDF Library, e un'applicazione WinForms che mostra file PDF con PdfiumViewer.

Da Quick PDF Library (Delphi)

Quick PDF Library (Debenu Quick PDF Library, poi Foxit Quick PDF Library) viene fornita come DLL, ActiveX o LIB con una chiave di sblocco, e lavora su un unico oggetto in cui sono "selezionati" un documento, una pagina, un font e un'immagine. sgcPDF è un insieme di unit Pascal con un modello a oggetti: TsgcPDFDocument, TsgcPDFPage, TsgcPDFEditor e TsgcPDFAcroForm, da Delphi 7 a Delphi 13.

Da PdfiumViewer (WinForms)

PdfiumViewer racchiude la libreria nativa PDFium in un controllo PdfViewer, un PdfRenderer e un PdfDocument. Mostra, cerca, renderizza e stampa i file PDF. sgcPDF li sostituisce con un unico controllo gestito, TsgcPDFViewerControl, e aggiunge ciò che PdfiumViewer non ha mai avuto: creare file PDF, compilare moduli, aggiungere annotazioni e salvare le modifiche.

Quick PDF Library. L'avviso di Foxit (letto il 20/10/2026) dice in sostanza: "Dal 13 dicembre 2021 Foxit dismetterà i seguenti prodotti", e il primo prodotto dell'elenco è Foxit Quick PDF Library (tutte le piattaforme). I clienti con contratti attivi di manutenzione e supporto sono stati assistiti fino al 13 dicembre 2022: "Dopo tale data il prodotto passerà a fine supporto e non sarete più assistiti." Le alternative indicate da Foxit sono i suoi SDK PDF per Windows, Mac, Linux, Android e iOS, il suo SDK ActiveX e la sua suite di SDK .NET.

PdfiumViewer. Il repository GitHub (letto il 20/10/2026) mostra in sostanza: "Questo repository è stato archiviato dal proprietario il 2 ago 2019. Ora è di sola lettura." Il suo README spiega: "Da molto tempo non riesco a dedicarvi tempo reale", e "Non sono in grado di supportare adeguatamente questo progetto." Dice anche: "Il controllo PdfiumViewer richiede le librerie native PDFium. Non sono incluse nel pacchetto NuGet di PdfiumViewer." Il pacchetto NuGet è stato aggiornato l'ultima volta l'11/6/2017 (versione 2.13.0) e ha come destinazione net20.

Una sola libreria PDF, codice sorgente incluso

sgcPDF è il prodotto PDF di sgcUI. Crea, modifica, compila, firma, cifra, renderizza e mostra file PDF in Delphi e in .NET.

Nessuna DLL PDF da distribuire

In Delphi le unit di sgcPDF vengono compilate nell'exe: nessuna DLL, ActiveX o LIB da distribuire e registrare, e nessuna chiamata a una chiave di sblocco. In .NET sgcPDF è C# gestito, quindi non c'è pdfium.dll né un pacchetto nativo x86 o x64 da scegliere: l'esempio gira come AnyCPU.

Un modello a oggetti

Ogni chiamata riceve l'oggetto pagina o l'indice, quindi lo stato "selezionato" di Quick PDF Library scompare. L'imposizione usa XObject di modulo vettoriali (AddPageAsForm, DrawForm, DrawFormInRect), i moduli usano AcroForm, e la cifratura arriva fino ad AES-256 (emAES_256).

Un visualizzatore che modifica

TsgcPDFViewerControl adatta la vista alla larghezza, alla pagina o all'altezza, ruota la vista, cerca e stampa con una finestra di dialogo, e in .NET fornisce un PrintDocument come PdfiumViewer. Compila anche i campi dei moduli (FormFilling), aggiunge annotazioni con il mouse (AnnotationTool) e seleziona il testo. Viste laterali: TsgcPDFThumbnailView, TsgcPDFOutlineView, TsgcPDFCommentsView.

sgcPDF si vende da solo, da €249 per un singolo sviluppatore in Delphi e C++ Builder e da €249 per .NET, con codice sorgente completo e 1 anno di aggiornamenti, ed è parte di sgcUI Enterprise e del bundle All-Access. I pacchetti .NET sono disponibili anche come pacchetti Community gratuiti su NuGet, esegece.sgcPDF.Community e esegece.sgcPDF.WinForms.Community, con le stesse funzioni. Vedi la pagina del prodotto sgcPDF.

Le funzioni di Quick PDF Library in sgcPDF

Le unit sono sgcPDF_Types, sgcPDF_Fonts e sgcPDF_Document, più sgcPDF_Editor, sgcPDF_Encryption, sgcPDF_Renderer_GDI e sgcPDF_Export quando servono. Gli indici di pagina di sgcPDF partono da 0.

Quick PDF Library sgcPDF
UnlockKeyniente da chiamare nel codice
NewDocumentTsgcPDFDocument.Create, poi AddPage (un nuovo documento non ha pagine finché non ne aggiungi una)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
LoadFromFile con una passwordTsgcPDFDocument.SetPassword(APassword) prima di LoadFromFile
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount; solo per un file, sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (base 0, proprietà predefinita), GetPage(AIndex)
SetInformationTsgcPDFDocument.Info.Title, .Author, .Subject, .Keywords, .Creator, .Producer
AddStandardFont + SelectFont + SetTextSize + DrawTextTsgcPDFPage.DrawText(AText, X, Y, AFont, AFontSize) con un TsgcPDFStandardFont (sfHelvetica, sfTimesRoman, sfCourier e le loro varianti grassetto e corsivo)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (componenti da 0 a 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (oppure AddTrueTypeFontFromFile), poi TsgcPDFPage.DrawTextTT
DrawLine, DrawBoxTsgcPDFPage.DrawLine(X1, Y1, X2, Y2, ALineWidth), DrawRectangle(X, Y, W, H, ALineWidth), DrawRectangleFill
AddImageFromFile + SelectImage + DrawImageTsgcPDFDocument.AddImage(AFileName): Integer + TsgcPDFPage.DrawImageFromIndex(AIndex, X, Y, W, H), oppure DrawImageFile(AFileName, X, Y, W, H)
GetPageTextTsgcPDFDocument.ExtractTextW(APageIndex), ExtractText, FindText; TsgcPDFEditor.ExtractAllText, SearchText
AddToFileList + MergeFileListsgcPDFMergeFiles([...], AOutputFile)
MergeDocumentTsgcPDFDocument.AppendDocument(ADoc), TsgcPDFEditor.MergeFrom(AFileName)
ExtractPageRanges, ExtractFilePagessgcPDFExtractPages(AInputFile, AOutputFile, ARange) (stringa di intervallo in base 1 come '1,3,5-9'), TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (filigrana)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
DrawText su ogni pagina (timbro, intestazione, piè di pagina)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight); nel visualizzatore VCL TsgcPDFViewerControl.RenderPageToBitmap
RenderPageToFileTsgcPDFExporter.ExportPage(ADocument, APageIndex, AFileName) (BMP, PNG, JPEG), sgcPDFPageToImage(APDFFile, AImageFile, APageIndex, ADPI)
FormFieldCount, FindFormFieldByTitleTsgcPDFDocument.AcroForm.FieldCount, AcroForm.FindField(AName)
SetFormFieldValue, SetFormFieldValueByTitleAcroForm.FillField(AName, AValue), AcroForm.SetCheckBox(AName, AChecked), TsgcPDFEditor.FillFormField
GetFormFieldValueAcroForm.GetFieldValue(AName)
NewFormFieldAcroForm.AddTextField, AddCheckBox, AddComboBox, AddListBox, AddRadioGroup + AddRadioButton, AddButton, AddSignatureField
FlattenFormFieldAcroForm.FlattenFields, TsgcPDFEditor.FlattenForm
EncryptTsgcPDFDocument.SetEncryption(AMethod, AUserPassword, AOwnerPassword) con emAES_256, emAES_128, emRC4_128 oppure emRC4_40
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (overload con un riquadro di pagina, un rettangolo o annotazioni)
DrawCapturedPageTsgcPDFPage.DrawForm(AFormIndex, X, Y, AScaleX, AScaleY, ARotation), DrawFormInRect(AFormIndex, ATarget, AKeepAspect, ARotation), DrawFormMatrix
GetPageBoxTsgcPDFPage.GetPageBox(ABox) (ppbTrimBox, ppbBleedBox, ...), TsgcPDFDocument.GetFormBBox
NewOutlineTsgcPDFEditor.AddBookmark(ATitle, APageIndex), AddBookmarkChild
AddLinkToPageTsgcPDFEditor.AddLinkAnnotation(APageIndex, ALeft, ABottom, ARight, ATop, ADestPage)
AddNoteAnnotationTsgcPDFEditor.AddTextAnnotation(APageIndex, ALeft, ABottom, ARight, ATop, AText)
SignFileTsgcPDFEditor.SignDocument(AOutputFile, ACertSubjectName, AReason, ALocation)
PrintDocumentIl visualizzatore VCL TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) stampa senza finestra di dialogo, PrintDialog(ATitle) mostra la finestra di dialogo della stampante (intervallo di pagine, copie) e stampa. Il visualizzatore FireMonkey TsgcPDFViewerFMX ha gli stessi due metodi su Windows e macOS.
SetMeasurementUnits(0), SetOrigin(0)il sistema di coordinate predefinito e unico: punti, origine in basso a sinistra; helper sgcPDFMMToPoints, sgcPDFRectMM

Anche nei visualizzatori Delphi: zoom adattato all'altezza (zmFitHeight su TsgcPDFViewerControl, fzmFitHeight su TsgcPDFViewerFMX, ZoomFitHeight su TsgcPDFViewer) e rotazione della vista (ViewRotation, RotateLeft, RotateRight), che ruota la vista e lascia invariato il documento.

I lavori più comuni di Quick PDF Library in sgcPDF

Ogni estratto è copiato dalla demo MigrateFromQuickPDF, che compila con Delphi 7 (Win32) e Delphi 13 (Win32 e Win64) e supera il proprio autotest. I commenti riportano le chiamate di Quick PDF Library che ogni riga sostituisce.

La clausola uses

L'unit di importazione di Quick PDF Library e la DLL spariscono. Queste unit coprono ogni lavoro della demo:

frmMain.pas
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ShellAPI,
  // sgc
  sgcPDF_Types, sgcPDF_Fonts, sgcPDF_Document, sgcPDF_Encryption,
  sgcPDF_Editor, sgcPDF_Renderer_GDI;

Creare un documento con testo, un riquadro e un'immagine

Sostituisce NewDocument, SetInformation, AddStandardFont, SelectFont, SetTextSize, SetTextColor, DrawText, DrawBox, AddImageFromFile, SelectImage, DrawImage e SaveToFile.

frmMain.pas
oDoc := TsgcPDFDocument.Create;
try
  // SetInformation(1, ...) / SetInformation(2, ...)
  oDoc.Info.Title := 'Created with sgcPDF';
  oDoc.Info.Author := 'Migration sample';
  // NewDocument creates page 1, sgcPDF adds every page explicitly
  oPage := oDoc.AddPage(CS_A4_WIDTH, CS_A4_HEIGHT);
  // AddStandardFont(4) + SelectFont + SetTextSize(28) + DrawText
  oPage.DrawText('Hello from sgcPDF', 72, 760, sfHelveticaBold, 28);
  // SetTextColor(r, g, b) + DrawText
  oPage.DrawTextColor('No DLL, pure Pascal.', 72, 725, sfHelvetica, 14,
    0.1, 0.3, 0.7);
  // SetLineColor + SetLineWidth + DrawBox(x, y, w, h, 0)
  oPage.DrawRectangle(72, 520, 260, 120, 1.5);
  // AddImageFromFile + SelectImage + DrawImage(x, y, w, h)
  vImage := oDoc.AddImage(OutFile('logo.bmp'));
  oPage.DrawImageFromIndex(vImage, 102, 540, 200, 80);
  oDoc.SaveToFile(OutFile('created.pdf'));
finally
  oDoc.Free;
end;

Estrarre il testo di una pagina

Sostituisce LoadFromFile, PageCount, SelectPage e GetPageText. Nota l'indice di pagina in base 0.

frmMain.pas
oDoc.LoadFromFile(OutFile('input_a.pdf'));
Log('Extract text: input_a.pdf has ' + IntToStr(oDoc.PageCount) +
  ' pages');
// SelectPage(2) + GetPageText(0): sgcPDF page indexes are 0-based
vText := string(oDoc.ExtractTextW(1));
Log(vText);

Unire e dividere

Sostituisce AddToFileList con MergeFileList, e ExtractPageRanges o ExtractFilePages. Le stringhe di intervallo restano in base 1.

frmMain.pas
sgcPDFMergeFiles([OutFile('input_a.pdf'), OutFile('input_b.pdf')],
  OutFile('merged.pdf'));
frmMain.pas
// 1-based range string, the same syntax as Quick PDF Library
sgcPDFExtractPages(OutFile('merged.pdf'), OutFile('pages_2-3.pdf'), '2-3');
// one file per page: split
sgcPDFExtractPages(OutFile('merged.pdf'), OutFile('page_4.pdf'), '4');

Filigrana e timbro su ogni pagina

Sostituisce SelectPage, SetTransparency, SetTextColor e DrawText in un ciclo sulle pagine.

frmMain.pas
oEditor.LoadFromFile(OutFile('input_a.pdf'));
vOptions.Text := 'CONFIDENTIAL';
vOptions.Font := sfHelveticaBold;
vOptions.FontSize := 72;
vOptions.Rotation := 45;
vOptions.Opacity := 0.3;
vOptions.R := 0.8;
vOptions.G := 0.1;
vOptions.B := 0.1;
oEditor.AddWatermarkAllPages(vOptions);
// a stamp in the top right corner of every page
for i := 0 to oEditor.Document.PageCount - 1 do
  oEditor.AddTextColor(i, 'APPROVED', 440, 800, sfHelveticaBold, 16,
    0.0, 0.5, 0.0);
oEditor.SaveToFile(OutFile('watermarked.pdf'));

Renderizzare una pagina su un contesto di dispositivo

Sostituisce RenderPageToDC. Il renderer prende il Parser del documento caricato e il PageDict della pagina.

frmMain.pas
oDoc.LoadFromFile(OutFile('created.pdf'));
oPage := oDoc.Pages[0];
// 96 DPI: points are 1/72 inch
vScale := 96 / 72;
vW := Round(oPage.Width * vScale);
vH := Round(oPage.Height * vScale);
oBitmap.PixelFormat := pf24bit;
oBitmap.Width := vW;
oBitmap.Height := vH;
oBitmap.Canvas.Brush.Color := clWhite;
oBitmap.Canvas.FillRect(Rect(0, 0, vW, vH));
oRenderer.RenderPage(oBitmap.Canvas.Handle, oDoc.Parser, oPage.PageDict,
  vW, vH);
GdiFlush;
oBitmap.SaveToFile(OutFile('created_page1.bmp'));

Compilare un modulo

Sostituisce FormFieldCount, FindFormFieldByTitle e SetFormFieldValue.

frmMain.pas
oDoc.LoadFromFile(OutFile('form.pdf'));
Log('Fill form: form.pdf has ' + IntToStr(oDoc.AcroForm.FieldCount) +
  ' fields');
oDoc.AcroForm.FillField('Customer', 'ACME Corporation');
oDoc.AcroForm.FillField('Amount', '1250.00');
oDoc.AcroForm.SetCheckBox('Paid', True);
oDoc.SaveToFile(OutFile('form_filled.pdf'));

Cifrare con AES-256 e aprire con la password

Sostituisce Encrypt, e LoadFromFile con una password.

frmMain.pas
oDoc.LoadFromFile(OutFile('input_a.pdf'));
oDoc.SetEncryption(emAES_256, CS_USER_PASSWORD, CS_OWNER_PASSWORD);
oDoc.SaveToFile(OutFile('encrypted.pdf'));
frmMain.pas
oDoc.SetPassword(CS_USER_PASSWORD);
oDoc.LoadFromFile(OutFile('encrypted.pdf'));
vText := string(oDoc.ExtractTextW(0));

Imposizione 2-up

Sostituisce CapturePage, NewPage, SetPageDimensions e DrawCapturedPage. AddPageAsForm mantiene ogni pagina di origine come XObject di modulo, quindi il testo resta vettoriale e selezionabile.

frmMain.pas
oSource.LoadFromFile(OutFile('merged.pdf'));
vHalf := CS_A4_HEIGHT / 2;
oSheet := nil;
for i := 0 to oSource.PageCount - 1 do
begin
  // a landscape A4 sheet for every 2 source pages
  if i mod 2 = 0 then
    oSheet := oTarget.AddPage(CS_A4_HEIGHT, CS_A4_WIDTH);
  // CapturePage
  vForm := oTarget.AddPageAsForm(oSource, i);
  // DrawCapturedPage, scaled to fit the left or the right half
  oSheet.DrawFormInRect(vForm, sgcPDFRect((i mod 2) * vHalf, 0,
    (i mod 2) * vHalf + vHalf, CS_A4_WIDTH), True);
end;
oTarget.SaveToFile(OutFile('imposed_2up.pdf'));

Le classi di PdfiumViewer in sgcPDF

Namespace esegece.sgcPDF, pacchetto esegece.sgcPDF.WinForms. Gli indici di pagina sono in base 0 in entrambe le librerie.

PdfiumViewer sgcPDF .NET
PdfViewer (UserControl con una barra degli strumenti e un riquadro dei segnalibri)TsgcPDFViewerControl; costruisci la tua barra degli strumenti, segnalibri in TsgcPDFOutlineView
PdfRenderer (PdfViewer.Renderer)lo stesso TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (il visualizzatore possiede il documento), LoadFromStream, oppure Document = vDoc (lo rilasci tu)
PdfDocument.Load(path, password)TsgcPDFDocument.SetPassword prima di LoadFromFile, poi TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (proprietà), TsgcPDFDocument.PageCount() (metodo)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width e .Height (punti)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex, GotoPage, NextPage, PrevPage, FirstPage, LastPage, evento OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (un fattore, 1.0 = 100%)TsgcPDFViewerControl.Zoom (una percentuale, 100 = 100%, imposta zmCustom), ZoomIn, ZoomOut, zmActualSize, ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0, pvr90, pvr180, pvr270); PageRotation(i) restituisce la rotazione mostrata
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (evidenzia e scorre), FindNext, FindPrevious, SearchResults, GetSearchMatch(i), ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog oppure PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() restituisce un System.Drawing.Printing.PrintDocument per gli stessi PrintDialog e PrintPreviewDialog. In una sola chiamata: PrintDialog(ATitle); senza finestra di dialogo: Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI); senza visualizzatore sgcPDF_Export.sgcPDFPageToImage or TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex); con le posizioni dei caratteri TsgcPDFViewerControl.PageText(i); selezione con il mouse SelectedText, CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile, SaveIncremental(AFileName) (mantiene i byte originali e accoda le modifiche)
nessun equivalente: compilazione di moduliTsgcPDFViewerControl.FormFilling = true, OnFieldChange; nel codice AcroForm.FillField, SetCheckBox, GetFieldValue, FindField
nessun equivalente: annotazioniTsgcPDFDocument.Annotations.AddText, AddFreeText, AddHighlight, AddStamp, AddLine, AddSquare, AddCircle, poi AnnotationsChanged(); con il mouse AnnotationTool e AnnotationEditing
nessun equivalente: creare un PDFTsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

Un modulo PdfiumViewer con il visualizzatore sgcPDF

Ogni estratto è copiato dalla demo MigrateFromPdfiumViewer, che compila in Release e supera il proprio autotest. I commenti citano il codice di PdfiumViewer che ogni blocco sostituisce.

Un solo controllo al posto di PdfViewer e PdfRenderer

MainForm.cs
// PdfiumViewer: PdfViewer (UserControl with toolbar) and its PdfRenderer (the page
// surface, PdfViewer.Renderer) -> one control, TsgcPDFViewerControl
private TsgcPDFViewerControl FViewer;
MainForm.cs
FViewer = new TsgcPDFViewerControl();
FViewer.Parent = pnlViewer;
FViewer.Dock = DockStyle.Fill;
// PdfiumViewer: PdfRenderer.DisplayRectangleChanged / polling PdfRenderer.Page -> OnPageChange
FViewer.OnPageChange = DoPageChange;
// PdfiumViewer: none, PdfiumViewer renders form fields but cannot edit them.
// sgcPDF: the user types into text fields and toggles check boxes in the viewer
FViewer.FormFilling = true;
FViewer.OnFieldChange = DoFieldChange;
// PdfiumViewer: none. sgcPDF: AnnotationTool adds notes, highlights, shapes, ink
// and stamps with the mouse; AnnotationEditing moves, resizes and deletes them
FViewer.AnnotationAuthor = "sgcPDF demo";

Aprire un file

MainForm.cs
// PdfiumViewer: pdfViewer1.Document = PdfDocument.Load(AFileName)
// sgcPDF: the viewer loads and owns the document; to share a document you load
// yourself, assign it: FViewer.Document = vDoc (you dispose it)
FViewer.LoadFromFile(AFileName);
// PdfiumViewer: PdfViewer.ZoomMode = PdfViewerZoomMode.FitWidth
FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitWidth;
// PdfiumViewer: PdfDocument.PageCount -> TsgcPDFViewerControl.PageCount
// (or TsgcPDFDocument.PageCount(), a method)
Log("Opened " + Path.GetFileName(AFileName) + ", " + sgcPDF_RTL.IntToStr(FViewer.PageCount) + " pages");

Modalità di zoom e rotazione della vista

Adatta alla larghezza, alla pagina e all'altezza si corrispondono uno a uno. Lo zoom è una percentuale invece di un fattore.

MainForm.cs
internal void FitWidth()
{
    // PdfiumViewer: PdfViewerZoomMode.FitWidth -> TsgcPDFViewerZoomMode.zmFitWidth
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitWidth;
}

internal void FitPage()
{
    // PdfiumViewer: PdfViewerZoomMode.FitBest -> TsgcPDFViewerZoomMode.zmFitPage
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitPage;
}

internal void FitHeight()
{
    // PdfiumViewer: PdfViewerZoomMode.FitHeight -> TsgcPDFViewerZoomMode.zmFitHeight
    FViewer.ZoomMode = TsgcPDFViewerZoomMode.zmFitHeight;
}

internal void RotateLeft()
{
    // PdfiumViewer: PdfRenderer.RotateLeft() -> TsgcPDFViewerControl.RotateLeft()
    // (ViewRotation turns the view only, the document is not changed)
    FViewer.RotateLeft();
}

internal void RotateRight()
{
    // PdfiumViewer: PdfRenderer.RotateRight() -> TsgcPDFViewerControl.RotateRight()
    FViewer.RotateRight();
}

internal void SetZoomPercent(double APercent)
{
    // PdfiumViewer: PdfRenderer.Zoom is a factor (1.0 = 100%);
    // TsgcPDFViewerControl.Zoom is a percentage (100 = 100%) and sets ZoomMode to zmCustom
    FViewer.Zoom = APercent;
}

Ricerca

MainForm.cs
// PdfiumViewer: PdfDocument.Search(text, matchCase, wholeWord) returns PdfMatches
// and the app adds PdfMarker objects to PdfRenderer.Markers to highlight them.
// sgcPDF: FindText highlights every match and scrolls to the first one,
// FindNext / FindPrevious move between them, GetSearchMatch(i) gives page and chars
if (!FViewer.FindText(AText, false, false))
{
    Log("Not found: " + AText);
    return 0;
}
for (int i = 0; i < FViewer.SearchResults; i++)
{
    TsgcPDFViewerSearchMatch vMatch = FViewer.GetSearchMatch(i);
    Log("Match " + sgcPDF_RTL.IntToStr(i + 1) + ": page " + sgcPDF_RTL.IntToStr(vMatch.PageIndex + 1) +
      ", char " + sgcPDF_RTL.IntToStr(vMatch.FirstChar));
}
return FViewer.SearchResults;

Stampare con CreatePrintDocument

Il codice di stampa di PdfiumViewer mantiene la sua forma: CreatePrintDocument() restituisce un PrintDocument per un PrintDialog o un PrintPreviewDialog.

MainForm.cs
// PdfiumViewer: using (PrintDocument d = PdfDocument.CreatePrintDocument())
//   { PrintDialog dlg = new PrintDialog(); dlg.Document = d; if (dlg.ShowDialog() == OK) d.Print(); }
// sgcPDF: TsgcPDFViewerControl.CreatePrintDocument() returns the same kind of
// System.Drawing.Printing.PrintDocument, so the PdfiumViewer code stays as it is. It honours
// the page range (all, some pages, current page), copies and collate of its PrinterSettings.
// A shorter way: FViewer.PrintDialog(title) shows the dialog and prints in one call, and
// FViewer.Print(from, to, title) prints without a dialog (0-based pages, -1 = last page).
if (FViewer.PageCount == 0)
    return;
using (PrintDocument vDoc = FViewer.CreatePrintDocument())
using (PrintDialog vDialog = new PrintDialog())
{
    vDoc.DocumentName = "PdfiumViewer migration sample";
    vDialog.Document = vDoc;
    vDialog.AllowSomePages = true;
    vDialog.AllowCurrentPage = true;
    vDialog.UseEXDialog = true;
    vDoc.PrinterSettings.MinimumPage = 1;
    vDoc.PrinterSettings.MaximumPage = FViewer.PageCount;
    vDoc.PrinterSettings.FromPage = 1;
    vDoc.PrinterSettings.ToPage = FViewer.PageCount;
    if (vDialog.ShowDialog(this) == DialogResult.OK)
        vDoc.Print();
}
MainForm.cs
// PdfiumViewer: PrintPreviewDialog with PdfDocument.CreatePrintDocument()
// sgcPDF: the same with TsgcPDFViewerControl.CreatePrintDocument()
if (FViewer.PageCount == 0)
    return;
using (PrintDocument vDoc = FViewer.CreatePrintDocument())
using (PrintPreviewDialog vPreview = new PrintPreviewDialog())
{
    vPreview.Document = vDoc;
    vPreview.Width = 900;
    vPreview.Height = 700;
    vPreview.ShowDialog(this);
}

Renderizzare una pagina in una bitmap

MainForm.cs
// PdfiumViewer: Image img = PdfDocument.Render(page, dpiX, dpiY, forPrinting)
// sgcPDF: RenderPageToBitmap(page, ref bitmap, zoomPercent, dpi); the bitmap passed
// in is disposed and replaced
Bitmap vBitmap = null;
FViewer.RenderPageToBitmap(APageIndex, ref vBitmap, 100, 150);
try
{
    vBitmap.Save(AFileName, ImageFormat.Png);
    Log("Page " + sgcPDF_RTL.IntToStr(APageIndex + 1) + " rendered at 150 dpi: " +
      sgcPDF_RTL.IntToStr(vBitmap.Width) + " x " + sgcPDF_RTL.IntToStr(vBitmap.Height) + " px, " +
      AFileName);
}
finally
{
    vBitmap.Dispose();
}
// without a viewer (server, batch): one call from file to image
sgcPDF_Export.sgcPDFPageToImage(FViewer.FileName, Path.ChangeExtension(AFileName, null) + "_file.png",
  APageIndex, 72);

Testo della pagina

MainForm.cs
// PdfiumViewer: PdfDocument.GetPdfText(page) returns the plain text of a page.
// sgcPDF: TsgcPDFDocument.ExtractTextW(page) is the same plain text, and
// TsgcPDFViewerControl.PageText(page) returns a TsgcPDFTextExtractor with the
// characters and their positions (GetTextWithPositions); the user can also select
// text with the mouse and copy it (SelectedText, CopyToClipboard)
string vText = FViewer.Document.ExtractTextW(APageIndex);
Log("Text of page " + sgcPDF_RTL.IntToStr(APageIndex + 1) + ": " + vText.Trim());
TsgcPDFTextExtractor vExtractor = FViewer.PageText(APageIndex);
if (vExtractor != null)
    Log("Characters with positions: " + sgcPDF_RTL.IntToStr(vExtractor.GetCharCount()));
return vText;

Oltre PdfiumViewer: compilare un modulo e aggiungere una nota

MainForm.cs
// PdfiumViewer: none (no AcroForm API). sgcPDF: AcroForm.FillField / SetCheckBox,
// then an incremental save keeps the original bytes and appends the change
TsgcPDFDocument vDoc = FViewer.Document;
if (vDoc.AcroForm.FindField("CustomerName") == null)
{
    Log("This document has no CustomerName field, open the generated sample");
    return;
}
vDoc.AcroForm.FillField("CustomerName", "ACME Ltd.");
vDoc.AcroForm.SetCheckBox("Approved", true);
FViewer.ClearCache();
FViewer.Invalidate();
vDoc.SaveIncremental(AFileName);
Log("Form filled and saved: " + AFileName);
MainForm.cs
// PdfiumViewer: none (annotations are only rendered). sgcPDF: the document's
// Annotations manager adds notes, free text, highlights, stamps, lines, shapes and
// ink; the viewer shows them after AnnotationsChanged
TsgcPDFDocument vDoc = FViewer.Document;
int vPage = FViewer.PageIndex;
TsgcPDFTextAnnotation vNote = vDoc.Annotations.AddText(vPage, 420, 760, 444, 784,
  "Migrated from PdfiumViewer to sgcPDF.");
vNote.Author = "sgcPDF demo";
vNote.SetColor(1.0, 0.9, 0.2);
vDoc.Annotations.AddHighlight(vPage, 72, 728, 330, 728, 72, 742, 330, 742);
FViewer.AnnotationsChanged();
vDoc.SaveIncremental(AFileName);
Log("Note and highlight added on page " + sgcPDF_RTL.IntToStr(vPage + 1) + ", saved: " + AFileName);

Passo dopo passo

Porta un lavoro o un modulo alla volta, e confronta i file di output prima e dopo.

Delphi: da Quick PDF Library

1

Aggiungere le unit

Aggiungi la cartella Source di sgcPDF o il pacchetto installato, e sostituisci l'importazione di Quick PDF Library con sgcPDF_Types, sgcPDF_Fonts e sgcPDF_Document, più sgcPDF_Editor, sgcPDF_Encryption e sgcPDF_Renderer_GDI quando servono.

2

Eliminare la DLL

Rimuovi la DLL o l'ActiveX dalla distribuzione e la chiamata a UnlockKey dal codice.

3

Un oggetto per documento

Sostituisci l'oggetto TQuickPDF con un TsgcPDFDocument per documento, o un TsgcPDFEditor per i lavori di caricamento, modifica e salvataggio.

4

Le pagine sono oggetti

Sostituisci SelectPage e le chiamate di disegno con chiamate sul TsgcPDFPage ottenuto da AddPage o Pages[i], e sottrai 1 da ogni numero di pagina.

5

Mappare le chiamate

Usa la tabella qui sopra. I font standard sono un argomento di DrawText; i font TrueType si aggiungono una volta con AddTrueTypeFont e si disegnano con DrawTextTT.

6

Imposizione

Sostituisci CapturePage e DrawCapturedPage con AddPageAsForm e DrawForm o DrawFormInRect.

7

Confrontare l'output

Esegui il lavoro convertito e controlla i file. L'autotest della demo fa da modello: riapre ogni output e controlla il numero di pagine, il testo e i valori del modulo.

WinForms: da PdfiumViewer

1

Rimuovere le parti native

Rimuovi il pacchetto PdfiumViewer, ogni pacchetto PdfiumViewer.Native.* e ogni pdfium.dll copiata a mano, comprese le cartelle x86 e x64. Il progetto può tornare ad AnyCPU.

2

Aggiungere sgcPDF

Aggiungi esegece.sgcPDF.WinForms (oppure esegece.sgcPDF.WinForms.Community), che porta con sé esegece.sgcPDF, e aggiungi using esegece.sgcPDF;.

3

Sostituire il controllo

Sostituisci il PdfViewer o il PdfRenderer con un TsgcPDFViewerControl (Dock = Fill) e ricostruisci i pulsanti della barra degli strumenti che usavi come chiamate sul controllo.

4

Caricare il documento

Sostituisci PdfDocument.Load e Document = con LoadFromFile, oppure carica tu stesso un TsgcPDFDocument e assegnalo a Document.

5

Mappare i membri

Page diventa PageIndex o GotoPage, le modalità di zoom corrispondono a TsgcPDFViewerZoomMode, il fattore di zoom si moltiplica per 100, Search diventa FindText, Render diventa RenderPageToBitmap.

6

Mantenere il codice di stampa

Chiama CreatePrintDocument() sul visualizzatore invece che sul documento di PdfiumViewer; il codice con PrintDialog e PrintPreviewDialog resta. Oppure usa PrintDialog(ATitle).

7

Attivare le novità

Facoltativo: FormFilling = true, AnnotationTool e SaveIncremental, che PdfiumViewer non poteva offrire.

Ciò che non si mappa uno a uno

Leggi questo prima di pianificare il passaggio.

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF e MigrateFromPdfiumViewer

Entrambe le demo generano i propri file di input, quindi non serve alcun PDF esterno, ed entrambe hanno un autotest.

Delphi: dove si trova

L'installer di sgcUI la colloca in Demos\PDF\Delphi\MigrateFromQuickPDF: sgcPDF_Demo_MigrateFromQuickPDF.dpr, frmMain.pas, frmMain.dfm e un readme.html.

Delphi: come eseguirla

Apri il .dpr in qualsiasi Delphi da 7 a 13 (VCL, Win32 o Win64), fai clic su Generate sample inputs, poi su un pulsante qualsiasi o su Run all. L'output va nella cartella output accanto all'exe.

Delphi: autotest

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] esegue ogni lavoro, controlla i risultati e scrive selftest.log, che termina con SELFTEST OK.

.NET: dove si trova

Nelle demo .NET di sgcUI, cartella PDF\MigrateFromPdfiumViewer della soluzione sgcUI_Demos.sln: sgcPDF_Demo_MigrateFromPdfiumViewer.csproj, Program.cs e MainForm.cs.

.NET: come eseguirla

dotnet run --project demos\PDF\MigrateFromPdfiumViewer (aggiungi -p:SgcCommunity=true per l'edizione Community), fai clic su Generate sample, che scrive e apre output\sample.pdf, poi su un pulsante qualsiasi.

.NET: autotest

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] apre l'esempio, naviga, zooma, adatta l'altezza, ruota, cerca, renderizza, conta le pagine di un'anteprima di stampa, estrae il testo, compila il modulo, aggiunge una nota e riapre i file salvati. Scrive selftest.log, che termina con SELFTEST OK.

Per essere onesti verso entrambe le librerie: un'applicazione basata su Quick PDF Library o PdfiumViewer continua a funzionare dove è distribuita oggi, e Foxit indica i propri SDK PDF come successori di Quick PDF Library. sgcPDF è la strada quando vuoi il codice PDF in sorgente Pascal o C# che si compila nella tua applicazione, senza una libreria PDF nativa da distribuire, e con un'unica API che crea, compila, annota, firma e cifra anche i file che il tuo visualizzatore mostra. Per i componenti e le edizioni vedi la pagina del prodotto sgcPDF.

La scelta più conveniente: All-AccessTutti i prodotti eSeGeCe, con Supporto Premium incluso, a partire da €1,059/anno.
Vedi i prezzi All-Access

Porta oggi il tuo primo lavoro PDF

Scarica sgcUI con sgcPDF, oppure aggiungi i pacchetti Community gratuiti da NuGet, e porta il tuo primo lavoro o modulo con le demo MigrateFromQuickPDF e MigrateFromPdfiumViewer accanto.