Migracja z Quick PDF Library i PdfiumViewer do sgcPDF

Foxit zakończył wsparcie dla Quick PDF Library 13 grudnia 2021, a repozytorium PdfiumViewer jest tylko do odczytu od 2 sierpnia 2019. sgcPDF zastępuje oba: czysty Pascal kompilowany do exe Delphi oraz zarządzany C# dla WinForms, bez biblioteki DLL do PDF do wdrożenia. Ten zestaw mapuje funkcje Quick PDF Library i klasy PdfiumViewer na sgcPDF, z kodem z dwóch przykładów, które się kompilują i przechodzą własne autotesty.

Aplikacje zbudowane na bibliotece PDF, która już się nie rozwija

Dwa typowe przypadki: aplikacja Delphi, która tworzy, scala, wypełnia i renderuje pliki PDF za pomocą Quick PDF Library, oraz aplikacja WinForms, która wyświetla pliki PDF za pomocą PdfiumViewer.

Z Quick PDF Library (Delphi)

Quick PDF Library (Debenu Quick PDF Library, później Foxit Quick PDF Library) jest dostarczana jako DLL, ActiveX lub LIB z kluczem odblokowującym i działa na jednym obiekcie z "wybranym" dokumentem, stroną, czcionką i obrazem. sgcPDF to zestaw jednostek Pascala z modelem obiektowym: TsgcPDFDocument, TsgcPDFPage, TsgcPDFEditor i TsgcPDFAcroForm, od Delphi 7 do Delphi 13.

Z PdfiumViewer (WinForms)

PdfiumViewer opakowuje natywną bibliotekę PDFium w kontrolkę PdfViewer, PdfRenderer i PdfDocument. Wyświetla, przeszukuje, renderuje i drukuje pliki PDF. sgcPDF zastępuje je jedną zarządzaną kontrolką, TsgcPDFViewerControl, i dodaje to, czego PdfiumViewer nigdy nie miał: tworzenie plików PDF, wypełnianie formularzy, dodawanie adnotacji i zapisywanie zmian.

Quick PDF Library. Komunikat Foxit (odczytany 2026-10-20) mówi: "Od 13 grudnia 2021 Foxit wycofuje następujące produkty", a pierwszym produktem na liście jest Foxit Quick PDF Library (All Platforms). Klienci z aktywną umową serwisową i wsparcia byli obsługiwani do 13 grudnia 2022: "Po tej dacie produkt przejdzie w stan końca wsparcia i nie będzie już wspierany." Zamienniki wskazane przez Foxit to jego pakiety PDF SDK dla Windows, Mac, Linux, Android i iOS, jego ActiveX SDK i jego zestaw .NET SDK.

PdfiumViewer. Repozytorium GitHub (odczytane 2026-10-20) pokazuje: "To repozytorium zostało zarchiwizowane przez właściciela 2 sierpnia 2019. Jest teraz tylko do odczytu." README wyjaśnia: "Od dawna nie mogę poświęcić temu projektowi prawdziwego czasu" oraz "Nie jestem w stanie należycie wspierać tego projektu." Dodaje też: "Kontrolka PdfiumViewer wymaga natywnych bibliotek PDFium. Nie są one dołączone do pakietu NuGet PdfiumViewer." Pakiet NuGet był ostatnio aktualizowany 6 listopada 2017 (wersja 2.13.0) i jest przeznaczony dla net20.

Jedna biblioteka PDF, w zestawie kod źródłowy

sgcPDF to produkt PDF z pakietu sgcUI. Tworzy, edytuje, wypełnia, podpisuje, szyfruje, renderuje i wyświetla pliki PDF w Delphi i w .NET.

Brak biblioteki DLL do PDF do wdrożenia

W Delphi jednostki sgcPDF kompilują się do exe: nie ma DLL, ActiveX ani LIB do wdrożenia i rejestracji, ani wywołania klucza odblokowującego. W .NET sgcPDF to zarządzany C#, więc nie ma pdfium.dll ani natywnego pakietu x86 lub x64 do wyboru: przykład działa jako AnyCPU.

