Quick PDF Library と PdfiumViewer から sgcPDF への移行

Foxit は 2021 年 12 月 13 日に Quick PDF Library を終了し、PdfiumViewer のリポジトリは 2019 年 8 月 2 日から読み取り専用になっています。sgcPDF は両方を置き換えます。Delphi の exe にコンパイルされる純粋な Pascal と、WinForms 向けのマネージド C# で、配布する PDF DLL はありません。このキットは、Quick PDF Library の関数と PdfiumViewer のクラスを sgcPDF に対応付け、コンパイルでき自己テストに合格する 2 つのサンプルのコードを示します。

更新されなくなった PDF ライブラリの上に作られたアプリケーション

よくある 2 つのケースです。Quick PDF Library で PDF ファイルを作成、結合、入力、レンダリングする Delphi アプリケーションと、PdfiumViewer で PDF ファイルを表示する WinForms アプリケーションです。

Quick PDF Library (Delphi) から

Quick PDF Library (Debenu Quick PDF Library、のちに Foxit Quick PDF Library) は、アンロックキー付きの DLL、ActiveX または LIB として提供され、ドキュメント、ページ、フォント、画像が「選択された」状態になる 1 つのオブジェクトで動作します。sgcPDF はオブジェクトモデルを備えた Pascal ユニットの集まりです。TsgcPDFDocument、TsgcPDFPage、TsgcPDFEditor、TsgcPDFAcroForm を、Delphi 7 から Delphi 13 まで利用できます。

PdfiumViewer (WinForms) から

PdfiumViewer はネイティブの PDFium ライブラリを PdfViewer コントロール、PdfRenderer、PdfDocument でラップしています。PDF ファイルの表示、検索、レンダリング、印刷ができます。sgcPDF はこれらを 1 つのマネージドコントロール TsgcPDFViewerControl に置き換え、PdfiumViewer にはなかった PDF ファイルの作成、フォームの入力、注釈の追加、変更の保存を加えます。

Quick PDF Library。 Foxit の通知 (2026-10-20 に確認) には、要旨として次のように書かれています。「2021 年 12 月 13 日から、Foxit は次の製品を終了します」。リストの最初の製品が Foxit Quick PDF Library (全プラットフォーム) です。有効な保守およびサポート契約のある顧客は 2022 年 12 月 13 日までサポートされました。「その日以降、製品はサポート終了となり、サポートは提供されなくなります。」Foxit が挙げる後継は、Windows、Mac、Linux、Android、iOS 向けの PDF SDK、ActiveX SDK、.NET SDK スイートです。

PdfiumViewer。 GitHub リポジトリ (2026-10-20 に確認) には、要旨として次のように表示されています。「このリポジトリは 2019 年 8 月 2 日にオーナーによってアーカイブされました。現在は読み取り専用です。」README には「長い間、これに本格的な時間を割くことができていません」、「このプロジェクトを適切にサポートできる状況にありません」とあります。さらに「PdfiumViewer コントロールにはネイティブの PDFium ライブラリが必要です。これらは PdfiumViewer の NuGet パッケージには含まれていません」とも書かれています。NuGet パッケージの最終更新は 2017 年 11 月 6 日 (バージョン 2.13.0) で、対象は net20 です。

1 つの PDF ライブラリ、ソースコード付き

sgcPDF は sgcUI の PDF 製品です。Delphi と .NET で PDF ファイルの作成、編集、入力、署名、暗号化、レンダリング、表示ができます。

配布する PDF DLL は不要

Delphi では sgcPDF のユニットが exe にコンパイルされるため、配布して登録する DLL、ActiveX、LIB はなく、アンロックキーの呼び出しもありません。.NET では sgcPDF はマネージド C# なので、pdfium.dll も、選択すべき x86 または x64 のネイティブパッケージもありません。サンプルは AnyCPU で動作します。

オブジェクトモデル

すべての呼び出しがページオブジェクトまたはインデックスを受け取るため、Quick PDF Library の「選択」状態はなくなります。面付けにはベクターのフォーム XObject (AddPageAsForm、DrawForm、DrawFormInRect) を使い、フォームには AcroForm を使い、暗号化は AES-256 (emAES_256) までサポートします。

編集できるビューア

TsgcPDFViewerControl は、幅、ページ、高さへのフィット、表示の回転、検索、ダイアログ付きの印刷に対応し、.NET では PdfiumViewer と同様に PrintDocument を返します。さらに、フォームフィールドの入力 (FormFilling)、マウスによる注釈の追加 (AnnotationTool)、テキストの選択もできます。サイドビューは TsgcPDFThumbnailView、TsgcPDFOutlineView、TsgcPDFCommentsView です。

