Migrar do Quick PDF Library e do PdfiumViewer para o sgcPDF

A Foxit descontinuou o Quick PDF Library em 13 de dezembro de 2021, e o repositório do PdfiumViewer é somente leitura desde 2 de agosto de 2019. O sgcPDF substitui os dois: Pascal puro compilado no seu exe Delphi, e C# gerenciado para WinForms, sem DLL de PDF para distribuir. Este kit mapeia as funções do Quick PDF Library e as classes do PdfiumViewer para o sgcPDF, com código de dois exemplos que compilam e passam no próprio autoteste.

Aplicativos construídos sobre uma biblioteca PDF que não evolui mais

Dois casos comuns: um aplicativo Delphi que cria, mescla, preenche e renderiza arquivos PDF com o Quick PDF Library, e um aplicativo WinForms que exibe arquivos PDF com o PdfiumViewer.

Do Quick PDF Library (Delphi)

O Quick PDF Library (Debenu Quick PDF Library, depois Foxit Quick PDF Library) é entregue como DLL, ActiveX ou LIB com uma chave de desbloqueio, e trabalha com um único objeto em que um documento, uma página, uma fonte e uma imagem ficam "selecionados". O sgcPDF é um conjunto de units Pascal com um modelo de objetos: TsgcPDFDocument, TsgcPDFPage, TsgcPDFEditor e TsgcPDFAcroForm, do Delphi 7 ao Delphi 13.

Do PdfiumViewer (WinForms)

O PdfiumViewer encapsula a biblioteca nativa PDFium em um controle PdfViewer, um PdfRenderer e um PdfDocument. Ele exibe, pesquisa, renderiza e imprime arquivos PDF. O sgcPDF os substitui por um único controle gerenciado, TsgcPDFViewerControl, e acrescenta o que o PdfiumViewer nunca teve: criar arquivos PDF, preencher formulários, adicionar anotações e salvar alterações.

Quick PDF Library. O aviso da Foxit (lido em 20/10/2026) diz em essência: "A partir de 13 de dezembro de 2021, a Foxit descontinuará os seguintes produtos", e o primeiro produto da lista é o Foxit Quick PDF Library (todas as plataformas). Clientes com contratos ativos de manutenção e suporte tiveram suporte até 13 de dezembro de 2022: "Após essa data, o produto entrará em fim de suporte e você não terá mais suporte." Os substitutos que a Foxit indica são seus SDKs de PDF para Windows, Mac, Linux, Android e iOS, seu SDK ActiveX e sua suíte de SDKs .NET.

PdfiumViewer. O repositório no GitHub (lido em 20/10/2026) mostra em essência: "Este repositório foi arquivado pelo proprietário em 2 de ago. de 2019. Agora é somente leitura." O README explica: "Há muito tempo não consigo dedicar tempo real a isto", e "Não estou em condições de dar suporte adequado a este projeto." Também diz: "O controle PdfiumViewer requer bibliotecas nativas do PDFium. Elas não estão incluídas no pacote NuGet do PdfiumViewer." O pacote NuGet foi atualizado pela última vez em 06/11/2017 (versão 2.13.0) e tem como alvo net20.

Uma biblioteca PDF, código-fonte incluído

O sgcPDF é o produto PDF do sgcUI. Ele cria, edita, preenche, assina, criptografa, renderiza e exibe arquivos PDF no Delphi e no .NET.

Nenhuma DLL de PDF para distribuir

No Delphi, as units do sgcPDF são compiladas no exe: sem DLL, ActiveX ou LIB para distribuir e registrar, e sem chamada de chave de desbloqueio. No .NET, o sgcPDF é C# gerenciado, então não há pdfium.dll nem pacote nativo x86 ou x64 para escolher: o exemplo roda como AnyCPU.

Um modelo de objetos

Cada chamada recebe o objeto de página ou o índice, então o estado "selecionado" do Quick PDF Library desaparece. A imposição usa XObjects de formulário vetoriais (AddPageAsForm, DrawForm, DrawFormInRect), os formulários usam AcroForm, e a criptografia vai até AES-256 (emAES_256).

Um visualizador que edita

O TsgcPDFViewerControl ajusta a exibição à largura, à página ou à altura, gira a exibição, pesquisa e imprime com uma caixa de diálogo, e no .NET entrega um PrintDocument como o PdfiumViewer. Ele também preenche campos de formulário (FormFilling), adiciona anotações com o mouse (AnnotationTool) e seleciona texto. Exibições laterais: TsgcPDFThumbnailView, TsgcPDFOutlineView, TsgcPDFCommentsView.

