Migrar de Quick PDF Library y PdfiumViewer a sgcPDF

Foxit dio de baja Quick PDF Library el 13 de diciembre de 2021, y el repositorio de PdfiumViewer es de solo lectura desde el 2 de agosto de 2019. sgcPDF sustituye a ambos: Pascal puro compilado en tu exe de Delphi y C# administrado para WinForms, sin DLL de PDF que desplegar. Este kit hace corresponder las funciones de Quick PDF Library y las clases de PdfiumViewer con sgcPDF, con código de dos ejemplos que compilan y superan su autoprueba.

Aplicaciones construidas sobre una biblioteca PDF que ya no evoluciona

Dos casos habituales: una aplicación Delphi que crea, fusiona, rellena y renderiza archivos PDF con Quick PDF Library, y una aplicación WinForms que muestra archivos PDF con PdfiumViewer.

Desde Quick PDF Library (Delphi)

Quick PDF Library (Debenu Quick PDF Library, más tarde Foxit Quick PDF Library) se entrega como DLL, ActiveX o LIB con una clave de desbloqueo, y trabaja con un único objeto en el que hay un documento, una página, una fuente y una imagen "seleccionados". sgcPDF es un conjunto de unidades Pascal con un modelo de objetos: TsgcPDFDocument, TsgcPDFPage, TsgcPDFEditor y TsgcPDFAcroForm, de Delphi 7 a Delphi 13.

Desde PdfiumViewer (WinForms)

PdfiumViewer envuelve la biblioteca nativa PDFium en un control PdfViewer, un PdfRenderer y un PdfDocument. Muestra, busca, renderiza e imprime archivos PDF. sgcPDF los sustituye por un único control administrado, TsgcPDFViewerControl, y añade lo que PdfiumViewer nunca tuvo: crear archivos PDF, rellenar formularios, añadir anotaciones y guardar los cambios.

Quick PDF Library. El aviso de Foxit (leído el 20/10/2026) dice en esencia: "A partir del 13 de diciembre de 2021, Foxit dará de baja los siguientes productos", y el primer producto de la lista es Foxit Quick PDF Library (todas las plataformas). Los clientes con contratos de mantenimiento y soporte activos recibieron soporte hasta el 13 de diciembre de 2022: "Después de esa fecha, el producto pasará a fin de soporte y ya no recibirá soporte." Los sustitutos que nombra Foxit son sus SDK de PDF para Windows, Mac, Linux, Android e iOS, su SDK ActiveX y su suite de SDK .NET.

PdfiumViewer. El repositorio de GitHub (leído el 20/10/2026) muestra en esencia: "Este repositorio fue archivado por el propietario el 2 de ago. de 2019. Ahora es de solo lectura." Su README explica: "Hace mucho tiempo que no he podido dedicarle tiempo real", y "No estoy en condiciones de dar soporte adecuado a este proyecto." También dice: "El control PdfiumViewer requiere bibliotecas nativas de PDFium. No se incluyen en el paquete NuGet de PdfiumViewer." El paquete NuGet se actualizó por última vez el 06/11/2017 (versión 2.13.0) y apunta a net20.

Una biblioteca PDF, código fuente incluido

sgcPDF es el producto PDF de sgcUI. Crea, edita, rellena, firma, cifra, renderiza y muestra archivos PDF en Delphi y en .NET.

Ninguna DLL de PDF que entregar

En Delphi las unidades de sgcPDF se compilan en el exe: sin DLL, ActiveX ni LIB que desplegar y registrar, y sin llamada a una clave de desbloqueo. En .NET sgcPDF es C# administrado, así que no hay pdfium.dll ni paquete nativo x86 o x64 que elegir: el ejemplo se ejecuta como AnyCPU.

Un modelo de objetos

Cada llamada recibe el objeto de página o el índice, así que desaparece el estado "seleccionado" de Quick PDF Library. La imposición usa XObjects de formulario vectoriales (AddPageAsForm, DrawForm, DrawFormInRect), los formularios usan AcroForm, y el cifrado llega hasta AES-256 (emAES_256).

Un visor que edita

TsgcPDFViewerControl ajusta la vista al ancho, a la página o al alto, gira la vista, busca e imprime con un cuadro de diálogo, y en .NET entrega un PrintDocument como PdfiumViewer. También rellena campos de formulario (FormFilling), añade anotaciones con el ratón (AnnotationTool) y selecciona texto. Vistas laterales: TsgcPDFThumbnailView, TsgcPDFOutlineView, TsgcPDFCommentsView.