sgcPDF は単体で販売されており、Delphi と C++ Builder の開発者 1 名向けは €249 から、.NET 向けは €249 からで、完全なソースコードと 1 年間のアップデートが付属します。sgcUI Enterprise と All-Access バンドルにも含まれます。.NET パッケージは、同じ機能を持つ無料の Community パッケージ esegece.sgcPDF.Community と esegece.sgcPDF.WinForms.Community として NuGet でも提供されています。sgcPDF 製品ページをご覧ください。

sgcPDF での Quick PDF Library の関数

ユニットは sgcPDF_Types、sgcPDF_Fonts、sgcPDF_Document で、必要に応じて sgcPDF_Editor、sgcPDF_Encryption、sgcPDF_Renderer_GDI、sgcPDF_Export を加えます。sgcPDF のページインデックスは 0 から始まります。

Quick PDF Library sgcPDF
UnlockKeyコードから呼び出すものはありません
NewDocumentTsgcPDFDocument.Create のあと AddPage (新しいドキュメントには、追加するまでページがありません)
NewPage, SetPageDimensions, SetPageSizeTsgcPDFDocument.AddPage(AWidth, AHeight): TsgcPDFPage, InsertPage(AIndex, AWidth, AHeight)
LoadFromFile, LoadFromStringTsgcPDFDocument.LoadFromFile, LoadFromStream, LoadFromBytes
パスワード付きの LoadFromFileLoadFromFile の前に TsgcPDFDocument.SetPassword(APassword)
SaveToFile, SaveToStringTsgcPDFDocument.SaveToFile, SaveToStream, SaveIncremental
PageCountTsgcPDFDocument.PageCount。ファイルだけの場合は sgcPDFGetPageCount(AFileName)
SelectPageTsgcPDFDocument.Pages[AIndex] (0 始まり、既定プロパティ)、GetPage(AIndex)
SetInformationTsgcPDFDocument.Info.Title, .Author, .Subject, .Keywords, .Creator, .Producer
AddStandardFont + SelectFont + SetTextSize + DrawTextTsgcPDFPage.DrawText(AText, X, Y, AFont, AFontSize) と TsgcPDFStandardFont (sfHelvetica、sfTimesRoman、sfCourier とそれぞれの太字と斜体)
SetTextColor + DrawTextTsgcPDFPage.DrawTextColor(AText, X, Y, AFont, AFontSize, R, G, B) (成分は 0 から 1)
AddTrueTypeFont + DrawTextTsgcPDFDocument.AddTrueTypeFont(AFontName, ABold, AItalic): Integer (または AddTrueTypeFontFromFile)、続いて 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)、または 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) ('1,3,5-9' のような 1 始まりの範囲文字列)、TsgcPDFEditor.ExtractPages(ARange, AOutputFileName)
DeletePagesTsgcPDFDocument.DeletePages(ARange), DeletePage(AIndex)
RotatePageTsgcPDFEditor.RotatePage(AIndex, ADegrees)
SetTransparency + DrawText (透かし)TsgcPDFEditor.AddWatermarkAllPages(TsgcPDFWatermarkOptions), AddWatermark, AddTransparentText
全ページへの DrawText (スタンプ、ヘッダー、フッター)TsgcPDFEditor.AddTextColor, AddHeaderText, AddFooterText, AddPageNumbers
RenderPageToDCTsgcPDFRendererGDI.RenderPage(ADC, ADocument.Parser, APage.PageDict, AWidth, AHeight)。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) と emAES_256、emAES_128、emRC4_128、emRC4_40 のいずれか
CapturePageTsgcPDFDocument.AddPageAsForm(ASource, APageIndex): Integer (ページボックス、矩形、注釈を指定するオーバーロードあり)
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)
PrintDocumentVCL ビューアの TsgcPDFViewerControl.Print(AFromPage, AToPage, ATitle) はダイアログなしで印刷し、PrintDialog(ATitle) はプリンターダイアログ (ページ範囲、部数) を表示して印刷します。FireMonkey ビューア TsgcPDFViewerFMX にも、Windows と macOS で同じ 2 つのメソッドがあります。
SetMeasurementUnits(0), SetOrigin(0)既定で唯一の座標系: ポイント単位、原点は左下。ヘルパーは sgcPDFMMToPoints、sgcPDFRectMM