Model obiektowy

Każde wywołanie przyjmuje obiekt strony lub indeks, więc stan "wybrany" z Quick PDF Library znika. Impozycja używa wektorowych obiektów form XObject (AddPageAsForm, DrawForm, DrawFormInRect), formularze używają AcroForm, a szyfrowanie sięga AES-256 (emAES_256).

Przeglądarka, która edytuje

TsgcPDFViewerControl dopasowuje widok do szerokości, strony lub wysokości, obraca widok, wyszukuje i drukuje z oknem dialogowym, a w .NET udostępnia PrintDocument tak jak PdfiumViewer. Wypełnia też pola formularzy (FormFilling), dodaje adnotacje myszą (AnnotationTool) i zaznacza tekst. Widoki boczne: TsgcPDFThumbnailView, TsgcPDFOutlineView, TsgcPDFCommentsView.

sgcPDF jest sprzedawany osobno, od €249 dla jednego programisty w Delphi i C++ Builder oraz od €249 dla .NET, z pełnym kodem źródłowym i 1 rokiem aktualizacji, a także wchodzi w skład sgcUI Enterprise i pakietu All-Access. Pakiety .NET są też dostępne jako bezpłatne pakiety Community w NuGet, esegece.sgcPDF.Community i esegece.sgcPDF.WinForms.Community, z tymi samymi funkcjami. Zobacz stronę produktu sgcPDF.

Funkcje Quick PDF Library w sgcPDF

Jednostki to sgcPDF_Types, sgcPDF_Fonts i sgcPDF_Document, a w razie potrzeby także sgcPDF_Editor, sgcPDF_Encryption, sgcPDF_Renderer_GDI i sgcPDF_Export. Indeksy stron w sgcPDF liczone są od 0.

Quick PDF Library sgcPDF
UnlockKeynic do wywołania w kodzie
NewDocumentTsgcPDFDocument.Create, a potem AddPage (nowy dokument nie ma strony, dopóki jej nie dodasz)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
LoadFromFile z hasłemTsgcPDFDocument.SetPassword(APassword) przed LoadFromFile
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount; tylko dla pliku: sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (od 0, właściwość domyślna), GetPage(AIndex)
SetInformationTsgcPDFDocument.Info.Title, .Author, .Subject, .Keywords, .Creator, .Producer
AddStandardFont + SelectFont + SetTextSize + DrawTextTsgcPDFPage.DrawText(AText, X, Y, AFont, AFontSize) z TsgcPDFStandardFont (sfHelvetica, sfTimesRoman, sfCourier oraz ich warianty pogrubione i pochylone)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (składowe od 0 do 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (lub AddTrueTypeFontFromFile), a potem 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), lub 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) (ciąg zakresu liczony od 1, np. '1,3,5-9'), TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (znak wodny)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
DrawText na każdej stronie (pieczątka, nagłówek, stopka)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight); w przeglądarce 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) z emAES_256, emAES_128, emRC4_128 lub emRC4_40
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (przeciążenia z ramką strony, prostokątem lub adnotacjami)
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)
PrintDocumentPrzeglądarka VCL TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) drukuje bez okna dialogowego, PrintDialog(ATitle) pokazuje okno drukarki (zakres stron, liczba kopii) i drukuje. Przeglądarka FireMonkey TsgcPDFViewerFMX ma te same dwie metody w systemach Windows i macOS.
SetMeasurementUnits(0), SetOrigin(0)domyślny i jedyny układ współrzędnych: punkty, początek w lewym dolnym rogu; pomocnicze sgcPDFMMToPoints, sgcPDFRectMM

Także w przeglądarkach Delphi: powiększenie do wysokości (zmFitHeight w TsgcPDFViewerControl, fzmFitHeight w TsgcPDFViewerFMX, ZoomFitHeight w TsgcPDFViewer) i obrót widoku (ViewRotation, RotateLeft, RotateRight), który obraca widok i pozostawia dokument bez zmian.