O sgcPDF é vendido separadamente, a partir de €249 para um único desenvolvedor em Delphi e C++ Builder e a partir de €249 para .NET, com código-fonte completo e 1 ano de atualizações, e faz parte do sgcUI Enterprise e do pacote All-Access. Os pacotes .NET também são publicados como pacotes Community gratuitos no NuGet, esegece.sgcPDF.Community e esegece.sgcPDF.WinForms.Community, com os mesmos recursos. Veja a página do produto sgcPDF.

Funções do Quick PDF Library no sgcPDF

As units são sgcPDF_Types, sgcPDF_Fonts e sgcPDF_Document, mais sgcPDF_Editor, sgcPDF_Encryption, sgcPDF_Renderer_GDI e sgcPDF_Export quando necessário. Os índices de página do sgcPDF começam em 0.

Quick PDF Library sgcPDF
UnlockKeynada a chamar no código
NewDocumentTsgcPDFDocument.Create, depois AddPage (um documento novo não tem página até você adicionar uma)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
LoadFromFile com senhaTsgcPDFDocument.SetPassword(APassword) antes de LoadFromFile
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount; somente para um arquivo, sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (base 0, propriedade padrão), GetPage(AIndex)
SetInformationTsgcPDFDocument.Info.Title, .Author, .Subject, .Keywords, .Creator, .Producer
AddStandardFont + SelectFont + SetTextSize + DrawTextTsgcPDFPage.DrawText(AText, X, Y, AFont, AFontSize) com um TsgcPDFStandardFont (sfHelvetica, sfTimesRoman, sfCourier e suas variantes em negrito e itálico)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (componentes de 0 a 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (ou AddTrueTypeFontFromFile), depois 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), ou 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) (string de intervalo em base 1 como '1,3,5-9'), TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (marca d'água)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
DrawText em cada página (carimbo, cabeçalho, rodapé)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight); no visualizador 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) com emAES_256, emAES_128, emRC4_128 ou emRC4_40
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (sobrecargas com uma caixa de página, um retângulo ou anotações)
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)
PrintDocumentO visualizador VCL TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) imprime sem caixa de diálogo, PrintDialog(ATitle) mostra a caixa de diálogo da impressora (intervalo de páginas, cópias) e imprime. O visualizador FireMonkey TsgcPDFViewerFMX tem os mesmos dois métodos no Windows e no macOS.
SetMeasurementUnits(0), SetOrigin(0)o sistema de coordenadas padrão e único: pontos, origem no canto inferior esquerdo; auxiliares sgcPDFMMToPoints, sgcPDFRectMM

Também nos visualizadores Delphi: zoom de ajuste à altura (zmFitHeight em TsgcPDFViewerControl, fzmFitHeight em TsgcPDFViewerFMX, ZoomFitHeight em TsgcPDFViewer) e rotação da exibição (ViewRotation, RotateLeft, RotateRight), que gira a exibição e deixa o documento inalterado.

Os trabalhos comuns do Quick PDF Library no sgcPDF

Cada trecho é copiado da demo MigrateFromQuickPDF, que compila com Delphi 7 (Win32) e Delphi 13 (Win32 e Win64) e passa no próprio autoteste. Os comentários citam as chamadas do Quick PDF Library que cada linha substitui.

A cláusula uses

A unit de importação do Quick PDF Library e a DLL deixam de existir. Estas units cobrem todos os trabalhos da 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;

Criar um documento com texto, uma caixa e uma imagem

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

Extrair o texto de uma página

Substitui LoadFromFile, PageCount, SelectPage e GetPageText. Observe o índice de página em 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);

Mesclar e dividir

Substitui AddToFileList com MergeFileList, e ExtractPageRanges ou ExtractFilePages. As strings de intervalo continuam em 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 d'água e carimbo em cada página

Substitui SelectPage, SetTransparency, SetTextColor e DrawText em um laço sobre as 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 uma página em um contexto de dispositivo

Substitui RenderPageToDC. O renderizador recebe o Parser do documento carregado e o PageDict da 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'));

Preencher um formulário

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

Criptografar com AES-256 e abrir com a senha

Substitui Encrypt, e LoadFromFile com senha.

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

Imposição 2-up

Substitui CapturePage, NewPage, SetPageDimensions e DrawCapturedPage. AddPageAsForm mantém cada página de origem como XObject de formulário, então o texto continua vetorial e selecionável.

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