Delphi のビューアにはほかにも、高さに合わせるズーム (TsgcPDFViewerControl の zmFitHeight、TsgcPDFViewerFMX の fzmFitHeight、TsgcPDFViewer の ZoomFitHeight) と、表示の回転 (ViewRotation、RotateLeft、RotateRight) があり、これらは表示だけを回転し、ドキュメントは変更しません。

sgcPDF での Quick PDF Library のよくある作業

すべての抜粋は MigrateFromQuickPDF デモからコピーしたもので、Delphi 7 (Win32) と Delphi 13 (Win32 と Win64) でコンパイルでき、自己テストに合格します。コメントには、各行が置き換える Quick PDF Library の呼び出しを記しています。

uses 句

Quick PDF Library のインポートユニットと DLL は不要になります。次のユニットでデモのすべての作業をまかなえます。

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;

テキスト、ボックス、画像を含むドキュメントを作成する

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

ページのテキストを抽出する

LoadFromFile、PageCount、SelectPage、GetPageText を置き換えます。ページインデックスが 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);

結合と分割

AddToFileList と MergeFileList、および ExtractPageRanges または ExtractFilePages を置き換えます。範囲文字列は 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');

全ページに透かしとスタンプを入れる

ページをループして SelectPage、SetTransparency、SetTextColor、DrawText を使っていた処理を置き換えます。

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

ページをデバイスコンテキストにレンダリングする

RenderPageToDC を置き換えます。レンダラーは、読み込んだドキュメントの Parser とページの PageDict を受け取ります。

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

フォームに入力する

FormFieldCount、FindFormFieldByTitle、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'));

AES-256 で暗号化し、パスワードで開く

Encrypt と、パスワード付きの LoadFromFile を置き換えます。

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

2-up 面付け

CapturePage、NewPage、SetPageDimensions、DrawCapturedPage を置き換えます。AddPageAsForm は各元ページをフォーム XObject として保持するため、テキストはベクターのまま選択できます。

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

sgcPDF での PdfiumViewer のクラス

名前空間は esegece.sgcPDF、パッケージは esegece.sgcPDF.WinForms です。ページインデックスはどちらのライブラリでも 0 始まりです。

PdfiumViewer sgcPDF .NET
PdfViewer (ツールバーとブックマークペインを持つ UserControl)TsgcPDFViewerControl。ツールバーは自作し、ブックマークは TsgcPDFOutlineView を使います
PdfRenderer (PdfViewer.Renderer)同じ TsgcPDFViewerControl
PdfViewer.Document = PdfDocument.Load(path)TsgcPDFViewerControl.LoadFromFile(path) (ビューアがドキュメントを所有)、LoadFromStream、または Document = vDoc (破棄は呼び出し側)
PdfDocument.Load(path, password)LoadFromFile の前に TsgcPDFDocument.SetPassword、続いて TsgcPDFViewerControl.Document = vDoc
PdfDocument.PageCountTsgcPDFViewerControl.PageCount (プロパティ)、TsgcPDFDocument.PageCount() (メソッド)
PdfDocument.PageSizesTsgcPDFDocument.GetPage(i).Width と .Height (ポイント単位)
PdfRenderer.PageTsgcPDFViewerControl.PageIndex、GotoPage、NextPage、PrevPage、FirstPage、LastPage、イベント OnPageChange
PdfViewerZoomMode.FitWidthZoomMode = TsgcPDFViewerZoomMode.zmFitWidth
PdfViewerZoomMode.FitHeightTsgcPDFViewerZoomMode.zmFitHeight
PdfViewerZoomMode.FitBestTsgcPDFViewerZoomMode.zmFitPage
Zoom (係数、1.0 = 100%)TsgcPDFViewerControl.Zoom (パーセント、100 = 100%、zmCustom を設定)、ZoomIn、ZoomOut、zmActualSize、ZoomToRect
PdfRenderer.RotateLeft(), RotateRight()TsgcPDFViewerControl.RotateLeft(), RotateRight()
PdfRenderer.RotationTsgcPDFViewerControl.ViewRotation (TsgcPDFViewerRotation: pvr0、pvr90、pvr180、pvr270)。PageRotation(i) は表示中の回転を返します
PdfDocument.Search(text, matchCase, wholeWord) + PdfRenderer.MarkersTsgcPDFViewerControl.FindText(AText, ACaseSensitive, AWholeWord) (ハイライトしてスクロール)、FindNext、FindPrevious、SearchResults、GetSearchMatch(i)、ClearSearch
PdfDocument.CreatePrintDocument() + PrintDialog または PrintPreviewDialogTsgcPDFViewerControl.CreatePrintDocument() は、同じ PrintDialog と PrintPreviewDialog のコード用に System.Drawing.Printing.PrintDocument を返します。1 回の呼び出しで行うには PrintDialog(ATitle)、ダイアログなしなら Print(AFromPage, AToPage, ATitle)
PdfDocument.Render(page, dpiX, dpiY, forPrinting)TsgcPDFViewerControl.RenderPageToBitmap(APageIndex, ref Bitmap, AZoomPercent, ADPI)。ビューアなしなら sgcPDF_Export.sgcPDFPageToImage または TsgcPDFExporter.ExportPage
PdfDocument.GetPdfText(page)TsgcPDFDocument.ExtractTextW(APageIndex)。文字位置つきなら TsgcPDFViewerControl.PageText(i)。マウス選択は SelectedText、CopyToClipboard
PdfDocument.BookmarksTsgcPDFOutlineView
PdfViewer.LinkClickTsgcPDFViewerControl.OnLinkClick, OpenLinksInBrowser
PdfDocument.Save(path)TsgcPDFDocument.SaveToFile、SaveIncremental(AFileName) (元のバイトを保持し、変更を追記)
同等機能なし: フォーム入力TsgcPDFViewerControl.FormFilling = true、OnFieldChange。コードでは AcroForm.FillField、SetCheckBox、GetFieldValue、FindField
同等機能なし: 注釈TsgcPDFDocument.Annotations.AddText、AddFreeText、AddHighlight、AddStamp、AddLine、AddSquare、AddCircle、続いて AnnotationsChanged()。マウスでは AnnotationTool と AnnotationEditing
同等機能なし: PDF の作成TsgcPDFDocument.AddPage, TsgcPDFPage.DrawText, DrawRectangle, AcroForm.AddTextField, AddCheckBox, SaveToFile

