576 lines
28 KiB
C#
576 lines
28 KiB
C#
/*
|
|
This file is part of the TSpdf (R) project.
|
|
Copyright (c) 1987-2023 TSpdf
|
|
Authors: TSpdf Software.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License version 3
|
|
as published by the Free Software Foundation with the addition of the
|
|
following permission added to Section 15 as permitted in Section 7(a):
|
|
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
|
TSpdf GROUP. TSpdf GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
|
|
OF THIRD PARTY RIGHTS
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU Affero General Public License for more details.
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program; if not, see http://www.gnu.org/licenses or write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA, 02110-1301 USA, or download the license from the following URL:
|
|
http://TSpdfpdf.com/terms-of-use/
|
|
|
|
The interactive user interfaces in modified source and object code versions
|
|
of this program must display Appropriate Legal Notices, as required under
|
|
Section 5 of the GNU Affero General Public License.
|
|
|
|
In accordance with Section 7(b) of the GNU Affero General Public License,
|
|
a covered work must retain the producer line in every PDF that is created
|
|
or manipulated using TSpdf.
|
|
|
|
You can be released from the requirements of the license by purchasing
|
|
a commercial license. Buying such a license is mandatory as soon as you
|
|
develop commercial activities involving the TSpdf software without
|
|
disclosing the source code of your own applications.
|
|
These activities include: offering paid services to customers as an ASP,
|
|
serving PDFs on the fly in a web application, shipping TSpdf with a closed
|
|
source product.
|
|
|
|
For more information, please contact TSpdf Software Corp. at this
|
|
address: sales@TSpdfpdf.com
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using TSpdf.Commons.Utils;
|
|
using TSpdf.IO.Font.Constants;
|
|
using TSpdf.IO.Image;
|
|
using TSpdf.Kernel.Colors;
|
|
using TSpdf.Kernel.Font;
|
|
using TSpdf.Kernel.Geom;
|
|
using TSpdf.Kernel.Pdf.Action;
|
|
using TSpdf.Kernel.Pdf.Annot;
|
|
using TSpdf.Kernel.Pdf.Canvas;
|
|
using TSpdf.Kernel.Pdf.Canvas.Parser;
|
|
using TSpdf.Kernel.Pdf.Navigation;
|
|
using TSpdf.Kernel.Pdf.Xobject;
|
|
using TSpdf.Test;
|
|
|
|
namespace TSpdf.Kernel.Pdf {
|
|
[NUnit.Framework.Category("IntegrationTest")]
|
|
public class PageFlushingTest : ExtendedTSpdfTest {
|
|
private static readonly String sourceFolder = TSpdf.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
|
|
.CurrentContext.TestDirectory) + "/resources/TSpdf/kernel/pdf/PageFlushingTest/";
|
|
|
|
private static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
|
|
+ "/test/TSpdf/kernel/pdf/PageFlushingTest/";
|
|
|
|
[NUnit.Framework.OneTimeSetUp]
|
|
public static void BeforeClass() {
|
|
CreateOrClearDestinationFolder(destinationFolder);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void BaseWriting01() {
|
|
// not all objects are made indirect before closing
|
|
int total = 414;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 0;
|
|
Test("baseWriting01.pdf", PageFlushingTest.DocMode.WRITING, PageFlushingTest.FlushMode.NONE, PageFlushingTest.PagesOp
|
|
.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void PageFlushWriting01() {
|
|
int total = 715;
|
|
int flushedExpected = 400;
|
|
int notReadExpected = 0;
|
|
Test("pageFlushWriting01.pdf", PageFlushingTest.DocMode.WRITING, PageFlushingTest.FlushMode.PAGE_FLUSH, PageFlushingTest.PagesOp
|
|
.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void UnsafeDeepFlushWriting01() {
|
|
int total = 816;
|
|
// 100 still hanging: new font dictionaries on every page shall not be flushed before closing
|
|
int flushedExpected = 702;
|
|
int notReadExpected = 0;
|
|
Test("unsafeDeepFlushWriting01.pdf", PageFlushingTest.DocMode.WRITING, PageFlushingTest.FlushMode.UNSAFE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void AppendModeFlushWriting01() {
|
|
int total = 715;
|
|
int flushedExpected = 400;
|
|
int notReadExpected = 0;
|
|
Test("appendModeFlushWriting01.pdf", PageFlushingTest.DocMode.WRITING, PageFlushingTest.FlushMode.APPEND_MODE
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void BaseReading01() {
|
|
int total = 817;
|
|
int flushedExpected = 0;
|
|
// link annots, line annots, actions and images: one hundred of each
|
|
int notReadExpected = 402;
|
|
Test("baseReading01.pdf", PageFlushingTest.DocMode.READING, PageFlushingTest.FlushMode.NONE, PageFlushingTest.PagesOp
|
|
.READ, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void ReleaseDeepReading01() {
|
|
int total = 817;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 804;
|
|
Test("releaseDeepReading01.pdf", PageFlushingTest.DocMode.READING, PageFlushingTest.FlushMode.RELEASE_DEEP
|
|
, PageFlushingTest.PagesOp.READ, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void BaseStamping01() {
|
|
// not all objects are made indirect before closing
|
|
int total = 1618;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 603;
|
|
Test("baseStamping01.pdf", PageFlushingTest.DocMode.STAMPING, PageFlushingTest.FlushMode.NONE, PageFlushingTest.PagesOp
|
|
.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void PageFlushStamping01() {
|
|
int total = 2219;
|
|
int flushedExpected = 1200;
|
|
int notReadExpected = 403;
|
|
Test("pageFlushStamping01.pdf", PageFlushingTest.DocMode.STAMPING, PageFlushingTest.FlushMode.PAGE_FLUSH,
|
|
PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void UnsafeDeepFlushStamping01() {
|
|
int total = 2420;
|
|
// 200 still hanging: new font dictionaries on every page shall not be flushed before closing
|
|
int flushedExpected = 1602;
|
|
int notReadExpected = 603;
|
|
Test("unsafeDeepFlushStamping01.pdf", PageFlushingTest.DocMode.STAMPING, PageFlushingTest.FlushMode.UNSAFE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void AppendModeFlushStamping01() {
|
|
int total = 2219;
|
|
// 300 less than with page#flush, because of not modified released objects
|
|
int flushedExpected = 900;
|
|
int notReadExpected = 703;
|
|
Test("appendModeFlushStamping01.pdf", PageFlushingTest.DocMode.STAMPING, PageFlushingTest.FlushMode.APPEND_MODE
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void ReleaseDeepStamping01() {
|
|
int total = 1618;
|
|
int flushedExpected = 0;
|
|
// new objects cannot be released
|
|
int notReadExpected = 703;
|
|
Test("releaseDeepStamping01.pdf", PageFlushingTest.DocMode.STAMPING, PageFlushingTest.FlushMode.RELEASE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void BaseAppendMode01() {
|
|
int total = 1618;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 603;
|
|
Test("baseAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.NONE, PageFlushingTest.PagesOp
|
|
.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void PageFlushAppendMode01() {
|
|
int total = 2219;
|
|
int flushedExpected = 900;
|
|
int notReadExpected = 403;
|
|
Test("pageFlushAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.PAGE_FLUSH,
|
|
PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void UnsafeDeepFlushAppendMode01() {
|
|
int total = 2420;
|
|
// 200 still hanging: new font dictionaries on every page shall not be flushed before closing
|
|
int flushedExpected = 1502;
|
|
int notReadExpected = 703;
|
|
Test("unsafeDeepFlushAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.UNSAFE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void AppendModeFlushAppendMode01() {
|
|
int total = 2219;
|
|
// 600 still hanging: every new page contains image, font and action
|
|
int flushedExpected = 900;
|
|
int notReadExpected = 703;
|
|
Test("appendModeFlushAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.APPEND_MODE
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void ReleaseDeepAppendMode01() {
|
|
int total = 1618;
|
|
int flushedExpected = 0;
|
|
// new objects cannot be released
|
|
int notReadExpected = 703;
|
|
Test("releaseDeepAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.RELEASE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void BaseLightAppendMode01() {
|
|
int total = 1018;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 603;
|
|
Test("baseLightAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.NONE, PageFlushingTest.PagesOp
|
|
.MODIFY_LIGHTLY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void PageFlushLightAppendMode01() {
|
|
int total = 1318;
|
|
int flushedExpected = 500;
|
|
// in default PdfPage#flush annotations are always read and attempted to be flushed.
|
|
int notReadExpected = 403;
|
|
Test("pageFlushLightAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.PAGE_FLUSH
|
|
, PageFlushingTest.PagesOp.MODIFY_LIGHTLY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void UnsafeDeepFlushLightAppendMode01() {
|
|
int total = 1318;
|
|
int flushedExpected = 600;
|
|
int notReadExpected = 703;
|
|
Test("unsafeDeepFlushLightAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.UNSAFE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY_LIGHTLY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void AppendModeFlushLightAppendMode01() {
|
|
int total = 1318;
|
|
// resources are not flushed, here it's font dictionaries for every page which in any case shall not be flushed before closing.
|
|
int flushedExpected = 500;
|
|
int notReadExpected = 703;
|
|
Test("appendModeFlushLightAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.APPEND_MODE
|
|
, PageFlushingTest.PagesOp.MODIFY_LIGHTLY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void ReleaseDeepLightAppendMode01() {
|
|
int total = 1018;
|
|
int flushedExpected = 0;
|
|
int notReadExpected = 703;
|
|
Test("releaseDeepLightAppendMode01.pdf", PageFlushingTest.DocMode.APPEND, PageFlushingTest.FlushMode.RELEASE_DEEP
|
|
, PageFlushingTest.PagesOp.MODIFY_LIGHTLY, total, flushedExpected, notReadExpected);
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void ModifyAnnotationOnlyAppendMode() {
|
|
String input = sourceFolder + "100pages.pdf";
|
|
String output = destinationFolder + "modifyAnnotOnly.pdf";
|
|
PdfDocument pdfDoc = new PdfDocument(new PdfReader(input), new PdfWriter(output), new StampingProperties()
|
|
.UseAppendMode());
|
|
PdfPage page = pdfDoc.GetPage(1);
|
|
PdfIndirectReference pageIndRef = page.GetPdfObject().GetIndirectReference();
|
|
PdfDictionary annotObj = page.GetAnnotations()[0].SetRectangle(new PdfArray(new Rectangle(0, 0, 300, 300))
|
|
).SetPage(page).GetPdfObject();
|
|
PageFlushingHelper flushingHelper = new PageFlushingHelper(pdfDoc);
|
|
flushingHelper.AppendModeFlush(1);
|
|
// annotation is flushed
|
|
NUnit.Framework.Assert.IsTrue(annotObj.IsFlushed());
|
|
// page is not flushed
|
|
NUnit.Framework.Assert.IsFalse(pageIndRef.CheckState(PdfObject.FLUSHED));
|
|
// page is released
|
|
NUnit.Framework.Assert.IsNull(pageIndRef.refersTo);
|
|
// exception is not thrown
|
|
pdfDoc.Close();
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void SetLinkDestinationToPageAppendMode() {
|
|
String input = sourceFolder + "100pages.pdf";
|
|
String output = destinationFolder + "setLinkDestinationToPageAppendMode.pdf";
|
|
PdfDocument pdfDoc = new PdfDocument(new PdfReader(input), new PdfWriter(output), new StampingProperties()
|
|
.UseAppendMode());
|
|
PdfPage page1 = pdfDoc.GetPage(1);
|
|
PdfPage page2 = pdfDoc.GetPage(2);
|
|
PdfIndirectReference page1IndRef = page1.GetPdfObject().GetIndirectReference();
|
|
PdfIndirectReference page2IndRef = page2.GetPdfObject().GetIndirectReference();
|
|
PdfDictionary aDict = ((PdfLinkAnnotation)page1.GetAnnotations()[0]).GetAction();
|
|
new PdfAction(aDict).Put(PdfName.D, PdfExplicitDestination.CreateXYZ(page2, 300, 400, 1).GetPdfObject());
|
|
PageFlushingHelper flushingHelper = new PageFlushingHelper(pdfDoc);
|
|
flushingHelper.AppendModeFlush(2);
|
|
flushingHelper.UnsafeFlushDeep(1);
|
|
// annotation is flushed
|
|
NUnit.Framework.Assert.IsTrue(aDict.IsFlushed());
|
|
// page is not flushed
|
|
NUnit.Framework.Assert.IsFalse(page1IndRef.CheckState(PdfObject.FLUSHED));
|
|
// page is released
|
|
NUnit.Framework.Assert.IsNull(page1IndRef.refersTo);
|
|
// page is not flushed
|
|
NUnit.Framework.Assert.IsFalse(page2IndRef.CheckState(PdfObject.FLUSHED));
|
|
// page is released
|
|
NUnit.Framework.Assert.IsNull(page2IndRef.refersTo);
|
|
// exception is not thrown
|
|
pdfDoc.Close();
|
|
}
|
|
|
|
[NUnit.Framework.Test]
|
|
public virtual void FlushSelfContainingObjectsWritingMode() {
|
|
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new MemoryStream()));
|
|
PdfDictionary pageDict = pdfDoc.AddNewPage().GetPdfObject();
|
|
PdfDictionary dict1 = new PdfDictionary();
|
|
pageDict.Put(new PdfName("dict1"), dict1);
|
|
PdfArray arr1 = new PdfArray();
|
|
pageDict.Put(new PdfName("arr1"), arr1);
|
|
dict1.Put(new PdfName("dict1"), dict1);
|
|
dict1.Put(new PdfName("arr1"), arr1);
|
|
arr1.Add(arr1);
|
|
arr1.Add(dict1);
|
|
arr1.MakeIndirect(pdfDoc);
|
|
dict1.MakeIndirect(pdfDoc);
|
|
PageFlushingHelper flushingHelper = new PageFlushingHelper(pdfDoc);
|
|
flushingHelper.UnsafeFlushDeep(1);
|
|
NUnit.Framework.Assert.IsTrue(dict1.IsFlushed());
|
|
NUnit.Framework.Assert.IsTrue(arr1.IsFlushed());
|
|
pdfDoc.Close();
|
|
}
|
|
|
|
// exception is not thrown
|
|
[NUnit.Framework.Test]
|
|
public virtual void FlushingPageResourcesMadeIndependent() {
|
|
String inputFile = sourceFolder + "100pagesSharedResDict.pdf";
|
|
String outputFile = destinationFolder + "flushingPageResourcesMadeIndependent.pdf";
|
|
PdfDocument pdf = new PdfDocument(new PdfReader(inputFile), new PdfWriter(outputFile));
|
|
int numOfAddedXObjectsPerPage = 10;
|
|
for (int i = 1; i <= pdf.GetNumberOfPages(); ++i) {
|
|
PdfPage sourcePage = pdf.GetPage(i);
|
|
PdfDictionary res = sourcePage.GetPdfObject().GetAsDictionary(PdfName.Resources);
|
|
PdfDictionary resClone = new PdfDictionary();
|
|
// clone dictionary manually to ensure this object is direct and is flushed together with the page
|
|
foreach (KeyValuePair<PdfName, PdfObject> e in res.EntrySet()) {
|
|
resClone.Put(e.Key, e.Value.Clone());
|
|
}
|
|
sourcePage.GetPdfObject().Put(PdfName.Resources, resClone);
|
|
PdfCanvas pdfCanvas = new PdfCanvas(sourcePage);
|
|
pdfCanvas.SaveState();
|
|
for (int j = 0; j < numOfAddedXObjectsPerPage; ++j) {
|
|
PdfImageXObject xObject = new PdfImageXObject(ImageDataFactory.Create(sourceFolder + "simple.jpg"));
|
|
pdfCanvas.AddXObjectFittedIntoRectangle(xObject, new Rectangle(36, 720 - j * 150, 20, 20));
|
|
xObject.MakeIndirect(pdf).Flush();
|
|
}
|
|
pdfCanvas.RestoreState();
|
|
pdfCanvas.Release();
|
|
sourcePage.Flush();
|
|
}
|
|
VerifyFlushedObjectsNum(pdf, 1416, 1400, 0);
|
|
pdf.Close();
|
|
PrintOutputPdfNameAndDir(outputFile);
|
|
PdfDocument result = new PdfDocument(new PdfReader(outputFile));
|
|
PdfObject page15Res = result.GetPage(15).GetPdfObject().Get(PdfName.Resources, false);
|
|
PdfObject page34Res = result.GetPage(34).GetPdfObject().Get(PdfName.Resources, false);
|
|
NUnit.Framework.Assert.IsTrue(page15Res.IsDictionary());
|
|
NUnit.Framework.Assert.AreEqual(numOfAddedXObjectsPerPage, ((PdfDictionary)page15Res).GetAsDictionary(PdfName
|
|
.XObject).Size());
|
|
NUnit.Framework.Assert.IsTrue(page34Res.IsDictionary());
|
|
NUnit.Framework.Assert.AreNotEqual(page15Res, page34Res);
|
|
result.Close();
|
|
}
|
|
|
|
private static void Test(String filename, PageFlushingTest.DocMode docMode, PageFlushingTest.FlushMode flushMode
|
|
, PageFlushingTest.PagesOp pagesOp, int total, int flushedExpected, int notReadExpected) {
|
|
String input = sourceFolder + "100pages.pdf";
|
|
String output = destinationFolder + filename;
|
|
PdfDocument pdfDoc;
|
|
switch (docMode) {
|
|
case PageFlushingTest.DocMode.WRITING: {
|
|
pdfDoc = new PdfDocument(new PdfWriter(output));
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.DocMode.READING: {
|
|
pdfDoc = new PdfDocument(new PdfReader(input));
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.DocMode.STAMPING: {
|
|
pdfDoc = new PdfDocument(new PdfReader(input), new PdfWriter(output));
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.DocMode.APPEND: {
|
|
pdfDoc = new PdfDocument(new PdfReader(input), new PdfWriter(output), new StampingProperties().UseAppendMode
|
|
());
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
throw new InvalidOperationException();
|
|
}
|
|
}
|
|
PageFlushingHelper flushingHelper = new PageFlushingHelper(pdfDoc);
|
|
PdfFont font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA);
|
|
PdfImageXObject xObject = new PdfImageXObject(ImageDataFactory.Create(sourceFolder + "TSpdf.png"));
|
|
if (docMode != PageFlushingTest.DocMode.WRITING) {
|
|
for (int i = 0; i < 100; ++i) {
|
|
PdfPage page = pdfDoc.GetPage(i + 1);
|
|
switch (pagesOp) {
|
|
case PageFlushingTest.PagesOp.READ: {
|
|
PdfTextExtractor.GetTextFromPage(page);
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.PagesOp.MODIFY: {
|
|
AddContentToPage(page, font, xObject);
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.PagesOp.MODIFY_LIGHTLY: {
|
|
AddBasicContent(page, font);
|
|
break;
|
|
}
|
|
}
|
|
switch (flushMode) {
|
|
case PageFlushingTest.FlushMode.UNSAFE_DEEP: {
|
|
flushingHelper.UnsafeFlushDeep(i + 1);
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.RELEASE_DEEP: {
|
|
flushingHelper.ReleaseDeep(i + 1);
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.APPEND_MODE: {
|
|
flushingHelper.AppendModeFlush(i + 1);
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.PAGE_FLUSH: {
|
|
page.Flush();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (docMode != PageFlushingTest.DocMode.READING && pagesOp == PageFlushingTest.PagesOp.MODIFY) {
|
|
for (int i = 0; i < 100; ++i) {
|
|
PdfPage page = pdfDoc.AddNewPage();
|
|
AddContentToPage(page, font, xObject);
|
|
switch (flushMode) {
|
|
case PageFlushingTest.FlushMode.UNSAFE_DEEP: {
|
|
flushingHelper.UnsafeFlushDeep(pdfDoc.GetNumberOfPages());
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.RELEASE_DEEP: {
|
|
flushingHelper.ReleaseDeep(pdfDoc.GetNumberOfPages());
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.APPEND_MODE: {
|
|
flushingHelper.AppendModeFlush(pdfDoc.GetNumberOfPages());
|
|
break;
|
|
}
|
|
|
|
case PageFlushingTest.FlushMode.PAGE_FLUSH: {
|
|
page.Flush();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
VerifyFlushedObjectsNum(pdfDoc, total, flushedExpected, notReadExpected);
|
|
pdfDoc.Close();
|
|
}
|
|
|
|
private static void VerifyFlushedObjectsNum(PdfDocument pdfDoc, int total, int flushedExpected, int notReadExpected
|
|
) {
|
|
int flushedActual = 0;
|
|
int notReadActual = 0;
|
|
for (int i = 0; i < pdfDoc.GetXref().Size(); ++i) {
|
|
PdfIndirectReference indRef = pdfDoc.GetXref().Get(i);
|
|
if (indRef.CheckState(PdfObject.FLUSHED)) {
|
|
++flushedActual;
|
|
}
|
|
else {
|
|
if (!indRef.IsFree() && indRef.refersTo == null) {
|
|
++notReadActual;
|
|
}
|
|
}
|
|
}
|
|
if (pdfDoc.GetXref().Size() != total || flushedActual != flushedExpected || notReadActual != notReadExpected
|
|
) {
|
|
NUnit.Framework.Assert.Fail(MessageFormatUtil.Format("\nExpected total: {0}, flushed: {1}, not read: {2};"
|
|
+ "\nbut actual was: {3}, flushed: {4}, not read: {5}.", total, flushedExpected, notReadExpected, pdfDoc
|
|
.GetXref().Size(), flushedActual, notReadActual));
|
|
}
|
|
NUnit.Framework.Assert.AreEqual(total, pdfDoc.GetXref().Size(), "wrong num of total objects");
|
|
NUnit.Framework.Assert.AreEqual(flushedExpected, flushedActual, "wrong num of flushed objects");
|
|
NUnit.Framework.Assert.AreEqual(notReadExpected, notReadActual, "wrong num of not read objects");
|
|
}
|
|
|
|
private static void AddContentToPage(PdfPage pdfPage, PdfFont font, PdfImageXObject xObject) {
|
|
PdfCanvas canvas = AddBasicContent(pdfPage, font);
|
|
canvas.SaveState().Rectangle(250, 500, 100, 100).Fill().RestoreState();
|
|
PdfFont courier = PdfFontFactory.CreateFont(StandardFonts.COURIER);
|
|
courier.MakeIndirect(pdfPage.GetDocument());
|
|
canvas.SaveState().BeginText().MoveText(36, 650).SetFontAndSize(courier, 16).ShowText("Hello Courier!").EndText
|
|
().RestoreState();
|
|
canvas.SaveState().Circle(100, 400, 25).Fill().RestoreState();
|
|
canvas.SaveState().RoundRectangle(100, 650, 100, 100, 10).Fill().RestoreState();
|
|
canvas.SaveState().SetLineWidth(10).RoundRectangle(250, 650, 100, 100, 10).Stroke().RestoreState();
|
|
canvas.SaveState().SetLineWidth(5).Arc(400, 650, 550, 750, 0, 180).Stroke().RestoreState();
|
|
canvas.SaveState().SetLineWidth(5).MoveTo(400, 550).CurveTo(500, 570, 450, 450, 550, 550).Stroke().RestoreState
|
|
();
|
|
canvas.AddXObjectFittedIntoRectangle(xObject, new Rectangle(100, 500, 400, xObject.GetHeight()));
|
|
PdfImageXObject xObject2 = new PdfImageXObject(ImageDataFactory.Create(sourceFolder + "TSpdf.png"));
|
|
xObject2.MakeIndirect(pdfPage.GetDocument());
|
|
canvas.AddXObjectFittedIntoRectangle(xObject2, new Rectangle(100, 500, 400, xObject2.GetHeight()));
|
|
}
|
|
|
|
private static PdfCanvas AddBasicContent(PdfPage pdfPage, PdfFont font) {
|
|
Rectangle lineAnnotRect = new Rectangle(0, 0, PageSize.A4.GetRight(), PageSize.A4.GetTop());
|
|
pdfPage.AddAnnotation(new PdfLinkAnnotation(new Rectangle(100, 600, 100, 20)).SetAction(PdfAction.CreateURI
|
|
("http://TSpdfpdf.com"))).AddAnnotation(new PdfLineAnnotation(lineAnnotRect, new float[] { lineAnnotRect
|
|
.GetX(), lineAnnotRect.GetY(), lineAnnotRect.GetRight(), lineAnnotRect.GetTop() }).SetColor(ColorConstants
|
|
.BLACK));
|
|
PdfCanvas canvas = new PdfCanvas(pdfPage);
|
|
canvas.Rectangle(100, 100, 100, 100).Fill();
|
|
canvas.SaveState().BeginText().SetTextMatrix(AffineTransform.GetRotateInstance(Math.PI / 4, 36, 350)).SetFontAndSize
|
|
(font, 72).ShowText("Hello Helvetica!").EndText().RestoreState();
|
|
return canvas;
|
|
}
|
|
|
|
private enum DocMode {
|
|
WRITING,
|
|
READING,
|
|
STAMPING,
|
|
APPEND
|
|
}
|
|
|
|
private enum FlushMode {
|
|
NONE,
|
|
PAGE_FLUSH,
|
|
UNSAFE_DEEP,
|
|
RELEASE_DEEP,
|
|
APPEND_MODE
|
|
}
|
|
|
|
private enum PagesOp {
|
|
NONE,
|
|
READ,
|
|
MODIFY,
|
|
MODIFY_LIGHTLY
|
|
}
|
|
}
|
|
}
|