sgcPDF se vende por separado, desde €249 para un solo desarrollador en Delphi y C++ Builder y desde €249 para .NET, con código fuente completo y 1 año de actualizaciones, y forma parte de sgcUI Enterprise y del paquete All-Access. Los paquetes .NET también se publican como paquetes Community gratuitos en NuGet, esegece.sgcPDF.Community y esegece.sgcPDF.WinForms.Community, con las mismas funciones. Consulta la página de producto de sgcPDF.

Funciones de Quick PDF Library en sgcPDF

Las unidades son sgcPDF_Types, sgcPDF_Fonts y sgcPDF_Document, más sgcPDF_Editor, sgcPDF_Encryption, sgcPDF_Renderer_GDI y sgcPDF_Export cuando hacen falta. Los índices de página de sgcPDF empiezan en 0.

Quick PDF Library sgcPDF
UnlockKeynada que llamar en el código
NewDocumentTsgcPDFDocument.Create, después AddPage (un documento nuevo no tiene página hasta que añade una)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
LoadFromFile con contraseñaTsgcPDFDocument.SetPassword(APassword) antes de LoadFromFile
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount; solo para un archivo, sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (base 0, propiedad predeterminada), 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 y sus variantes en negrita y cursiva)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (componentes de 0 a 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (o AddTrueTypeFontFromFile), después 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), o 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) (cadena de rango en base 1 como '1,3,5-9'), TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (marca de agua)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
DrawText en cada página (sello, encabezado, pie de página)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight); en el visor 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 o emRC4_40
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (sobrecargas con un cuadro de página, un rectángulo o anotaciones)
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)
PrintDocumentVisor VCL TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) imprime sin cuadro de diálogo, PrintDialog(ATitle) muestra el cuadro de diálogo de impresión (rango de páginas, copias) e imprime. El visor FireMonkey TsgcPDFViewerFMX tiene los mismos dos métodos en Windows y macOS.
SetMeasurementUnits(0), SetOrigin(0)el sistema de coordenadas predeterminado y único: puntos, origen en la esquina inferior izquierda; ayudas sgcPDFMMToPoints, sgcPDFRectMM

También en los visores de Delphi: zoom de ajuste al alto (zmFitHeight en TsgcPDFViewerControl, fzmFitHeight en TsgcPDFViewerFMX, ZoomFitHeight en TsgcPDFViewer) y giro de la vista (ViewRotation, RotateLeft, RotateRight), que gira la vista y deja el documento sin cambios.

Los trabajos habituales de Quick PDF Library en sgcPDF

Cada fragmento está copiado de la demo MigrateFromQuickPDF, que compila con Delphi 7 (Win32) y Delphi 13 (Win32 y Win64) y supera su autoprueba. Los comentarios nombran las llamadas de Quick PDF Library que sustituye cada línea.

La cláusula uses

La unidad de importación de Quick PDF Library y la DLL desaparecen. Estas unidades cubren todos los trabajos de la 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;

Crear un documento con texto, un recuadro y una imagen

Sustituye NewDocument, SetInformation, AddStandardFont, SelectFont, SetTextSize, SetTextColor, DrawText, DrawBox, AddImageFromFile, SelectImage, DrawImage y 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;

Extraer el texto de una página

Sustituye LoadFromFile, PageCount, SelectPage y GetPageText. Observa el índice de página en 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);

Fusionar y dividir

Sustituye AddToFileList con MergeFileList, y ExtractPageRanges o ExtractFilePages. Las cadenas de rango siguen en 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');

Marca de agua y sello en cada página

Sustituye SelectPage, SetTransparency, SetTextColor y DrawText en un bucle sobre las páginas.

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'));

Renderizar una página en un contexto de dispositivo

Sustituye RenderPageToDC. El renderizador toma el Parser del documento cargado y el PageDict de la página.

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'));

Rellenar un formulario

Sustituye FormFieldCount, FindFormFieldByTitle y 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'));

Cifrar con AES-256 y abrir con la contraseña

Sustituye Encrypt, y LoadFromFile con contraseña.

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));

Imposición 2-up

Sustituye CapturePage, NewPage, SetPageDimensions y DrawCapturedPage. AddPageAsForm conserva cada página de origen como XObject de formulario, así que el texto sigue siendo vectorial y seleccionable.

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'));