sgcPDF ビューアを使った PdfiumViewer のフォーム

すべての抜粋は MigrateFromPdfiumViewer デモからコピーしたもので、Release でコンパイルでき、自己テストに合格します。コメントには、各ブロックが置き換える PdfiumViewer のコードを引用しています。

PdfViewer と PdfRenderer の代わりに 1 つのコントロール

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

ファイルを開く

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

ズームモードと表示の回転

幅に合わせる、ページに合わせる、高さに合わせるは 1 対 1 で対応します。ズームは係数ではなくパーセントです。

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

検索

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;

CreatePrintDocument で印刷する

PdfiumViewer の印刷コードはそのままの形を保ちます。CreatePrintDocument() は、PrintDialog または PrintPreviewDialog 用の PrintDocument を返します。

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

ページをビットマップにレンダリングする

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

ページのテキスト

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;

PdfiumViewer の先へ: フォームに入力してメモを追加する

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

ステップバイステップ

作業 1 つ、またはフォーム 1 つずつ移行し、前後の出力ファイルを比較してください。

Delphi: Quick PDF Library から

1

ユニットを追加する

sgcPDF の Source フォルダーまたはインストール済みパッケージを追加し、Quick PDF Library のインポートを sgcPDF_Types、sgcPDF_Fonts、sgcPDF_Document に置き換えます。必要に応じて sgcPDF_Editor、sgcPDF_Encryption、sgcPDF_Renderer_GDI も加えます。

2

DLL を外す

配布物から DLL または ActiveX を外し、コードから UnlockKey の呼び出しを削除します。

3

ドキュメントごとに 1 つのオブジェクト

TQuickPDF オブジェクトを、ドキュメントごとの TsgcPDFDocument に置き換えます。読み込み、編集、保存の作業には TsgcPDFEditor を使います。

4

ページはオブジェクト

SelectPage と描画の呼び出しを、AddPage または Pages[i] から得た TsgcPDFPage への呼び出しに置き換え、すべてのページ番号から 1 を引きます。

5

呼び出しを対応付ける

上の表を使います。標準フォントは DrawText の引数です。TrueType フォントは AddTrueTypeFont で一度追加し、DrawTextTT で描画します。

6

面付け

CapturePage と DrawCapturedPage を、AddPageAsForm と、DrawForm または DrawFormInRect に置き換えます。

7

出力を比較する

変換した作業を実行し、ファイルを確認します。デモの自己テストがひな形になります。各出力を開き直して、ページ数、テキスト、フォームの値を確認します。

WinForms: PdfiumViewer から

1

ネイティブ部分を取り除く