Typowe zadania Quick PDF Library w sgcPDF

Każdy fragment jest skopiowany z dema MigrateFromQuickPDF, które kompiluje się w Delphi 7 (Win32) i Delphi 13 (Win32 i Win64) oraz przechodzi własny autotest. Komentarze podają wywołania Quick PDF Library, które zastępuje każdy wiersz.

Klauzula uses

Jednostka importu Quick PDF Library i biblioteka DLL znikają. Te jednostki obejmują każde zadanie dema:

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;

Tworzenie dokumentu z tekstem, ramką i obrazem

Zastępuje NewDocument, SetInformation, AddStandardFont, SelectFont, SetTextSize, SetTextColor, DrawText, DrawBox, AddImageFromFile, SelectImage, DrawImage i 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;

Wyodrębnianie tekstu strony

Zastępuje LoadFromFile, PageCount, SelectPage i GetPageText. Zwróć uwagę na indeks strony liczony od 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);

Scalanie i dzielenie

Zastępuje AddToFileList z MergeFileList oraz ExtractPageRanges lub ExtractFilePages. Ciągi zakresów nadal liczone są od 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');

Znak wodny i pieczątka na każdej stronie

Zastępuje SelectPage, SetTransparency, SetTextColor i DrawText w pętli po stronach.

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

Renderowanie strony do kontekstu urządzenia

Zastępuje RenderPageToDC. Renderer przyjmuje Parser wczytanego dokumentu i PageDict strony.

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

Wypełnianie formularza

Zastępuje FormFieldCount, FindFormFieldByTitle i 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'));

Szyfrowanie AES-256 i otwieranie z hasłem

Zastępuje Encrypt oraz LoadFromFile z hasłem.

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

Impozycja 2-up

Zastępuje CapturePage, NewPage, SetPageDimensions i DrawCapturedPage. AddPageAsForm zachowuje każdą stronę źródłową jako form XObject, więc tekst pozostaje wektorowy i można go zaznaczać.

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

Klasy PdfiumViewer w sgcPDF

Przestrzeń nazw esegece.sgcPDF, pakiet esegece.sgcPDF.WinForms. Indeksy stron w obu bibliotekach liczone są od 0.

PdfiumViewer sgcPDF .NET
PdfViewer (UserControl z paskiem narzędzi i panelem zakładek)TsgcPDFViewerControl; własny pasek narzędzi, zakładki w TsgcPDFOutlineView
PdfRenderer (PdfViewer.Renderer)ten sam TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (przeglądarka jest właścicielem dokumentu), LoadFromStream lub Document = vDoc (zwalniasz go sam)
PdfDocument.Load(path, password)TsgcPDFDocument.SetPassword przed LoadFromFile, a potem TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (właściwość), TsgcPDFDocument.PageCount() (metoda)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width i .Height (punkty)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex, GotoPage, NextPage, PrevPage, FirstPage, LastPage, zdarzenie OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (współczynnik, 1.0 = 100%)TsgcPDFViewerControl.Zoom (wartość procentowa, 100 = 100%, ustawia zmCustom), ZoomIn, ZoomOut, zmActualSize, ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0, pvr90, pvr180, pvr270); PageRotation(i) zwraca wyświetlany obrót
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (podświetla i przewija), FindNext, FindPrevious, SearchResults, GetSearchMatch(i), ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog lub PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() zwraca System.Drawing.Printing.PrintDocument dla tego samego kodu PrintDialog i PrintPreviewDialog. Jednym wywołaniem: PrintDialog(ATitle); bez okna dialogowego: Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI); bez przeglądarki sgcPDF_Export.sgcPDFPageToImage lub TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex); z pozycjami znaków TsgcPDFViewerControl.PageText(i); zaznaczanie myszą SelectedText, CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile, SaveIncremental(AFileName) (zachowuje oryginalne bajty i dołącza zmiany)
brak odpowiednika: wypełnianie formularzyTsgcPDFViewerControl.FormFilling = true, OnFieldChange; w kodzie AcroForm.FillField, SetCheckBox, GetFieldValue, FindField
brak odpowiednika: adnotacjeTsgcPDFDocument.Annotations.AddText, AddFreeText, AddHighlight, AddStamp, AddLine, AddSquare, AddCircle, a potem AnnotationsChanged(); myszą AnnotationTool i AnnotationEditing
brak odpowiednika: tworzenie pliku PDFTsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