Clases de PdfiumViewer en sgcPDF

Espacio de nombres esegece.sgcPDF, paquete esegece.sgcPDF.WinForms. Los índices de página son de base 0 en ambas bibliotecas.

PdfiumViewer sgcPDF .NET
PdfViewer (UserControl con una barra de herramientas y un panel de marcadores)TsgcPDFViewerControl; crea tu propia barra de herramientas, marcadores en TsgcPDFOutlineView
PdfRenderer (PdfViewer.Renderer)el mismo TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (el visor es propietario del documento), LoadFromStream, o Document = vDoc (tú lo liberas)
PdfDocument.Load(path, password)TsgcPDFDocument.SetPassword antes de LoadFromFile, después TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (propiedad), TsgcPDFDocument.PageCount() (método)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width y .Height (puntos)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex, GotoPage, NextPage, PrevPage, FirstPage, LastPage, evento OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (un factor, 1.0 = 100 %)TsgcPDFViewerControl.Zoom (un porcentaje, 100 = 100 %, establece zmCustom), ZoomIn, ZoomOut, zmActualSize, ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0, pvr90, pvr180, pvr270); PageRotation(i) devuelve el giro mostrado
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (resalta y se desplaza), FindNext, FindPrevious, SearchResults, GetSearchMatch(i), ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog o PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() devuelve un System.Drawing.Printing.PrintDocument para los mismos PrintDialog y PrintPreviewDialog. En una sola llamada: PrintDialog(ATitle); sin cuadro de diálogo: Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI); sin visor sgcPDF_Export.sgcPDFPageToImage or TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex); con posiciones de caracteres TsgcPDFViewerControl.PageText(i); selección con el ratón SelectedText, CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile, SaveIncremental(AFileName) (conserva los bytes originales y añade los cambios)
sin equivalente: rellenar formulariosTsgcPDFViewerControl.FormFilling = true, OnFieldChange; en código AcroForm.FillField, SetCheckBox, GetFieldValue, FindField
sin equivalente: anotacionesTsgcPDFDocument.Annotations.AddText, AddFreeText, AddHighlight, AddStamp, AddLine, AddSquare, AddCircle, después AnnotationsChanged(); con el ratón AnnotationTool y AnnotationEditing
sin equivalente: crear un PDFTsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

Un formulario de PdfiumViewer con el visor de sgcPDF

Cada fragmento está copiado de la demo MigrateFromPdfiumViewer, que compila en Release y supera su autoprueba. Los comentarios citan el código de PdfiumViewer que sustituye cada bloque.

Un control en lugar de PdfViewer y 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";

Abrir un archivo

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");

Modos de zoom y giro de la vista

Ajustar al ancho, a la página y al alto se corresponden uno a uno. El zoom es un porcentaje en lugar de un factor.

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;
}

Búsqueda

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;

Imprimir con CreatePrintDocument

El código de impresión de PdfiumViewer conserva su forma: CreatePrintDocument() devuelve un PrintDocument para 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);
}

Renderizar una página en un mapa de bits

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);

Texto de la página

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;

Más allá de PdfiumViewer: rellenar un formulario y añadir 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);

Paso a paso

Porta un trabajo o un formulario cada vez, y compara los archivos de salida antes y después.

Delphi: desde Quick PDF Library

1

Añadir las unidades

Añade la carpeta Source de sgcPDF o el paquete instalado, y sustituye la importación de Quick PDF Library por sgcPDF_Types, sgcPDF_Fonts y sgcPDF_Document, más sgcPDF_Editor, sgcPDF_Encryption y sgcPDF_Renderer_GDI cuando hagan falta.

2

Quitar la DLL

Quita la DLL o el ActiveX del despliegue y la llamada a UnlockKey del código.

3

Un objeto por documento

Sustituye el objeto TQuickPDF por un TsgcPDFDocument por documento, o un TsgcPDFEditor para los trabajos de carga, edición y guardado.

4

Las páginas son objetos

Sustituye SelectPage y las llamadas de dibujo por llamadas sobre el TsgcPDFPage obtenido con AddPage o Pages[i], y resta 1 de cada número de página.

5

Hacer corresponder las llamadas

Usa la tabla anterior. Las fuentes estándar son un argumento de DrawText; las fuentes TrueType se añaden una vez con AddTrueTypeFont y se dibujan con DrawTextTT.

6

Imposición