Classes do PdfiumViewer no sgcPDF

Namespace esegece.sgcPDF, pacote esegece.sgcPDF.WinForms. Os índices de página são de base 0 nas duas bibliotecas.

PdfiumViewer sgcPDF .NET
PdfViewer (UserControl com uma barra de ferramentas e um painel de marcadores)TsgcPDFViewerControl; crie sua própria barra de ferramentas, marcadores em TsgcPDFOutlineView
PdfRenderer (PdfViewer.Renderer)o mesmo TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (o visualizador é dono do documento), LoadFromStream, ou Document = vDoc (você o libera)
PdfDocument.Load(path, password)TsgcPDFDocument.SetPassword antes de LoadFromFile, depois TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (propriedade), TsgcPDFDocument.PageCount() (método)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width e .Height (pontos)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex, GotoPage, NextPage, PrevPage, FirstPage, LastPage, evento OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (um fator, 1.0 = 100%)TsgcPDFViewerControl.Zoom (uma porcentagem, 100 = 100%, define zmCustom), ZoomIn, ZoomOut, zmActualSize, ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0, pvr90, pvr180, pvr270); PageRotation(i) retorna a rotação exibida
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (destaca e rola), FindNext, FindPrevious, SearchResults, GetSearchMatch(i), ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog ou PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() retorna um System.Drawing.Printing.PrintDocument para os mesmos PrintDialog e PrintPreviewDialog. Em uma única chamada: PrintDialog(ATitle); sem caixa de diálogo: Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI); sem visualizador sgcPDF_Export.sgcPDFPageToImage or TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex); com posições de caracteres TsgcPDFViewerControl.PageText(i); seleção com o mouse SelectedText, CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile, SaveIncremental(AFileName) (mantém os bytes originais e acrescenta as alterações)
sem equivalente: preenchimento de formuláriosTsgcPDFViewerControl.FormFilling = true, OnFieldChange; no código AcroForm.FillField, SetCheckBox, GetFieldValue, FindField
sem equivalente: anotaçõesTsgcPDFDocument.Annotations.AddText, AddFreeText, AddHighlight, AddStamp, AddLine, AddSquare, AddCircle, depois AnnotationsChanged(); com o mouse AnnotationTool e AnnotationEditing
sem equivalente: criar um PDFTsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

Um formulário PdfiumViewer com o visualizador sgcPDF

Cada trecho é copiado da demo MigrateFromPdfiumViewer, que compila em Release e passa no próprio autoteste. Os comentários citam o código do PdfiumViewer que cada bloco substitui.

Um controle no lugar de 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";

Abrir um arquivo

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 e rotação da exibição

Ajustar à largura, à página e à altura correspondem um a um. O zoom é uma porcentagem em vez de um fator.

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

Pesquisa

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 com CreatePrintDocument

O código de impressão do PdfiumViewer mantém a forma: CreatePrintDocument() retorna um PrintDocument para um PrintDialog ou um 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 uma página em um 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);

Texto da 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;

Além do PdfiumViewer: preencher um formulário e adicionar uma 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 a passo

Porte um trabalho ou um formulário de cada vez, e compare os arquivos de saída antes e depois.

Delphi: do Quick PDF Library

1

Adicionar as units

Adicione a pasta Source do sgcPDF ou o pacote instalado, e substitua a importação do Quick PDF Library por sgcPDF_Types, sgcPDF_Fonts e sgcPDF_Document, mais sgcPDF_Editor, sgcPDF_Encryption e sgcPDF_Renderer_GDI quando necessário.

2

Remover a DLL

Remova a DLL ou o ActiveX da distribuição e a chamada UnlockKey do código.

3

Um objeto por documento

Substitua o objeto TQuickPDF por um TsgcPDFDocument por documento, ou um TsgcPDFEditor para trabalhos de carregar, editar e salvar.

4

As páginas são objetos

Substitua SelectPage e as chamadas de desenho por chamadas no TsgcPDFPage obtido de AddPage ou Pages[i], e subtraia 1 de cada número de página.

5

Mapear as chamadas

Use a tabela acima. As fontes padrão são um argumento de DrawText; as fontes TrueType são adicionadas uma vez com AddTrueTypeFont e desenhadas com DrawTextTT.

6

Imposição

Substitua CapturePage e DrawCapturedPage por AddPageAsForm e DrawForm ou DrawFormInRect.

7