PdfiumViewer パッケージ、すべての PdfiumViewer.Native.* パッケージ、手作業でコピーした pdfium.dll を、x86 と x64 のフォルダーも含めて削除します。プロジェクトは AnyCPU に戻せます。

2

sgcPDF を追加する

esegece.sgcPDF.WinForms (または esegece.sgcPDF.WinForms.Community) を追加すると esegece.sgcPDF も入ります。そして using esegece.sgcPDF; を追加します。

3

コントロールを差し替える

PdfViewer または PdfRenderer を TsgcPDFViewerControl (Dock = Fill) に置き換え、使っていたツールバーのボタンをコントロールへの呼び出しとして作り直します。

4

ドキュメントを読み込む

PdfDocument.Load と Document = を LoadFromFile に置き換えるか、自分で TsgcPDFDocument を読み込んで Document に代入します。

5

メンバーを対応付ける

Page は PageIndex または GotoPage になり、ズームモードは TsgcPDFViewerZoomMode に対応し、ズーム係数は 100 倍にし、Search は FindText に、Render は RenderPageToBitmap になります。

6

印刷コードを維持する

PdfiumViewer のドキュメントの代わりにビューアの CreatePrintDocument() を呼び出します。PrintDialog と PrintPreviewDialog のコードはそのままです。または PrintDialog(ATitle) を使います。

7

新しい機能を有効にする

必要に応じて、PdfiumViewer にはなかった FormFilling = true、AnnotationTool、SaveIncremental を使います。

1 対 1 で対応しないもの

移行を計画する前にお読みください。

Quick PDF Library

PdfiumViewer

MigrateFromQuickPDF と MigrateFromPdfiumViewer

どちらのデモも自前の入力ファイルを生成するため、外部の PDF は不要で、どちらにも自己テストがあります。

Delphi: 場所

sgcUI インストーラーは Demos\PDF\Delphi\MigrateFromQuickPDF に配置します。内容は sgcPDF_Demo_MigrateFromQuickPDF.dpr、frmMain.pas、frmMain.dfm、readme.html です。

Delphi: 実行方法

Delphi 7 から 13 の任意のバージョン (VCL、Win32 または Win64) で .dpr を開き、Generate sample inputs をクリックしてから、任意のボタンまたは Run all をクリックします。出力は exe の隣の output フォルダーに保存されます。

Delphi: 自己テスト

sgcPDF_Demo_MigrateFromQuickPDF.exe /selftest [folder] はすべての作業を実行して結果を確認し、selftest.log を書き出します。ログは SELFTEST OK で終わります。

.NET: 場所

sgcUI の .NET デモ内の、sgcUI_Demos.sln ソリューションのフォルダー PDF\MigrateFromPdfiumViewer にあります。内容は sgcPDF_Demo_MigrateFromPdfiumViewer.csproj、Program.cs、MainForm.cs です。

.NET: 実行方法

dotnet run --project demos\PDF\MigrateFromPdfiumViewer を実行し (Community エディションでは -p:SgcCommunity=true を追加)、Generate sample をクリックして output\sample.pdf を書き出して開き、続いて任意のボタンをクリックします。

.NET: 自己テスト

sgcPDF_Demo_MigrateFromPdfiumViewer.exe /selftest [folder] は、サンプルを開き、移動、ズーム、高さへのフィット、回転、検索、レンダリング、印刷プレビューのページ数のカウント、テキストの抽出、フォームの入力、メモの追加を行い、保存したファイルを開き直します。selftest.log を書き出し、SELFTEST OK で終わります。

両方のライブラリに公平を期すために述べると、Quick PDF Library または PdfiumViewer で作られたアプリケーションは、現在配布されている環境で動作し続けますし、Foxit は自社の PDF SDK を Quick PDF Library の後継として挙げています。sgcPDF は、アプリケーションにコンパイルされる Pascal または C# のソースとして PDF コードを持ちたく、配布するネイティブ PDF ライブラリは不要で、ビューアが表示するファイルの作成、入力、注釈、署名、暗号化も 1 つの API で行いたい場合の選択肢です。コンポーネントとエディションについては、sgcPDF 製品ページをご覧ください。

最もお得な選択: All-AccesseSeGeCe の全製品にプレミアムサポートが付いて、年間 €1,059 からご利用いただけます。
All-Access の価格を見る

最初の PDF 作業を今日から移植する

sgcPDF を含む sgcUI をダウンロードするか、NuGet の無料 Community パッケージを追加して、MigrateFromQuickPDF と MigrateFromPdfiumViewer のデモを参考に、最初の作業またはフォームを移植しましょう。