Formularz PdfiumViewer z przeglądarką sgcPDF

Każdy fragment jest skopiowany z dema MigrateFromPdfiumViewer, które kompiluje się w Release i przechodzi własny autotest. Komentarze cytują kod PdfiumViewer, który zastępuje każdy blok.

Jedna kontrolka zamiast PdfViewer i 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";

Otwieranie pliku

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

Tryby powiększenia i obrót widoku

Dopasowanie do szerokości, do strony i do wysokości odpowiadają sobie jeden do jednego. Powiększenie jest wartością procentową, a nie współczynnikiem.

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

Wyszukiwanie

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;

Drukowanie przez CreatePrintDocument

Kod drukowania PdfiumViewer zachowuje swój kształt: CreatePrintDocument() zwraca PrintDocument dla PrintDialog lub 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);
}

Renderowanie strony do bitmapy

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

Tekst strony

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;

Więcej niż PdfiumViewer: wypełnianie formularza i dodawanie notatki

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

Krok po kroku

Przenoś jedno zadanie lub jeden formularz naraz i porównuj pliki wynikowe przed i po.

Delphi: z Quick PDF Library

1

Dodaj jednostki

Dodaj folder Source sgcPDF lub zainstalowany pakiet i zastąp import Quick PDF Library jednostkami sgcPDF_Types, sgcPDF_Fonts i sgcPDF_Document, a w razie potrzeby także sgcPDF_Editor, sgcPDF_Encryption i sgcPDF_Renderer_GDI.

2

Usuń bibliotekę DLL

Usuń DLL lub ActiveX z wdrożenia oraz wywołanie UnlockKey z kodu.

3

Jeden obiekt na dokument

Zastąp obiekt TQuickPDF obiektem TsgcPDFDocument na dokument lub TsgcPDFEditor dla zadań wczytania, edycji i zapisu.

4

Strony są obiektami

Zastąp SelectPage i wywołania rysowania wywołaniami na TsgcPDFPage z AddPage lub Pages[i] i odejmij 1 od każdego numeru strony.

5

Zmapuj wywołania

Użyj tabeli powyżej. Czcionki standardowe są argumentem DrawText; czcionki TrueType dodaje się raz przez AddTrueTypeFont i rysuje przez DrawTextTT.

6

Impozycja

Zastąp CapturePage i DrawCapturedPage wywołaniami AddPageAsForm i DrawForm lub DrawFormInRect.

7

Porównaj wyniki

Uruchom przekonwertowane zadanie i sprawdź pliki. Autotest dema jest wzorcem: ponownie otwiera każdy plik wynikowy i sprawdza liczbę stron, tekst i wartości formularzy.

WinForms: z PdfiumViewer

1

Usuń części natywne

Usuń pakiet PdfiumViewer, każdy pakiet PdfiumViewer.Native.* oraz każdy ręcznie skopiowany plik pdfium.dll, razem z folderami x86 i x64. Projekt może wrócić do AnyCPU.

2

Dodaj sgcPDF

Dodaj esegece.sgcPDF.WinForms (lub esegece.sgcPDF.WinForms.Community), który wciąga esegece.sgcPDF, i dodaj using esegece.sgcPDF;.

3

Wymień kontrolkę

Zastąp PdfViewer lub PdfRenderer kontrolką TsgcPDFViewerControl (Dock = Fill) i odtwórz używane przyciski paska narzędzi jako wywołania na kontrolce.