Comparar a saída

Execute o trabalho convertido e confira os arquivos. O autoteste da demo serve de modelo: ele reabre cada saída e confere o número de páginas, o texto e os valores do formulário.

WinForms: do PdfiumViewer

1

Remover as partes nativas

Remova o pacote PdfiumViewer, todo pacote PdfiumViewer.Native.* e qualquer pdfium.dll copiada à mão, incluindo as pastas x86 e x64. O projeto pode voltar para AnyCPU.

2

Adicionar o sgcPDF

Adicione esegece.sgcPDF.WinForms (ou esegece.sgcPDF.WinForms.Community), que traz o esegece.sgcPDF, e adicione using esegece.sgcPDF;.

3

Trocar o controle

Substitua o PdfViewer ou o PdfRenderer por um TsgcPDFViewerControl (Dock = Fill) e recrie os botões da barra de ferramentas que você usava como chamadas no controle.

4

Carregar o documento

Substitua PdfDocument.Load e Document = por LoadFromFile, ou carregue você mesmo um TsgcPDFDocument e atribua-o a Document.

5

Mapear os membros

Page passa a ser PageIndex ou GotoPage, os modos de zoom correspondem a TsgcPDFViewerZoomMode, o fator de zoom é multiplicado por 100, Search passa a ser FindText, Render passa a ser RenderPageToBitmap.

6

Manter o código de impressão

Chame CreatePrintDocument() no visualizador em vez de no documento do PdfiumViewer; o código com PrintDialog e PrintPreviewDialog permanece. Ou use PrintDialog(ATitle).

7

Ativar as novidades

Opcional: FormFilling = true, AnnotationTool e SaveIncremental, que o PdfiumViewer não podia oferecer.

O que não se mapeia um a um

Leia isto antes de planejar a migração.

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF e MigrateFromPdfiumViewer

As duas demos geram seus próprios arquivos de entrada, então nenhum PDF externo é necessário, e as duas têm um autoteste.

Delphi: onde está

O instalador do sgcUI a coloca em Demos\PDF\Delphi\MigrateFromQuickPDF: sgcPDF_Demo_MigrateFromQuickPDF.dpr, frmMain.pas, frmMain.dfm e um readme.html.

Delphi: como executar

Abra o .dpr em qualquer Delphi de 7 a 13 (VCL, Win32 ou Win64), clique em Generate sample inputs, depois em qualquer botão ou em Run all. A saída vai para a pasta output ao lado do exe.

Delphi: autoteste

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] executa cada trabalho, confere os resultados e grava selftest.log, que termina com SELFTEST OK.

.NET: onde está

Nas demos .NET do sgcUI, pasta PDF\MigrateFromPdfiumViewer da solução sgcUI_Demos.sln: sgcPDF_Demo_MigrateFromPdfiumViewer.csproj, Program.cs e MainForm.cs.

.NET: como executar

dotnet run --project demos\PDF\MigrateFromPdfiumViewer (adicione -p:SgcCommunity=true para a edição Community), clique em Generate sample, que grava e abre output\sample.pdf, depois em qualquer botão.

.NET: autoteste

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] abre o exemplo, navega, aplica zoom, ajusta a altura, gira, pesquisa, renderiza, conta as páginas de uma visualização de impressão, extrai texto, preenche o formulário, adiciona uma nota e reabre os arquivos salvos. Ele grava selftest.log, que termina com SELFTEST OK.

Para ser justo com as duas bibliotecas: um aplicativo construído sobre o Quick PDF Library ou o PdfiumViewer continua funcionando onde está distribuído hoje, e a Foxit indica os próprios SDKs de PDF como sucessores do Quick PDF Library. O sgcPDF é o caminho quando você quer o código PDF em fonte Pascal ou C# compilado no seu aplicativo, sem biblioteca PDF nativa para distribuir, e uma única API que também cria, preenche, anota, assina e criptografa os arquivos que o seu visualizador exibe. Para os componentes e as edições, veja a página do produto sgcPDF.

Melhor custo-benefício: All-AccessTodos os produtos da eSeGeCe, com Suporte Premium incluído, a partir de €1,059/ano.
Ver preços do All-Access

Porte hoje o seu primeiro trabalho de PDF

Baixe o sgcUI com o sgcPDF, ou adicione os pacotes Community gratuitos do NuGet, e porte o seu primeiro trabalho ou formulário com as demos MigrateFromQuickPDF e MigrateFromPdfiumViewer ao lado.