// ===========================================================================
// ©2013-2026 WebSupergoo. All rights reserved.
//
// This source code is for use exclusively with the ABCpdf product with
// which it is distributed, under the terms of the license for that
// product. Details can be found at
//
// http://www.websupergoo.com/
//
// This copyright notice must not be deleted and must be reproduced alongside
// any sections of code extracted from this module.
// ===========================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using SD = System.Drawing;
using SD2 = System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using WebSupergoo.ABCpdf14;
using WebSupergoo.ABCpdf14.Atoms;
using WebSupergoo.ABCpdf14.Objects;
namespace WebSupergoo.PDFSurgeon
{
/// <summary>
/// Summary description for MainForm.
/// </summary>
public class MainForm : System.Windows.Forms.Form {
private Doc _doc;
private Navigator _nav;
private string _filePath;
private string _tempPath;
private List<TemporaryFile> _tempFiles;
private bool _dirty;
private ObjectExtractor _selectedExtractor;
private GraphicsScanner.Graphics _graphics;
private GraphicsScanner.Fixture _fixture;
public Dictionary<ObjectExtractor, EditText> _editTexts;
private Find _findDialog;
private ListView lst;
private OpenFileDialog dlgOpenFile;
private FontDialog dlgSelectFont;
private SplitContainer split;
private ColumnHeader cheaderID;
private ColumnHeader cheaderType;
private ColumnHeader cheaderName;
private ColumnHeader cheaderInfo1;
private ColumnHeader cheaderInfo2;
private TabControl tabInfo;
private TabPage pageAtom;
private TabPage pageContent;
private RichTextBox txtContent;
private TabPage pageImage;
private PictureBox pict;
private MenuStrip mstrip;
private ToolStripMenuItem mitemFile;
private ToolStripMenuItem mitemOpen;
private ToolStripSeparator mitemSep1;
private ToolStripMenuItem mitemExit;
private ImageList imglist;
private Panel pnlPicture;
private ContextMenuStrip cmenuIndirectObject;
private ToolStripMenuItem mitemDecompress;
private ToolStripMenuItem mItemMakeAscii85;
private ToolStripMenuItem mItemCompressFlate;
private ToolStripMenuItem mItemCompressJpeg75;
private ToolStripMenuItem mItemCompressJpeg50;
private ToolStripMenuItem mItemCompressJpeg25;
private ToolStripMenuItem mitemSaveAs;
private ToolStripMenuItem mitemSave;
private SaveFileDialog dlgSaveFile;
private ToolStripMenuItem mItemEdit;
private ToolStripMenuItem mItemRefresh;
private ToolStripMenuItem mItemMakeAsciiHex;
private ToolStripMenuItem editToolStripMenuItem;
private ToolStripMenuItem findToolStripMenuItem;
private ToolStripMenuItem selectAllToolStripMenuItem;
private ToolStripMenuItem viewToolStripMenuItem;
private ToolStripMenuItem showAllToolStripMenuItem;
private ToolStripMenuItem selectedToolStripMenuItem;
private ToolStripMenuItem unselectedToolStripMenuItem;
private ToolStripMenuItem compactToolStripMenuItem;
private ToolStripMenuItem saveImageToolStripMenuItem;
private SaveFileDialog dlgSaveImage;
private ToolStripMenuItem realizeToolStripMenuItem;
private ToolStripMenuItem flattenToolStripMenuItem;
private ToolStripMenuItem mItemFlattenFormXObjects;
private ToolStripMenuItem mItemExtract;
private ToolStripSeparator toolStripSeparator1;
private ToolStripMenuItem overprintToolStripMenuItem;
private ToolStripMenuItem mitemSaveAll;
private FolderBrowserDialog dlgSaveFolder;
private ToolStripMenuItem openInAcrobatToolStripMenuItem;
private TreeView atomTree;
private ToolStripMenuItem toolStripBack;
private ToolStripMenuItem toolStripForward;
private ToolTip toolTip1;
private Timer timer1;
private ToolStripMenuItem exportToolStripMenuItem;
private SaveFileDialog dlgExportFile;
private IContainer components;
public MainForm() {
//
// Required for Windows Form Designer support
//
InitializeComponent();
lst.ListViewItemSorter = new ListViewItemComparer();
Clear();
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1) {
try {
Open(args[1]);
}
catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing) {
if (disposing) {
Clear();
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.dlgOpenFile = new System.Windows.Forms.OpenFileDialog();
this.dlgSelectFont = new System.Windows.Forms.FontDialog();
this.split = new System.Windows.Forms.SplitContainer();
this.lst = new System.Windows.Forms.ListView();
this.cheaderID = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cheaderType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cheaderName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cheaderInfo1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cheaderInfo2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.cmenuIndirectObject = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mitemDecompress = new System.Windows.Forms.ToolStripMenuItem();
this.mItemMakeAscii85 = new System.Windows.Forms.ToolStripMenuItem();
this.mItemMakeAsciiHex = new System.Windows.Forms.ToolStripMenuItem();
this.mItemCompressFlate = new System.Windows.Forms.ToolStripMenuItem();
this.mItemCompressJpeg75 = new System.Windows.Forms.ToolStripMenuItem();
this.mItemCompressJpeg50 = new System.Windows.Forms.ToolStripMenuItem();
this.mItemCompressJpeg25 = new System.Windows.Forms.ToolStripMenuItem();
this.flattenToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mItemFlattenFormXObjects = new System.Windows.Forms.ToolStripMenuItem();
this.realizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveImageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mItemRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mItemEdit = new System.Windows.Forms.ToolStripMenuItem();
this.mItemExtract = new System.Windows.Forms.ToolStripMenuItem();
this.tabInfo = new System.Windows.Forms.TabControl();
this.pageImage = new System.Windows.Forms.TabPage();
this.pnlPicture = new System.Windows.Forms.Panel();
this.pict = new System.Windows.Forms.PictureBox();
this.pageAtom = new System.Windows.Forms.TabPage();
this.atomTree = new System.Windows.Forms.TreeView();
this.pageContent = new System.Windows.Forms.TabPage();
this.txtContent = new System.Windows.Forms.RichTextBox();
this.imglist = new System.Windows.Forms.ImageList(this.components);
this.mstrip = new System.Windows.Forms.MenuStrip();
this.mitemFile = new System.Windows.Forms.ToolStripMenuItem();
this.mitemOpen = new System.Windows.Forms.ToolStripMenuItem();
this.mitemSave = new System.Windows.Forms.ToolStripMenuItem();
this.mitemSaveAs = new System.Windows.Forms.ToolStripMenuItem();
this.mitemSaveAll = new System.Windows.Forms.ToolStripMenuItem();
this.mitemSep1 = new System.Windows.Forms.ToolStripSeparator();
this.mitemExit = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.compactToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.selectedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.unselectedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.overprintToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openInAcrobatToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripBack = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripForward = new System.Windows.Forms.ToolStripMenuItem();
this.dlgSaveFile = new System.Windows.Forms.SaveFileDialog();
this.dlgSaveImage = new System.Windows.Forms.SaveFileDialog();
this.dlgSaveFolder = new System.Windows.Forms.FolderBrowserDialog();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.dlgExportFile = new System.Windows.Forms.SaveFileDialog();
((System.ComponentModel.ISupportInitialize)(this.split)).BeginInit();
this.split.Panel1.SuspendLayout();
this.split.Panel2.SuspendLayout();
this.split.SuspendLayout();
this.cmenuIndirectObject.SuspendLayout();
this.tabInfo.SuspendLayout();
this.pageImage.SuspendLayout();
this.pnlPicture.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pict)).BeginInit();
this.pageAtom.SuspendLayout();
this.pageContent.SuspendLayout();
this.mstrip.SuspendLayout();
this.SuspendLayout();
//
// dlgOpenFile
//
this.dlgOpenFile.DefaultExt = "pdf";
this.dlgOpenFile.Filter = "PDF Document (*.pdf)|*.pdf";
this.dlgOpenFile.Title = "Open a PDF Document";
//
// split
//
this.split.Dock = System.Windows.Forms.DockStyle.Fill;
this.split.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
this.split.Location = new System.Drawing.Point(0, 33);
this.split.Name = "split";
//
// split.Panel1
//
this.split.Panel1.Controls.Add(this.lst);
//
// split.Panel2
//
this.split.Panel2.Controls.Add(this.tabInfo);
this.split.Size = new System.Drawing.Size(778, 511);
this.split.SplitterDistance = 455;
this.split.TabIndex = 3;
//
// lst
//
this.lst.AllowDrop = true;
this.lst.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.cheaderID,
this.cheaderType,
this.cheaderName,
this.cheaderInfo1,
this.cheaderInfo2});
this.lst.ContextMenuStrip = this.cmenuIndirectObject;
this.lst.Dock = System.Windows.Forms.DockStyle.Fill;
this.lst.FullRowSelect = true;
this.lst.HideSelection = false;
this.lst.Location = new System.Drawing.Point(0, 0);
this.lst.Name = "lst";
this.lst.Size = new System.Drawing.Size(455, 511);
this.lst.TabIndex = 0;
this.lst.UseCompatibleStateImageBehavior = false;
this.lst.View = System.Windows.Forms.View.Details;
this.lst.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lst_ColumnClick);
this.lst.SelectedIndexChanged += new System.EventHandler(this.lst_SelectedIndexChanged);
this.lst.DragDrop += new System.Windows.Forms.DragEventHandler(this.lst_DragDrop);
this.lst.DragOver += new System.Windows.Forms.DragEventHandler(this.lst_DragOver);
this.lst.DoubleClick += new System.EventHandler(this.lst_DoubleClick);
//
// cheaderID
//
this.cheaderID.Text = "ID";
//
// cheaderType
//
this.cheaderType.Text = "Type";
this.cheaderType.Width = 86;
//
// cheaderName
//
this.cheaderName.Text = "Details";
this.cheaderName.Width = 117;
//
// cheaderInfo1
//
this.cheaderInfo1.Text = "Info";
this.cheaderInfo1.Width = 77;
//
// cheaderInfo2
//
this.cheaderInfo2.Text = "Info";
this.cheaderInfo2.Width = 300;
//
// cmenuIndirectObject
//
this.cmenuIndirectObject.ImageScalingSize = new System.Drawing.Size(20, 20);
this.cmenuIndirectObject.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mitemDecompress,
this.mItemMakeAscii85,
this.mItemMakeAsciiHex,
this.mItemCompressFlate,
this.mItemCompressJpeg75,
this.mItemCompressJpeg50,
this.mItemCompressJpeg25,
this.flattenToolStripMenuItem,
this.mItemFlattenFormXObjects,
this.realizeToolStripMenuItem,
this.saveImageToolStripMenuItem,
this.exportToolStripMenuItem,
this.mItemRefresh,
this.mItemEdit,
this.mItemExtract});
this.cmenuIndirectObject.Name = "textBoxContextMenu";
this.cmenuIndirectObject.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
this.cmenuIndirectObject.ShowCheckMargin = true;
this.cmenuIndirectObject.ShowImageMargin = false;
this.cmenuIndirectObject.Size = new System.Drawing.Size(339, 484);
this.cmenuIndirectObject.Text = "cmenuIndirectObject";
this.cmenuIndirectObject.Opening += new System.ComponentModel.CancelEventHandler(this.cmenuTextBox_Opening);
//
// mitemDecompress
//
this.mitemDecompress.Name = "mitemDecompress";
this.mitemDecompress.Size = new System.Drawing.Size(338, 32);
this.mitemDecompress.Text = "&Decompress";
this.mitemDecompress.Click += new System.EventHandler(this.mitemDecompress_Click);
//
// mItemMakeAscii85
//
this.mItemMakeAscii85.Name = "mItemMakeAscii85";
this.mItemMakeAscii85.Size = new System.Drawing.Size(338, 32);
this.mItemMakeAscii85.Text = "&Make ASCII85";
this.mItemMakeAscii85.Click += new System.EventHandler(this.mItemMakeAscii_Click);
//
// mItemMakeAsciiHex
//
this.mItemMakeAsciiHex.Name = "mItemMakeAsciiHex";
this.mItemMakeAsciiHex.Size = new System.Drawing.Size(338, 32);
this.mItemMakeAsciiHex.Text = "&Make ASCII Hex";
this.mItemMakeAsciiHex.Click += new System.EventHandler(this.mItemMakeAsciiHex_Click);
//
// mItemCompressFlate
//
this.mItemCompressFlate.Name = "mItemCompressFlate";
this.mItemCompressFlate.Size = new System.Drawing.Size(338, 32);
this.mItemCompressFlate.Text = "Compress Flate";
this.mItemCompressFlate.Click += new System.EventHandler(this.mItemCompressFlate_Click);
//
// mItemCompressJpeg75
//
this.mItemCompressJpeg75.Name = "mItemCompressJpeg75";
this.mItemCompressJpeg75.Size = new System.Drawing.Size(338, 32);
this.mItemCompressJpeg75.Text = "Compress JPEG High Quality";
this.mItemCompressJpeg75.Click += new System.EventHandler(this.mItemCompressJpeg75_Click);
//
// mItemCompressJpeg50
//
this.mItemCompressJpeg50.Name = "mItemCompressJpeg50";
this.mItemCompressJpeg50.Size = new System.Drawing.Size(338, 32);
this.mItemCompressJpeg50.Text = "Compress JPEG Medium Quality";
this.mItemCompressJpeg50.Click += new System.EventHandler(this.mItemCompressJpeg50_Click);
//
// mItemCompressJpeg25
//
this.mItemCompressJpeg25.Name = "mItemCompressJpeg25";
this.mItemCompressJpeg25.Size = new System.Drawing.Size(338, 32);
this.mItemCompressJpeg25.Text = "Compress JPEG Low Quality";
this.mItemCompressJpeg25.Click += new System.EventHandler(this.mItemCompressJpeg25_Click);
//
// flattenToolStripMenuItem
//
this.flattenToolStripMenuItem.Name = "flattenToolStripMenuItem";
this.flattenToolStripMenuItem.Size = new System.Drawing.Size(338, 32);
this.flattenToolStripMenuItem.Text = "Compress Page Contents";
this.flattenToolStripMenuItem.Click += new System.EventHandler(this.flattenToolStripMenuItem_Click);
//
// mItemFlattenFormXObjects
//
this.mItemFlattenFormXObjects.Name = "mItemFlattenFormXObjects";
this.mItemFlattenFormXObjects.Size = new System.Drawing.Size(338, 32);
this.mItemFlattenFormXObjects.Text = "Stamp Form XObjects Into Page";
this.mItemFlattenFormXObjects.Click += new System.EventHandler(this.mItemFlattenFormXObjects_Click);
//
// realizeToolStripMenuItem
//
this.realizeToolStripMenuItem.Name = "realizeToolStripMenuItem";
this.realizeToolStripMenuItem.Size = new System.Drawing.Size(338, 32);
this.realizeToolStripMenuItem.Text = "Realize Image";
this.realizeToolStripMenuItem.Click += new System.EventHandler(this.realizeToolStripMenuItem_Click);
//
// saveImageToolStripMenuItem
//
this.saveImageToolStripMenuItem.Name = "saveImageToolStripMenuItem";
this.saveImageToolStripMenuItem.Size = new System.Drawing.Size(338, 32);
this.saveImageToolStripMenuItem.Text = "Save Image...";
this.saveImageToolStripMenuItem.Click += new System.EventHandler(this.saveImageToolStripMenuItem_Click);
//
// exportToolStripMenuItem
//
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
this.exportToolStripMenuItem.Size = new System.Drawing.Size(338, 32);
this.exportToolStripMenuItem.Text = "Export Data...";
this.exportToolStripMenuItem.Click += new System.EventHandler(this.exportToolStripMenuItem_Click);
//
// mItemRefresh
//
this.mItemRefresh.Name = "mItemRefresh";
this.mItemRefresh.Size = new System.Drawing.Size(338, 32);
this.mItemRefresh.Text = "Refresh";
this.mItemRefresh.Click += new System.EventHandler(this.mItemRefresh_Click);
//
// mItemEdit
//
this.mItemEdit.Name = "mItemEdit";
this.mItemEdit.Size = new System.Drawing.Size(338, 32);
this.mItemEdit.Text = "Edit Item...";
this.mItemEdit.Click += new System.EventHandler(this.mItemEdit_Click);
//
// mItemExtract
//
this.mItemExtract.Name = "mItemExtract";
this.mItemExtract.Size = new System.Drawing.Size(338, 32);
this.mItemExtract.Text = "Delete Other Pages...";
this.mItemExtract.Click += new System.EventHandler(this.mItemExtract_Click);
//
// tabInfo
//
this.tabInfo.Controls.Add(this.pageImage);
this.tabInfo.Controls.Add(this.pageAtom);
this.tabInfo.Controls.Add(this.pageContent);
this.tabInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabInfo.ImageList = this.imglist;
this.tabInfo.Location = new System.Drawing.Point(0, 0);
this.tabInfo.Name = "tabInfo";
this.tabInfo.SelectedIndex = 0;
this.tabInfo.Size = new System.Drawing.Size(319, 511);
this.tabInfo.TabIndex = 2;
this.tabInfo.SelectedIndexChanged += new System.EventHandler(this.tabInfo_SelectedIndexChanged);
//
// pageImage
//
this.pageImage.AutoScroll = true;
this.pageImage.Controls.Add(this.pnlPicture);
this.pageImage.ImageIndex = 0;
this.pageImage.Location = new System.Drawing.Point(4, 29);
this.pageImage.Name = "pageImage";
this.pageImage.Size = new System.Drawing.Size(311, 478);
this.pageImage.TabIndex = 0;
this.pageImage.Text = "Image";
this.pageImage.UseVisualStyleBackColor = true;
//
// pnlPicture
//
this.pnlPicture.AutoScroll = true;
this.pnlPicture.BackColor = System.Drawing.Color.Azure;
this.pnlPicture.Controls.Add(this.pict);
this.pnlPicture.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlPicture.Location = new System.Drawing.Point(0, 0);
this.pnlPicture.Margin = new System.Windows.Forms.Padding(0);
this.pnlPicture.Name = "pnlPicture";
this.pnlPicture.Size = new System.Drawing.Size(311, 478);
this.pnlPicture.TabIndex = 1;
this.pnlPicture.Click += new System.EventHandler(this.pict_Click);
//
// pict
//
this.pict.Location = new System.Drawing.Point(0, 0);
this.pict.Name = "pict";
this.pict.Size = new System.Drawing.Size(311, 493);
this.pict.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pict.TabIndex = 0;
this.pict.TabStop = false;
this.pict.Click += new System.EventHandler(this.pict_Click);
this.pict.Paint += new System.Windows.Forms.PaintEventHandler(this.pict_Paint);
this.pict.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.pict_MouseDoubleClick);
this.pict.MouseLeave += new System.EventHandler(this.pict_MouseLeave);
this.pict.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pict_MouseMove);
//
// pageAtom
//
this.pageAtom.Controls.Add(this.atomTree);
this.pageAtom.ImageIndex = 0;
this.pageAtom.Location = new System.Drawing.Point(4, 29);
this.pageAtom.Name = "pageAtom";
this.pageAtom.Size = new System.Drawing.Size(417, 614);
this.pageAtom.TabIndex = 1;
this.pageAtom.Text = "Atom";
this.pageAtom.UseVisualStyleBackColor = true;
//
// atomTree
//
this.atomTree.Dock = System.Windows.Forms.DockStyle.Fill;
this.atomTree.Location = new System.Drawing.Point(0, 0);
this.atomTree.Name = "atomTree";
this.atomTree.ShowNodeToolTips = true;
this.atomTree.Size = new System.Drawing.Size(417, 614);
this.atomTree.TabIndex = 0;
this.atomTree.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.atomTree_NodeMouseDoubleClick);
//
// pageContent
//
this.pageContent.Controls.Add(this.txtContent);
this.pageContent.ImageIndex = 0;
this.pageContent.Location = new System.Drawing.Point(4, 29);
this.pageContent.Name = "pageContent";
this.pageContent.Size = new System.Drawing.Size(417, 614);
this.pageContent.TabIndex = 2;
this.pageContent.Text = "Content";
this.pageContent.UseVisualStyleBackColor = true;
//
// txtContent
//
this.txtContent.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtContent.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtContent.Location = new System.Drawing.Point(0, 0);
this.txtContent.Name = "txtContent";
this.txtContent.ReadOnly = true;
this.txtContent.Size = new System.Drawing.Size(417, 614);
this.txtContent.TabIndex = 0;
this.txtContent.Text = "";
this.txtContent.WordWrap = false;
//
// imglist
//
this.imglist.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imglist.ImageStream")));
this.imglist.TransparentColor = System.Drawing.Color.Transparent;
this.imglist.Images.SetKeyName(0, "cross.ico");
this.imglist.Images.SetKeyName(1, "tick.ico");
//
// mstrip
//
this.mstrip.GripMargin = new System.Windows.Forms.Padding(2, 2, 0, 2);
this.mstrip.ImageScalingSize = new System.Drawing.Size(20, 20);
this.mstrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mitemFile,
this.editToolStripMenuItem,
this.viewToolStripMenuItem,
this.toolStripBack,
this.toolStripForward});
this.mstrip.Location = new System.Drawing.Point(0, 0);
this.mstrip.Name = "mstrip";
this.mstrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
this.mstrip.Size = new System.Drawing.Size(778, 33);
this.mstrip.TabIndex = 4;
this.mstrip.Text = "mstrip";
//
// mitemFile
//
this.mitemFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mitemOpen,
this.mitemSave,
this.mitemSaveAs,
this.mitemSaveAll,
this.mitemSep1,
this.mitemExit});
this.mitemFile.Name = "mitemFile";
this.mitemFile.Size = new System.Drawing.Size(54, 29);
this.mitemFile.Text = "&File";
//
// mitemOpen
//
this.mitemOpen.Name = "mitemOpen";
this.mitemOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.mitemOpen.Size = new System.Drawing.Size(255, 34);
this.mitemOpen.Text = "&Open...";
this.mitemOpen.Click += new System.EventHandler(this.mitemOpen_Click);
//
// mitemSave
//
this.mitemSave.Name = "mitemSave";
this.mitemSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.mitemSave.Size = new System.Drawing.Size(255, 34);
this.mitemSave.Text = "&Save";
this.mitemSave.Click += new System.EventHandler(this.mitemSave_Click);
//
// mitemSaveAs
//
this.mitemSaveAs.Name = "mitemSaveAs";
this.mitemSaveAs.Size = new System.Drawing.Size(255, 34);
this.mitemSaveAs.Text = "&Save As...";
this.mitemSaveAs.Click += new System.EventHandler(this.mitemSaveAs_Click);
//
// mitemSaveAll
//
this.mitemSaveAll.Name = "mitemSaveAll";
this.mitemSaveAll.Size = new System.Drawing.Size(255, 34);
this.mitemSaveAll.Text = "Export &Revisions...";
this.mitemSaveAll.Click += new System.EventHandler(this.mitemSaveAll_Click);
//
// mitemSep1
//
this.mitemSep1.Name = "mitemSep1";
this.mitemSep1.Size = new System.Drawing.Size(252, 6);
//
// mitemExit
//
this.mitemExit.Name = "mitemExit";
this.mitemExit.Size = new System.Drawing.Size(255, 34);
this.mitemExit.Text = "E&xit";
this.mitemExit.Click += new System.EventHandler(this.mitemExit_Click);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.findToolStripMenuItem,
this.selectAllToolStripMenuItem,
this.compactToolStripMenuItem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(58, 29);
this.editToolStripMenuItem.Text = "&Edit";
//
// findToolStripMenuItem
//
this.findToolStripMenuItem.Name = "findToolStripMenuItem";
this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
this.findToolStripMenuItem.Size = new System.Drawing.Size(248, 34);
this.findToolStripMenuItem.Text = "&Find All...";
this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click);
//
// selectAllToolStripMenuItem
//
this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(248, 34);
this.selectAllToolStripMenuItem.Text = "Select &All";
this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
//
// compactToolStripMenuItem
//
this.compactToolStripMenuItem.Name = "compactToolStripMenuItem";
this.compactToolStripMenuItem.Size = new System.Drawing.Size(248, 34);
this.compactToolStripMenuItem.Text = "Compact";
this.compactToolStripMenuItem.Click += new System.EventHandler(this.compactToolStripMenuItem_Click);
//
// viewToolStripMenuItem
//
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.showAllToolStripMenuItem,
this.selectedToolStripMenuItem,
this.unselectedToolStripMenuItem,
this.toolStripSeparator1,
this.overprintToolStripMenuItem,
this.openInAcrobatToolStripMenuItem});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(65, 29);
this.viewToolStripMenuItem.Text = "View";
//
// showAllToolStripMenuItem
//
this.showAllToolStripMenuItem.Name = "showAllToolStripMenuItem";
this.showAllToolStripMenuItem.Size = new System.Drawing.Size(360, 34);
this.showAllToolStripMenuItem.Text = "All";
this.showAllToolStripMenuItem.Click += new System.EventHandler(this.allToolStripMenuItem_Click);
//
// selectedToolStripMenuItem
//
this.selectedToolStripMenuItem.Name = "selectedToolStripMenuItem";
this.selectedToolStripMenuItem.Size = new System.Drawing.Size(360, 34);
this.selectedToolStripMenuItem.Text = "Selected Only";
this.selectedToolStripMenuItem.Click += new System.EventHandler(this.selectedToolStripMenuItem_Click);
//
// unselectedToolStripMenuItem
//
this.unselectedToolStripMenuItem.Name = "unselectedToolStripMenuItem";
this.unselectedToolStripMenuItem.Size = new System.Drawing.Size(360, 34);
this.unselectedToolStripMenuItem.Text = "Unselected Only";
this.unselectedToolStripMenuItem.Click += new System.EventHandler(this.unselectedToolStripMenuItem_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(357, 6);
//
// overprintToolStripMenuItem
//
this.overprintToolStripMenuItem.Name = "overprintToolStripMenuItem";
this.overprintToolStripMenuItem.Size = new System.Drawing.Size(360, 34);
this.overprintToolStripMenuItem.Text = "Overprint";
this.overprintToolStripMenuItem.Click += new System.EventHandler(this.overprintToolStripMenuItem_Click);
//
// openInAcrobatToolStripMenuItem
//
this.openInAcrobatToolStripMenuItem.Name = "openInAcrobatToolStripMenuItem";
this.openInAcrobatToolStripMenuItem.ShortcutKeyDisplayString = "";
this.openInAcrobatToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.V)));
this.openInAcrobatToolStripMenuItem.Size = new System.Drawing.Size(360, 34);
this.openInAcrobatToolStripMenuItem.Text = "View in Acrobat...";
this.openInAcrobatToolStripMenuItem.Click += new System.EventHandler(this.openInAcrobatToolStripMenuItem_Click);
//
// toolStripBack
//
this.toolStripBack.AutoToolTip = true;
this.toolStripBack.Name = "toolStripBack";
this.toolStripBack.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Left)));
this.toolStripBack.Size = new System.Drawing.Size(44, 29);
this.toolStripBack.Text = "◀";
this.toolStripBack.ToolTipText = "Click to go back";
this.toolStripBack.Click += new System.EventHandler(this.toolStripBack_Click);
//
// toolStripForward
//
this.toolStripForward.AutoToolTip = true;
this.toolStripForward.Name = "toolStripForward";
this.toolStripForward.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.Right)));
this.toolStripForward.Size = new System.Drawing.Size(44, 29);
this.toolStripForward.Text = "▶";
this.toolStripForward.ToolTipText = "Click to go forwards";
this.toolStripForward.Click += new System.EventHandler(this.toolStripForward_Click);
//
// dlgSaveFile
//
this.dlgSaveFile.DefaultExt = "pdf";
this.dlgSaveFile.FileName = "Untitled";
this.dlgSaveFile.Filter = "PDF Document (*.pdf)|*.pdf";
this.dlgSaveFile.Title = "Save a PDF Document";
//
// dlgSaveImage
//
this.dlgSaveImage.DefaultExt = "jpg";
this.dlgSaveImage.FileName = "Untitled";
this.dlgSaveImage.Filter = "Image Files(*.JPG;*.PNG;*.TIF;*.GIF;*.BMP;)|*.JPG;*.PNG;*.TIF;*.GIF;*.BMP|All fil" +
"es (*.*)|*.*";
this.dlgSaveImage.Title = "Save an Image";
//
// dlgSaveFolder
//
this.dlgSaveFolder.Description = "Export the revisions of the saved document in a diffable format.";
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// dlgExportFile
//
this.dlgExportFile.AddExtension = false;
this.dlgExportFile.DefaultExt = "txt";
this.dlgExportFile.FileName = "Untitled";
this.dlgExportFile.Filter = "Data Files(*.TXT;*.DAT;*.TTF;*.JPG;)|*.TXT;*.DAT;*.TTF;*.JPG;|All files (*.*)|*.*" +
"";
this.dlgExportFile.SupportMultiDottedExtensions = true;
this.dlgExportFile.Title = "Export Data";
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(8, 19);
this.ClientSize = new System.Drawing.Size(778, 544);
this.Controls.Add(this.split);
this.Controls.Add(this.mstrip);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.mstrip;
this.Name = "MainForm";
this.Text = "PDF Surgeon";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.split.Panel1.ResumeLayout(false);
this.split.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.split)).EndInit();
this.split.ResumeLayout(false);
this.cmenuIndirectObject.ResumeLayout(false);
this.tabInfo.ResumeLayout(false);
this.pageImage.ResumeLayout(false);
this.pnlPicture.ResumeLayout(false);
this.pnlPicture.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pict)).EndInit();
this.pageAtom.ResumeLayout(false);
this.pageContent.ResumeLayout(false);
this.mstrip.ResumeLayout(false);
this.mstrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
private void Clear() {
ResetItemView();
lst.Items.Clear();
_graphics = null;
_fixture = null;
_editTexts = new Dictionary<ObjectExtractor, EditText>();
_nav = new Navigator();
}
private void ResetItemView() {
atomTree.Nodes.Clear();
//txtAtom.Clear();
txtContent.Clear();
pict.Visible = false;
pageImage.ImageIndex = 0;
pageAtom.ImageIndex = 0;
pageContent.ImageIndex = 0;
}
public void UpdateInfo(HashSet<int> ids) {
lst.BeginUpdate();
try {
foreach (ListViewItem item in lst.Items) {
ObjectExtractor extractor = item.Tag as ObjectExtractor;
if ((extractor == null) || (extractor.Object == null))
continue;
if (ids == null || ids.Contains(extractor.Object.ID)) {
var info = extractor.GetProperties();
for (int i = 0; (i < item.SubItems.Count) && (i < info.Count); i++)
item.SubItems[i].Text = info[i].Summary;
extractor.Invalidate();
UpdateContent(extractor);
}
}
}
finally {
lst.EndUpdate();
}
}
public void UpdateListItemInfo(ListViewItem item) {
if (item == null)
return;
ObjectExtractor extractor = item.Tag as ObjectExtractor;
if ((extractor == null) || (extractor.Object == null))
return;
var info = extractor.GetProperties();
for (int i = 0; (i < item.SubItems.Count) && (i < info.Count); i++)
item.SubItems[i].Text = info[i].Summary;
extractor.Invalidate();
UpdateContent(extractor);
}
public void UpdateContent(ObjectExtractor item) {
// first atom...
atomTree.SuspendLayout();
atomTree.Nodes.Clear();
TreeNode root = atomTree.Nodes.Add($"{item.Object.ID} {item.Object.Gen} R");
UpdateContent(root, new Font(atomTree.Font, FontStyle.Bold), item.Object.Atom);
StreamObjectExtractor so = item as StreamObjectExtractor;
if (item is StreamObjectExtractor) {
atomTree.Nodes.Add($"stream");
atomTree.Nodes.Add(((StreamObjectExtractor)item).GetSnippet());
atomTree.Nodes.Add($"endstream");
}
// ... then content
string content = item.GetContent();
if (content == null) {
txtContent.Clear();
pageContent.ImageIndex = 0;
}
else {
SetTextBoxText(content, txtContent);
pageContent.ImageIndex = 1;
}
// ... then properties
TreeNode props = atomTree.Nodes.Add($"Calculated Properties");
var items = item.GetProperties();
for (int i = 2; i < items.Count; i++)
props.Nodes.Add(items[i].Detail);
// ... finish
atomTree.ExpandAll();
root.EnsureVisible();
pageAtom.ImageIndex = 1;
_nav.Add(item.Object.ID);
atomTree.ResumeLayout();
}
private void UpdateContent(TreeNode root, Font bold, Atom atom) {
root.Tag = atom;
if (atom is DictAtom) {
DictAtom dict = atom as DictAtom;
root.Text += " <<>>";
foreach (var pair in dict) {
TreeNode key = root.Nodes.Add("/" + pair.Key);
UpdateContent(key, bold, pair.Value);
}
}
else if (atom is ArrayAtom) {
ArrayAtom array = atom as ArrayAtom;
bool isRectOrMatrix = false;
if (array.Count == 4 || array.Count == 6) {
isRectOrMatrix = true;
for (int i = 0; i < array.Count; i++) {
if (array[i] is NumAtom == false) {
isRectOrMatrix = false;
break;
}
}
}
if (isRectOrMatrix) {
root.Text += " [";
for (int i = 0; i < array.Count; i++)
root.Text += " " + array[i].ToString();
root.Text += " ]";
if (array.Count == 4) {
double x1 = ((NumAtom)array[0]).Real;
double y1 = ((NumAtom)array[1]).Real;
double x2 = ((NumAtom)array[2]).Real;
double y2 = ((NumAtom)array[3]).Real;
XRect rect = XRect.FromSides(x1, y1, x2, y2);
root.ToolTipText = $"Width {rect.Width} Height {rect.Height}";
}
}
else {
root.Text += " []";
for (int i = 0; i < array.Count; i++) {
TreeNode item = root.Nodes.Add("");
item.ToolTipText = $"Item {i + 1} of {array.Count}";
UpdateContent(item, bold, array[i]);
}
}
}
else {
root.Text += " " + atom.ToString();
if (atom is RefAtom)
root.ToolTipText = $"Jump to {atom}";
}
}
public void UpdateImage(ObjectExtractor extractor, bool reload) {
Preview preview = extractor.GetPreview(reload);
if (preview == null)
pageImage.ImageIndex = 0;
else
pageImage.ImageIndex = 1;
}
public bool Dirty { get { return _dirty; } set { _dirty = value; } }
public Find FindDialog { get { return _findDialog; } set { _findDialog = value; } }
public GraphicsScanner.Fixture Fixture { get { return _fixture; } }
public void Find(string search, bool wholeWord) {
if ((_doc == null) || (search == null) || (search == ""))
return;
foreach (ListViewItem item in lst.Items) {
ObjectExtractor extractor = item.Tag as ObjectExtractor;
string val = extractor != null ? extractor.GetValue(_doc) : "";
int pos = -1;
while (true) {
pos = val.IndexOf(search, pos + 1);
if (pos < 0)
break;
if (!wholeWord)
break;
int p1 = pos - 1;
if ((p1 >= 0) && (!char.IsWhiteSpace(val[p1])) && (!char.IsPunctuation(val[p1])))
continue; // start of word joined up
int p2 = pos + search.Length + 1;
if ((p2 < val.Length) && (!char.IsWhiteSpace(val[p2])) && (!char.IsPunctuation(val[p2])))
continue; // end of word joined up
break;
}
item.Selected = (pos >= 0);
}
lst.Focus();
}
public void SelectByObjectID(int id) {
if (_doc == null)
return;
foreach (ListViewItem item in lst.Items) {
ObjectExtractor extractor = item.Tag as ObjectExtractor;
item.Selected = (extractor != null) && (extractor.Object != null) && (extractor.Object.ID == id);
}
}
public void OpenSnapshot() {
if (_tempFiles == null)
_tempFiles = new List<TemporaryFile>();
TemporaryFile temp = new TemporaryFile(".pdf");
// when we save we try to keep the object ids constant
_doc.SaveOptions.Linearize = false;
_doc.SaveOptions.Remap = false;
_doc.SaveOptions.Compact = false;
_doc.SaveOptions.CompressObjects = false;
_doc.Save(temp.Path);
_tempFiles.Add(temp);
Process.Start(temp.Path);
}
private void Open(string filePath) {
if (!CloseFile())
return;
string oldText = Text;
Doc doc = null;
try {
Text = "PDF Surgeon - "+filePath;
Update();
doc = new Doc();
XReadOptions ro = new XReadOptions();
ro.Repair = true;
doc.Read(filePath, ro);
} catch {
if(doc!=null)
doc.Dispose();
Text = oldText;
throw;
}
Clear();
_doc = doc;
_doc.SetInfo(0, "CheckSaveRestore", 0);
_doc.Rendering.Overprint = overprintToolStripMenuItem.Checked;
_filePath = filePath;
_dirty = false;
lst.BeginUpdate();
try {
lst.Items.AddRange(MakeListItems(doc));
} finally {
lst.EndUpdate();
}
}
private static ListViewItem[] MakeListItems(Doc doc) {
ObjectSoup soup = doc.ObjectSoup;
int count = soup.Count;
ListViewItem[] items;
List<ObjectExtractor> extractorList = new List<ObjectExtractor>(count);
string[] errorList = new string[count];
ExtractorContext context = new ExtractorContext();
for (int i = 0; i < count; ++i)
extractorList.Add(null);
for (int i = 0; i < count; ++i) {
IndirectObject obj = soup[i];
if (obj == null)
continue;
try {
extractorList[i] = ObjectExtractor.FromIndirectObject(obj, context);
}
catch (Exception exc) {
extractorList[i] = new ObjectExtractor(obj, context);
errorList[i] = exc.Message;
}
}
foreach(int id in context.CMaps) {
StreamObjectExtractor streamExtractor
= unchecked((uint)id) >= unchecked((uint)count) ? null :
extractorList[id] as StreamObjectExtractor;
if(streamExtractor != null)
streamExtractor.StreamType = "CMap";
}
foreach (KeyValuePair<int, string> pair in context.Xfa) {
StreamObjectExtractor streamExtractor
= unchecked((uint)pair.Key) >= unchecked((uint)count) ? null :
extractorList[pair.Key] as StreamObjectExtractor;
if (streamExtractor != null) {
streamExtractor.StreamType = pair.Value == null ? "XML/XFA" :
string.Format("XML/XFA[{0}]", pair.Value);
}
}
string[] scriptTypeList = { "JavaScript",
"JavaScript[{0}]",
"JavaScript[PageID {1}]",
"JavaScript[{0},PageID {1}]",
"JavaScript[AnnotationID {2}]",
"JavaScript[{0},AnnotationID {2}]",
"JavaScript[PageID {1},AnnotationID {2}]",
"JavaScript[{0},PageID {1},AnnotationID {2}]"
};
foreach (KeyValuePair<int, ScriptType> pair in context.Scripts) {
StreamObjectExtractor streamExtractor
= unchecked((uint)pair.Key) >= unchecked((uint)count) ? null :
extractorList[pair.Key] as StreamObjectExtractor;
if (streamExtractor != null) {
int formatIndex = 0;
if (pair.Value.DocumentName != null)
formatIndex |= 1;
if (pair.Value.PageName != null)
formatIndex |= 2;
if (pair.Value.AnnotationName != null)
formatIndex |= 4;
streamExtractor.StreamType = string.Format(
scriptTypeList[formatIndex], pair.Value.DocumentName,
pair.Value.PageName, pair.Value.AnnotationName);
}
}
foreach(KeyValuePair<int, string> pair in context.Type3Glyphs) {
StreamObjectExtractor streamExtractor
= unchecked((uint)pair.Key) >= unchecked((uint)count) ? null :
extractorList[pair.Key] as StreamObjectExtractor;
if(streamExtractor != null) {
streamExtractor.StreamType = string.Format(
"Type 3 Glyph[{0}]", pair.Value);
}
}
foreach (int id in context.PageContents) {
StreamObjectExtractor streamExtractor
= unchecked((uint)id) >= unchecked((uint)count) ? null :
extractorList[id] as StreamObjectExtractor;
if (streamExtractor != null)
streamExtractor.ContentPageNumber = context.PageContentIdToPageNumber[id];
}
List<ListViewItem> itemList = new List<ListViewItem>(count);
for (int i = 0; i < count; ++i) {
ObjectExtractor extractor = extractorList[i];
if (extractor != null) {
var props = extractor.GetProperties();
if (errorList[i] != null)
props.Insert(Math.Min(props.Count, 2), new Property("Error", errorList[i]));
List<string> values = new List<string>();
foreach (var prop in props)
values.Add(prop.Summary);
ListViewItem item = new ListViewItem(values.ToArray());
item.Tag = extractor;
itemList.Add(item);
}
}
items = itemList.ToArray();
return items;
}
private bool CloseFile() {
bool ok = true;
if (_dirty) {
string text = string.Format("Do you want to save changes to {0} ?",
Path.GetFileNameWithoutExtension(_filePath));
switch (MessageBox.Show(text, Application.ProductName, MessageBoxButtons.YesNoCancel)) {
case DialogResult.Yes :
_dirty = false;
Save();
_doc.Clear();
break;
case DialogResult.No :
break;
case DialogResult.Cancel :
ok = false;
break;
}
}
return ok;
}
private void Save() {
bool swap = File.Exists(_filePath);
Tuple<string, string> pair = swap ? GetSaveAsName(_filePath) : null;
string path = swap ? Path.Combine(pair.Item1, pair.Item2): _filePath;
// when we save we try to keep the object ids constant
_doc.SaveOptions.Linearize = false;
_doc.SaveOptions.Remap = false;
_doc.SaveOptions.Compact = false;
_doc.SaveOptions.CompressObjects = false;
_doc.Save(path);
_doc.Clear();
if (swap) {
try {
File.Delete(_filePath);
File.Move(path, _filePath);
}
catch (Exception ex) {
MessageBox.Show($"Saving to {Path.GetFileName(path)}. The reason for this is the following. {ex.Message}");
_filePath = path;
}
}
_dirty = false;
Open(_filePath);
TempFile = null;
}
private void SaveAll(string folder) {
using (TemporaryFile temp = new TemporaryFile(".pdf")) {
File.Copy(_filePath, temp.Path);
bool linearized = File.ReadAllText(temp.Path).Contains("/Linearized 1");
string name = Path.GetFileNameWithoutExtension(_filePath);
List<long> eofs = null;
List<int> signedAreas = new List<int>();
using (Doc doc = new Doc()) {
doc.Read(temp.Path);
int n = doc.ObjectSoup.Revisions;
if (eofs == null) {
eofs = new List<long>(doc.ObjectSoup.RevisionEOFs);
eofs.Reverse();
}
if (linearized)
n--;
for (int i = 0; i < n; i++) {
doc.Read(temp.Path);
XReadOptions ro = new XReadOptions { SkipRevisions = i };
doc.Read(temp.Path, ro);
int max = 0;
foreach (var o in doc.ObjectSoup) {
if (o == null)
continue;
var a = o.Atom; // touch the atom to ensure consistent formatting
var br = Atom.GetItem(a, "ByteRange") as ArrayAtom;
if (br != null && br.Count == 4 && Atom.GetItem(a, "Contents") != null)
max = Math.Max(max, Atom.GetInt(br[2]) + Atom.GetInt(br[3]));
}
signedAreas.Add(max);
doc.SaveOptions.Remap = false;
doc.SaveOptions.Linearize = false;
doc.SaveOptions.Incremental = false;
doc.SaveOptions.Compact = false;
doc.SaveOptions.CompressObjects = false;
doc.Save(Path.Combine(folder, $"{name}-rewrite-{n - i}of{n}.pdf"));
}
}
var data = File.ReadAllBytes(temp.Path);
for (int i = 0; i < eofs.Count; i++) {
int diff = 0;
if (signedAreas[i] > 0) {
diff = signedAreas[i] - (int)eofs[i];
if (diff < 0 || diff > 10) // something odd
diff = "%%EOF\r\n".Length;
}
var path = Path.Combine(folder, $"{name}-original-{eofs.Count - i}of{eofs.Count}.pdf");
using (var stream = new FileStream(path, FileMode.Create))
stream.Write(data, 0, (int)(eofs[i] + diff));
}
}
}
private string TempFile {
set {
try {
if ((_tempPath != null) && (File.Exists(_tempPath)))
File.Delete(_tempPath);
}
catch {
}
_tempPath = value;
}
get { return _tempPath; }
}
public void SetItemValue(int id, string text) {
_doc.SetInfo(id, "value", text);
}
private ListViewItem GetSelectedItem() {
ListViewItem item = lst.FocusedItem;
if(item!=null && item.Selected)
return item;
if(lst.SelectedItems.Count>0)
return lst.SelectedItems[0];
return null;
}
private void SetPreview(Preview preview) {
if (preview == null) {
pict.Visible = false;
}
else {
var img = preview.Image;
var graphics = preview.Graphics;
if (img != pict.Image)
pict.Image = img;
if (graphics != _graphics) {
_graphics = graphics;
_fixture = null;
}
if (pageImage.ImageIndex != 1)
pageImage.ImageIndex = 1;
pict.Visible = true;
}
}
private void SetTextBoxText(string text, RichTextBox textBox) {
textBox.Clear();
int i = text.IndexOf('\0');
if(i<0) {
textBox.Text = text;
return;
}
textBox.Text = text.Replace('\0', '\ufeff');
text = textBox.Text;
textBox.Text = text.Replace('\ufeff', ' ');
Color backColor = Color.FromKnownColor(KnownColor.Control);
Color highlight = Color.FromKnownColor(KnownColor.Highlight);
highlight = Color.FromArgb(highlight.A, (highlight.R+backColor.R)/2,
(highlight.G+backColor.G)/2, (highlight.B+backColor.B)/2);
// some character combinations cause mismatches between Select and text positions
while((i = text.IndexOf('\ufeff', i))>=0) {
int j = i;
do {
++i;
} while(i<text.Length && text[i]=='\ufeff');
textBox.Select(j, i-j);
textBox.SelectionBackColor = highlight;
}
textBox.Select(0, 0);
textBox.SelectionBackColor = new Color();
}
private void mitemExit_Click(object sender, EventArgs e) {
CloseFile();
Close();
}
private void mitemOpen_Click(object sender, EventArgs e) {
if(dlgOpenFile.ShowDialog()!=DialogResult.OK)
return;
try {
Open(dlgOpenFile.FileName);
} catch(Exception exc) {
MessageBox.Show(exc.Message);
}
}
private void cmenuTextBox_ItemClicked(object sender, ToolStripItemClickedEventArgs e) {
}
private void cmenuTextBox_Opening(object sender, CancelEventArgs e) {
IndirectObject extractor = _selectedExtractor != null ? _selectedExtractor.Object : null;
ContextMenuStrip cmd = (ContextMenuStrip)sender;
cmd.Items[0].Enabled = extractor is StreamObject;
cmd.Items[1].Enabled = extractor is StreamObject;
cmd.Items[2].Enabled = extractor is StreamObject;
cmd.Items[3].Enabled = extractor is StreamObject;
cmd.Items[4].Enabled = extractor is PixMap;
cmd.Items[5].Enabled = extractor is PixMap;
cmd.Items[6].Enabled = extractor is PixMap;
cmd.Items[7].Enabled = extractor is Page;
cmd.Items[8].Enabled = extractor is Page;
cmd.Items[9].Enabled = extractor is PixMap;
cmd.Items[10].Enabled = extractor is PixMap;
cmd.Items[10].Enabled = extractor is StreamObject;
}
private void lst_SelectedIndexChanged(object sender, EventArgs e) {
ListViewItem item = GetSelectedItem();
ObjectExtractor extractor = item==null? null: item.Tag as ObjectExtractor;
if(_selectedExtractor==extractor)
return;
_selectedExtractor = extractor;
if(extractor==null) {
ResetItemView();
return;
}
UpdateContent(extractor);
UpdateImage(extractor, false);
}
private void lst_DoubleClick(object sender, EventArgs e) {
EditItem();
}
private void lst_ColumnClick(object sender, ColumnClickEventArgs e) {
ListViewItemComparer comparer = lst.ListViewItemSorter as ListViewItemComparer;
if(comparer!=null){
if(e.Column==comparer.Column){
if(comparer.Order==SortOrder.Ascending)
comparer.Order = SortOrder.Descending;
else
comparer.Order = SortOrder.Ascending;
}else{
comparer.Column = e.Column;
comparer.Order = SortOrder.Ascending;
}
}
lst.Sort();
ListViewItem item = lst.FocusedItem;
if(item!=null)
item.EnsureVisible();
}
private void lst_DragOver(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Move;
}
private void lst_DragDrop(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files.Length > 0) {
try {
Open(files[0]);
}
catch (Exception exc) {
MessageBox.Show(exc.Message);
}
}
}
}
private void pict_Click(object sender, EventArgs e) {
pnlPicture.Focus();
}
private void pict_MouseDoubleClick(object sender, MouseEventArgs e) {
var preview = _selectedExtractor != null ? _selectedExtractor.GetPreview(false) : null;
if (preview == null)
return;
double[] levels = new double[] { 0.02, 0.04, 0.08, 0.16, 0.25, 0.33, 0.5, 0.67, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 };
int pos = 0;
double bestDelta = double.MaxValue;
for (int i = 0; i < levels.Length; i++) {
double delta = Math.Abs(preview.Scale - levels[i]);
if (delta < bestDelta) {
bestDelta = delta;
pos = i;
}
}
bool unzoom = (Control.ModifierKeys & Keys.Alt) == Keys.Alt;
pos = unzoom ? Math.Max(pos - 1, 0) : Math.Min(pos + 1, levels.Length - 1);
if (preview.Scale != levels[pos]) {
preview.Scale = levels[pos];
preview.Reload();
}
}
private void mitemDecompress_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
StreamObject stream = extractor.Object as StreamObject;
if (stream == null) return;
stream.Decompress();
extractor.Invalidate();
UpdateContent(extractor);
UpdateListItemInfo(GetSelectedItem());
Dirty = true;
}
private void mItemMakeAscii_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
StreamObject stream = extractor.Object as StreamObject;
if (stream == null) return;
stream.CompressAscii85();
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void mItemMakeAsciiHex_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
StreamObject stream = extractor.Object as StreamObject;
if (stream == null) return;
stream.CompressAsciiHex();
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void mItemCompressFlate_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
StreamObject stream = extractor.Object as StreamObject;
if (stream == null) return;
stream.CompressFlate();
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void mItemCompressJpeg75_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
PixMap pixMap = extractor.Object as PixMap;
if (pixMap == null) return;
pixMap.Decompress();
pixMap.CompressJpeg(75);
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void mItemCompressJpeg50_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
PixMap pixMap = extractor.Object as PixMap;
if (pixMap == null) return;
pixMap.Decompress();
pixMap.CompressJpeg(50);
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void mItemCompressJpeg25_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
PixMap pixMap = extractor.Object as PixMap;
if (pixMap == null) return;
pixMap.Decompress();
pixMap.CompressJpeg(25);
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void flattenToolStripMenuItem_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
Page page = extractor.Object as Page;
if (page == null) return;
page.Flatten(true);
extractor.Invalidate();
UpdateInfo(null);
UpdateContent(extractor);
UpdateImage(extractor, true);
Dirty = true;
}
private void mItemFlattenFormXObjects_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
Page page = extractor.Object as Page;
if (page == null) return;
page.StampFormXObjects(true);
HashSet<int> ids = new HashSet<int>();
foreach (var item in page.GetLayers())
ids.Add(item.ID);
UpdateInfo(ids);
UpdateContent(extractor);
UpdateImage(extractor, true);
Dirty = true;
}
private void realizeToolStripMenuItem_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
PixMap pixMap = extractor.Object as PixMap;
if (pixMap == null) return;
pixMap.Realize();
extractor.Invalidate();
UpdateContent(extractor);
Dirty = true;
}
private void saveImageToolStripMenuItem_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
PixMap pixMap = extractor.Object as PixMap;
if (pixMap == null) return;
if (dlgSaveImage.ShowDialog() == DialogResult.OK) {
string filePath = dlgSaveImage.FileName;
pixMap.Save(filePath);
}
}
private void exportToolStripMenuItem_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
StreamObject stm = extractor.Object as StreamObject;
if (stm == null) return;
if (dlgExportFile.ShowDialog() == DialogResult.OK) {
string filePath = dlgExportFile.FileName;
File.WriteAllBytes(filePath, stm.GetData());
}
}
private void mItemRefresh_Click(object sender, EventArgs e) {
RefreshSelectedImage();
}
public void RefreshSelectedImage() {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
extractor.Invalidate();
UpdateContent(extractor);
UpdateImage(extractor, true);
}
private void mItemEdit_Click(object sender, EventArgs e)
{
EditItem();
}
private void EditItem()
{
ObjectExtractor extractor = _selectedExtractor;
if ((extractor == null) || (extractor.Object == null)) return;
EditText theEdit = null;
_editTexts.TryGetValue(extractor, out theEdit);
if (theEdit == null)
{
theEdit = new EditText(this, extractor);
_editTexts.Add(extractor, theEdit);
theEdit.Show();
}
else
theEdit.BringToFront();
}
private void mItemExtract_Click(object sender, EventArgs e) {
ObjectExtractor extractor = _selectedExtractor;
if (extractor == null) return;
Page page = extractor.Object as Page;
if (page == null) return;
_doc.Page = page.ID;
_doc.RemapPages(new int[] { _doc.PageNumber });
UpdateInfo(null);
UpdateContent(extractor);
UpdateImage(extractor, true);
Dirty = true;
}
private void mitemSave_Click(object sender, EventArgs e) {
Save();
}
private void mitemSaveAs_Click(object sender, EventArgs e) {
if (File.Exists(_filePath)) {
Tuple<string, string> dirAndName = GetSaveAsName(_filePath);
dlgSaveFile.InitialDirectory = dirAndName.Item1;
dlgSaveFile.FileName = dirAndName.Item2;
}
if (dlgSaveFile.ShowDialog() == DialogResult.OK) {
_filePath = dlgSaveFile.FileName;
Save();
}
}
private static Tuple<string, string> GetSaveAsName(string currentFilePath) {
string directory = Directory.GetParent(currentFilePath).FullName;
string currentName = Path.GetFileNameWithoutExtension(currentFilePath);
string newName = "";
int p = currentName.LastIndexOf(' ');
if (p >= 0) {
bool alreadyNumbered = true;
for (int i = p + 1; i < currentName.Length; i++) {
if (char.IsNumber(currentName[i]) == false) {
alreadyNumbered = false;
break;
}
}
if (alreadyNumbered)
currentName = currentName.Substring(0, p);
}
for (int i = 1; i < 1000; i++) {
newName = currentName + " " + i.ToString() + Path.GetExtension(currentFilePath);
if (!File.Exists(Path.Combine(directory, newName)))
break;
}
return new Tuple<string, string>(directory, newName);
}
private void mitemSaveAll_Click(object sender, EventArgs e) {
if (File.Exists(_filePath)) {
dlgSaveFolder.SelectedPath = Directory.GetParent(_filePath).FullName;
if (dlgSaveFolder.ShowDialog() == DialogResult.OK) {
SaveAll(dlgSaveFolder.SelectedPath);
}
}
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) {
Control control = ActiveControl;
while(control!=null) {
ContainerControl container = control as ContainerControl;
if(container==null) {
TextBoxBase txt = control as TextBoxBase;
if(txt!=null) {
txt.SelectAll();
return;
}
break;
}
control = container.ActiveControl;
}
foreach (ListViewItem item in lst.Items)
item.Selected = true;
}
private void findToolStripMenuItem_Click(object sender, EventArgs e) {
if (_findDialog == null)
_findDialog = new Find(this);
_findDialog.Show();
_findDialog.BringToFront();
}
private void compactToolStripMenuItem_Click(object sender, EventArgs e) {
// remove any redundant objects
string path = Path.GetTempPath() + Guid.NewGuid().ToString() + ".pdf";
_doc.SaveOptions.Linearize = false;
_doc.SaveOptions.Remap = true;
_doc.SaveOptions.Compact = false;
_doc.SaveOptions.CompressObjects = false;
_doc.Save(path);
_doc.Clear();
string oldText = Text;
string oldPath = _filePath;
_dirty = false;
Open(path);
_dirty = true;
_filePath = oldPath;
Text = oldText;
TempFile = path;
}
private void allToolStripMenuItem_Click(object sender, EventArgs e) {
if (_doc == null)
return;
lst.BeginUpdate();
try {
lst.Items.Clear();
lst.Items.AddRange(MakeListItems(_doc));
}
finally {
lst.EndUpdate();
}
}
private void selectedToolStripMenuItem_Click(object sender, EventArgs e) {
ShowSelected(true);
}
private void unselectedToolStripMenuItem_Click(object sender, EventArgs e) {
ShowSelected(false);
}
private void ShowSelected(bool truth) {
List<ListViewItem> itemList = new List<ListViewItem>();
foreach (ListViewItem item in lst.Items) {
if (item.Selected == truth)
itemList.Add(item);
}
lst.BeginUpdate();
try {
lst.Items.Clear();
lst.Items.AddRange(itemList.ToArray());
}
finally {
lst.EndUpdate();
}
}
private void overprintToolStripMenuItem_Click(object sender, EventArgs e) {
overprintToolStripMenuItem.Checked = !overprintToolStripMenuItem.Checked;
if (_doc != null) {
_doc.Rendering.Overprint = overprintToolStripMenuItem.Checked;
RefreshSelectedImage();
}
}
private void openInAcrobatToolStripMenuItem_Click(object sender, EventArgs e) {
if (_doc != null)
OpenSnapshot();
}
private void MainForm_Load(object sender, EventArgs e) {
Size size = Properties.Settings.Default.WindowSize;
if (size.Width > 30 && size.Height > 30)
Size = size;
int distance = Properties.Settings.Default.SplitterDistance;
if (distance > 10)
split.SplitterDistance = distance;
Preview.InitialImage = pict.InitialImage;
Preview.ErrorImage = pict.ErrorImage;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) {
Properties.Settings.Default.WindowSize = Size;
Properties.Settings.Default.SplitterDistance = split.SplitterDistance;
Properties.Settings.Default.Save();
if (CloseFile()) {
if (_doc != null) {
_doc.Dispose();
_doc = null;
}
TempFile = null;
}
else
e.Cancel = true;
}
private void atomTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {
RefAtom rf = e.Node.Tag as RefAtom;
if (rf == null) return;
SelectByObjectID(rf.ID);
if (lst.SelectedItems.Count > 0)
lst.EnsureVisible(lst.SelectedIndices[0]);
}
private void toolStripBack_Click(object sender, EventArgs e) {
if (_nav.CanNavigate())
SelectByObjectID(_nav.Back());
}
private void toolStripForward_Click(object sender, EventArgs e) {
if (_nav.CanNavigate())
SelectByObjectID(_nav.Forward());
}
private void pict_MouseMove(object sender, MouseEventArgs e) {
if (ModifierKeys.HasFlag(Keys.Shift))
return; // allow focus freeze if shift pressed
bool refresh = false;
if (_graphics != null && _graphics.All.Count > 0) {
Point loc = e.Location;
var offset = GetImageOffset();
loc.Offset(-offset.X, -offset.Y);
GraphicsScanner.Fixture best = null;
foreach (var part in _graphics.All) {
if (part.Region.IsVisible(loc)) {
if (best == null || part.Area < best.Area)
best = part;
}
}
if (_fixture != best) {
refresh = true;
_fixture = best;
if (_fixture == null) {
toolTip1.Hide(this);
toolTip1.Tag = null;
}
else if (toolTip1.Tag != _fixture) {
string txt = $"ID {_fixture.OwnerID} {_fixture.Text}";
if (!string.IsNullOrEmpty(txt)) {
Point pp = pict.PointToScreen(new Point());
Point fp = this.PointToScreen(new Point());
Point delta = new Point(pp.X - fp.X, pp.Y - fp.Y);
Point imgloc = GetImageOffset();
toolTip1.Tag = _fixture;
if (txt.Length > 500)
txt = txt.Substring(0, 500) + "...";
toolTip1.Show(txt, this, loc.X + delta.X + imgloc.X + 32, loc.Y + delta.Y + imgloc.Y + 64);
}
}
}
}
if (refresh)
pict.Invalidate();
}
private void pict_MouseLeave(object sender, EventArgs e) {
_fixture = null;
toolTip1.Hide(this);
toolTip1.Tag = null;
pict.Invalidate();
}
private void tabInfo_SelectedIndexChanged(object sender, EventArgs e) {
_fixture = null;
toolTip1.Hide(this);
toolTip1.Tag = null;
pict.Invalidate();
}
private void pict_Paint(object sender, PaintEventArgs e) {
Graphics g = e.Graphics;
if (_graphics != null && _graphics.All.Count > 0) {
var offset = GetImageOffset();
var pen = new Pen(Color.Blue, 1);
if ((Control.ModifierKeys & Keys.Control) == Keys.Control && (Control.ModifierKeys & Keys.Alt) == Keys.Alt) {
var saved = g.Save();
g.TranslateTransform(offset.X, offset.Y);
foreach (var fixture in _graphics.All)
g.DrawPath(pen, fixture.Path);
g.Restore(saved);
}
else if (_fixture != null) {
var saved = g.Save();
g.TranslateTransform(offset.X, offset.Y);
g.DrawPath(pen, _fixture.Path);
g.Restore(saved);
}
}
}
private Point GetImageOffset() {
if (pict.SizeMode != PictureBoxSizeMode.CenterImage)
return new Point();
var image = pict.Image;
Debug.Assert(image != null);
if (image == null)
return new Point();
int dx = (pict.Width - image.Width) / 2;
int dy = (pict.Height - image.Height) / 2;
return new Point(dx, dy);
}
private void timer1_Tick(object sender, EventArgs e) {
// We update from a timer because we are loading images on a separate
// thread and we can't call directly into the UI from that thread.
ListViewItem item = GetSelectedItem();
ObjectExtractor obj = item != null ? (ObjectExtractor)item.Tag : null;
Preview preview = obj != null ? obj.GetPreview(false) : null;
SetPreview(preview);
}
}
}