4

Wczytaj dokument

Zastąp PdfDocument.Load i Document = wywołaniem LoadFromFile albo sam wczytaj TsgcPDFDocument i przypisz go do Document.

5

Zmapuj składowe

Page staje się PageIndex lub GotoPage, tryby powiększenia odpowiadają TsgcPDFViewerZoomMode, współczynnik powiększenia mnoży się przez 100, Search staje się FindText, a Render staje się RenderPageToBitmap.

6

Zachowaj kod drukowania

Wywołaj CreatePrintDocument() na przeglądarce zamiast na dokumencie PdfiumViewer; kod PrintDialog i PrintPreviewDialog pozostaje. Albo użyj PrintDialog(ATitle).

7

Włącz nowe możliwości

Opcjonalnie: FormFilling = true, AnnotationTool i SaveIncremental, czego PdfiumViewer nie oferował.

Co nie odwzorowuje się jeden do jednego

Przeczytaj to, zanim zaplanujesz przejście.

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF i MigrateFromPdfiumViewer

Oba dema generują własne pliki wejściowe, więc nie potrzeba zewnętrznego pliku PDF, i oba mają autotest.

Delphi: gdzie to jest

Instalator sgcUI umieszcza je w Demos\PDF\Delphi\MigrateFromQuickPDF: sgcPDF_Demo_MigrateFromQuickPDF.dpr, frmMain.pas, frmMain.dfm i readme.html.

Delphi: jak uruchomić

Otwórz .dpr w dowolnym Delphi od 7 do 13 (VCL, Win32 lub Win64), kliknij Generate sample inputs, a potem dowolny przycisk lub Run all. Wynik trafia do folderu output obok exe.

Delphi: autotest

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] uruchamia każde zadanie, sprawdza wyniki i zapisuje selftest.log, który kończy się na SELFTEST OK.

.NET: gdzie to jest

W demach .NET sgcUI, folder PDF\MigrateFromPdfiumViewer rozwiązania sgcUI_Demos.sln: sgcPDF_Demo_MigrateFromPdfiumViewer.csproj, Program.cs i MainForm.cs.

.NET: jak uruchomić

dotnet run --project demos\PDF\MigrateFromPdfiumViewer (dodaj -p:SgcCommunity=true dla edycji Community), kliknij Generate sample, co zapisuje i otwiera output\sample.pdf, a potem dowolny przycisk.

.NET: autotest

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] otwiera przykład, nawiguje, powiększa, dopasowuje wysokość, obraca, wyszukuje, renderuje, liczy strony podglądu wydruku, wyodrębnia tekst, wypełnia formularz, dodaje notatkę i ponownie otwiera zapisane pliki. Zapisuje selftest.log kończący się na SELFTEST OK.

Żeby być uczciwym wobec obu bibliotek: aplikacja zbudowana na Quick PDF Library lub PdfiumViewer nadal działa tam, gdzie jest dziś wdrożona, a Foxit wskazuje własne pakiety PDF SDK jako następców Quick PDF Library. sgcPDF jest drogą, gdy chcesz mieć kod PDF w źródłach Pascala lub C# kompilowanych do aplikacji, bez natywnej biblioteki PDF do wdrożenia, oraz jedno API, które także tworzy, wypełnia, opisuje adnotacjami, podpisuje i szyfruje pliki pokazywane przez przeglądarkę. Komponenty i edycje opisuje strona produktu sgcPDF.

Najkorzystniejsza oferta: All-AccessWszystkie produkty eSeGeCe, ze wsparciem Premium w cenie, już od €1,059 rocznie.
Zobacz cennik All-Access

Przenieś swoje pierwsze zadanie PDF już dziś

Pobierz sgcUI z sgcPDF lub dodaj bezpłatne pakiety Community z NuGet i przenieś pierwsze zadanie albo formularz z pomocą dem MigrateFromQuickPDF i MigrateFromPdfiumViewer obok.