Sustituye CapturePage y DrawCapturedPage por AddPageAsForm y DrawForm o DrawFormInRect.

7

Comparar la salida

Ejecuta el trabajo convertido y comprueba los archivos. La autoprueba de la demo sirve de plantilla: reabre cada salida y comprueba el número de páginas, el texto y los valores del formulario.

WinForms: desde PdfiumViewer

1

Quitar las partes nativas

Quita el paquete PdfiumViewer, cada paquete PdfiumViewer.Native.* y cualquier pdfium.dll copiado a mano, incluidas las carpetas x86 y x64. El proyecto puede volver a AnyCPU.

2

Añadir sgcPDF

Añade esegece.sgcPDF.WinForms (o esegece.sgcPDF.WinForms.Community), que incluye esegece.sgcPDF, y añada using esegece.sgcPDF;.

3

Cambiar el control

Sustituye el PdfViewer o el PdfRenderer por un TsgcPDFViewerControl (Dock = Fill) y reconstruye los botones de la barra de herramientas que usaba como llamadas sobre el control.

4

Cargar el documento

Sustituye PdfDocument.Load y Document = por LoadFromFile, o carga tú mismo un TsgcPDFDocument y asígnalo a Document.

5

Hacer corresponder los miembros

Page pasa a ser PageIndex o GotoPage, los modos de zoom se corresponden con TsgcPDFViewerZoomMode, el factor de zoom se multiplica por 100, Search pasa a ser FindText, Render pasa a ser RenderPageToBitmap.

6

Conservar el código de impresión

Llama a CreatePrintDocument() en el visor en lugar de en el documento de PdfiumViewer; el código de PrintDialog y PrintPreviewDialog se mantiene. O usa PrintDialog(ATitle).

7

Activar las novedades

Opcional: FormFilling = true, AnnotationTool y SaveIncremental, que PdfiumViewer no podía ofrecer.

Lo que no se corresponde uno a uno

Lee esto antes de planificar el cambio.

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF y MigrateFromPdfiumViewer

Ambas demos generan sus propios archivos de entrada, así que no hace falta ningún PDF externo, y ambas tienen una autoprueba.

Delphi: dónde está

El instalador de sgcUI la coloca en Demos\PDF\Delphi\MigrateFromQuickPDF: sgcPDF_Demo_MigrateFromQuickPDF.dpr, frmMain.pas, frmMain.dfm y un readme.html.

Delphi: cómo ejecutarla

Abre el .dpr en cualquier Delphi de 7 a 13 (VCL, Win32 o Win64), haz clic en Generate sample inputs, y después en cualquier botón o en Run all. La salida va a la carpeta output junto al exe.

Delphi: autoprueba

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] ejecuta cada trabajo, comprueba los resultados y escribe selftest.log, que termina en SELFTEST OK.

.NET: dónde está

En las demos .NET de sgcUI, carpeta PDF\MigrateFromPdfiumViewer de la solución sgcUI_Demos.sln: sgcPDF_Demo_MigrateFromPdfiumViewer.csproj, Program.cs y MainForm.cs.

.NET: cómo ejecutarla

dotnet run --project demos\PDF\MigrateFromPdfiumViewer (añade -p:SgcCommunity=true para la edición Community), haz clic en Generate sample, que escribe y abre output\sample.pdf, y después en cualquier botón.

.NET: autoprueba

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] abre el ejemplo, navega, hace zoom, ajusta el alto, gira, busca, renderiza, cuenta las páginas de una vista previa de impresión, extrae texto, rellena el formulario, añade una nota y reabre los archivos guardados. Escribe selftest.log, que termina en SELFTEST OK.

Para ser justos con ambas bibliotecas: una aplicación construida sobre Quick PDF Library o PdfiumViewer sigue funcionando donde está desplegada hoy, y Foxit nombra sus propios SDK de PDF como sucesores de Quick PDF Library. sgcPDF es el camino cuando se quiere el código PDF en fuente Pascal o C# que se compila en tu aplicación, sin biblioteca PDF nativa que entregar, y una sola API que además crea, rellena, anota, firma y cifra los archivos que muestra tu visor. Para los componentes y las ediciones, vea la página de producto de sgcPDF.

La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

Porta hoy tu primer trabajo PDF

Descarga sgcUI con sgcPDF, o añade los paquetes Community gratuitos desde NuGet, y porta tu primer trabajo o formulario con las demos MigrateFromQuickPDF y MigrateFromPdfiumViewer al lado.