+ /// This is the equivalent Java code for iText 7 of the C# code for iTextSharp 5
+ /// in the question.
+ ///
+ /// Author: mkl.
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void TestCreateLocalLinkInRotatedCell() {
+ String outFileName = destinationFolder + "linkInRotatedCell.pdf";
+ String cmpFileName = sourceFolder + "cmp_linkInRotatedCell.pdf";
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
+ Document document = new Document(pdfDocument);
+ Table table = new Table(2);
+ Link chunk = new Link("Click here", PdfAction.CreateURI("http://itextpdf.com/"));
+ table.AddCell(new Cell().Add(new Paragraph().Add(chunk)).SetRotationAngle(Math.PI / 2));
+ chunk = new Link("Click here 2", PdfAction.CreateURI("http://itextpdf.com/"));
+ table.AddCell(new Paragraph().Add(chunk));
+ document.Add(table);
+ document.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void RotatedLinkAtFixedPosition() {
+ String outFileName = destinationFolder + "rotatedLinkAtFixedPosition.pdf";
+ String cmpFileName = sourceFolder + "cmp_rotatedLinkAtFixedPosition.pdf";
+ Document doc = new Document(new PdfDocument(new PdfWriter(outFileName)));
+ PdfAction action = PdfAction.CreateURI("http://itextpdf.com/", false);
+ Link link = new Link("TestLink", action);
+ doc.Add(new Paragraph(link).SetRotationAngle(Math.PI / 4).SetFixedPosition(300, 623, 100));
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
+ ///
+ ///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
+ [NUnit.Framework.Test]
+ public virtual void RotatedLinkInnerRotation() {
+ String outFileName = destinationFolder + "rotatedLinkInnerRotation.pdf";
+ String cmpFileName = sourceFolder + "cmp_rotatedLinkInnerRotation.pdf";
+ Document doc = new Document(new PdfDocument(new PdfWriter(outFileName)));
+ PdfAction action = PdfAction.CreateURI("http://itextpdf.com/", false);
+ Link link = new Link("TestLink", action);
+ Paragraph p = new Paragraph(link).SetRotationAngle(Math.PI / 4).SetBackgroundColor(Color.RED);
+ Div div = new Div().Add(p).SetRotationAngle(Math.PI / 3).SetBackgroundColor(Color.BLUE);
+ doc.Add(div);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
}
}
diff --git a/itext.tests/itext.layout.tests/itext/layout/ListTest.cs b/itext.tests/itext.layout.tests/itext/layout/ListTest.cs
index 87a5e9f3b4..08828bb488 100644
--- a/itext.tests/itext.layout.tests/itext/layout/ListTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/ListTest.cs
@@ -1,14 +1,16 @@
using System;
using System.Collections.Generic;
-using System.IO;
+using iText.IO;
using iText.IO.Image;
using iText.Kernel.Colors;
+using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Xobject;
using iText.Kernel.Utils;
using iText.Layout.Element;
using iText.Layout.Properties;
using iText.Test;
+using iText.Test.Attributes;
namespace iText.Layout {
public class ListTest : ExtendedITextTest {
@@ -28,7 +30,7 @@ public static void BeforeClass() {
public virtual void NestedListTest01() {
String outFileName = destinationFolder + "nestedListTest01.pdf";
String cmpFileName = sourceFolder + "cmp_nestedListTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
List romanList2 = new List(ListNumberingType.ROMAN_LOWER).SetSymbolIndent(20).SetMarginLeft(25).Add("One")
.Add("Two").Add("Three");
@@ -49,7 +51,7 @@ public virtual void NestedListTest01() {
public virtual void ListNumberingTest01() {
String outFileName = destinationFolder + "listNumberingTest01.pdf";
String cmpFileName = sourceFolder + "cmp_listNumberingTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
IList lists = new List();
lists.Add(new List(ListNumberingType.DECIMAL));
@@ -72,13 +74,70 @@ public virtual void ListNumberingTest01() {
, "diff"));
}
+ ///
+ ///
+ [NUnit.Framework.Test]
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 8)]
+ public virtual void AddListOnShortPage1() {
+ String outFileName = destinationFolder + "addListOnShortPage1.pdf";
+ String cmpFileName = sourceFolder + "cmp_addListOnShortPage1.pdf";
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc, new PageSize(500, 60));
+ ListItem item = new ListItem();
+ ListItem nestedItem = new ListItem();
+ List list = new List(ListNumberingType.DECIMAL);
+ List nestedList = new List(ListNumberingType.ENGLISH_UPPER);
+ List nestedNestedList = new List(ListNumberingType.GREEK_LOWER);
+ nestedNestedList.Add("Hello");
+ nestedNestedList.Add("World");
+ nestedItem.Add(nestedNestedList);
+ nestedList.Add(nestedItem);
+ nestedList.Add(nestedItem);
+ item.Add(nestedList);
+ list.Add(item);
+ list.Add(item);
+ doc.Add(list);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
+ ///
+ ///
+ [NUnit.Framework.Test]
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 3)]
+ public virtual void AddListOnShortPage2() {
+ String outFileName = destinationFolder + "addListOnShortPage2.pdf";
+ String cmpFileName = sourceFolder + "cmp_addListOnShortPage2.pdf";
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc, new PageSize(500, 130));
+ List list = new List(ListNumberingType.DECIMAL);
+ ListItem item = new ListItem();
+ item.Add(new Paragraph("Red"));
+ item.Add(new Paragraph("Is"));
+ item.Add(new Paragraph("The"));
+ item.Add(new Paragraph("Color"));
+ item.Add(new Image(ImageDataFactory.Create(sourceFolder + "red.png")));
+ List nestedList = new List(ListNumberingType.ENGLISH_UPPER);
+ nestedList.Add("Hello");
+ nestedList.Add("World");
+ item.Add(nestedList);
+ for (int i = 0; i < 3; i++) {
+ list.Add(item);
+ }
+ doc.Add(list);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
///
///
[NUnit.Framework.Test]
public virtual void DivInListItemTest01() {
String outFileName = destinationFolder + "divInListItemTest01.pdf";
String cmpFileName = sourceFolder + "cmp_divInListItemTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
ListItem item = new ListItem();
item.Add(new Div().Add(new Paragraph("text")));
@@ -94,7 +153,7 @@ public virtual void DivInListItemTest01() {
public virtual void ListOverflowTest01() {
String outFileName = destinationFolder + "listOverflowTest01.pdf";
String cmpFileName = sourceFolder + "cmp_listOverflowTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph("Test String");
List list = new List(ListNumberingType.DECIMAL).Add("first string").Add("second string").Add("third string"
@@ -114,7 +173,7 @@ public virtual void ListOverflowTest01() {
public virtual void ListOverflowTest02() {
String outFileName = destinationFolder + "listOverflowTest02.pdf";
String cmpFileName = sourceFolder + "cmp_listOverflowTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph("Test String");
List list = new List(ListNumberingType.DECIMAL).Add("first string");
@@ -135,7 +194,7 @@ public virtual void ListOverflowTest02() {
public virtual void ListOverflowTest03() {
String outFileName = destinationFolder + "listOverflowTest03.pdf";
String cmpFileName = sourceFolder + "cmp_listOverflowTest03.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph("Test String");
List list = new List(ListNumberingType.DECIMAL).SetItemStartIndex(10).Add("first string").Add("second string"
@@ -155,7 +214,7 @@ public virtual void ListOverflowTest03() {
public virtual void ListEmptyItemTest01() {
String outFileName = destinationFolder + "listEmptyItemTest01.pdf";
String cmpFileName = sourceFolder + "cmp_listEmptyItemTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
List list = new List(ListNumberingType.GREEK_LOWER);
list.Add(new ListItem()).Add(new ListItem()).Add(new ListItem()).Add("123").Add((ListItem)new ListItem().Add
@@ -172,7 +231,7 @@ public virtual void ListEmptyItemTest01() {
public virtual void ImageInListTest01() {
String outFileName = destinationFolder + "imageInListTest01.pdf";
String cmpFileName = sourceFolder + "cmp_imageInListTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
List list = new List(ListNumberingType.GREEK_LOWER);
PdfImageXObject xObject = new PdfImageXObject(ImageDataFactory.Create(sourceFolder + "Desert.jpg"));
@@ -191,7 +250,7 @@ public virtual void ImageInListTest01() {
public virtual void ListItemAlignmentTest01() {
String outFileName = destinationFolder + "listItemAlignmentTest01.pdf";
String cmpFileName = sourceFolder + "cmp_listItemAlignmentTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
List list = new List(ListNumberingType.DECIMAL).SetListSymbolAlignment(ListSymbolAlignment.LEFT);
for (int i = 1; i <= 30; i++) {
diff --git a/itext.tests/itext.layout.tests/itext/layout/OverflowTest.cs b/itext.tests/itext.layout.tests/itext/layout/OverflowTest.cs
index 22a0d1ecce..94ed3b30d1 100644
--- a/itext.tests/itext.layout.tests/itext/layout/OverflowTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/OverflowTest.cs
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using System.Text;
using iText.IO.Font;
using iText.Kernel.Colors;
@@ -27,7 +26,7 @@ public static void BeforeClass() {
public virtual void TextOverflowTest01() {
String outFileName = destinationFolder + "textOverflowTest01.pdf";
String cmpFileName = sourceFolder + "cmp_textOverflowTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
StringBuilder text = new StringBuilder();
for (int i = 0; i < 1000; i++) {
@@ -46,7 +45,7 @@ public virtual void TextOverflowTest01() {
public virtual void TextOverflowTest02() {
String outFileName = destinationFolder + "textOverflowTest02.pdf";
String cmpFileName = sourceFolder + "cmp_textOverflowTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
iText.Layout.Element.Text overflowText = new iText.Layout.Element.Text("This is a long-long and large text which will not overflow"
).SetFontSize(19).SetFontColor(Color.RED);
@@ -64,7 +63,7 @@ public virtual void TextOverflowTest02() {
public virtual void TextOverflowTest03() {
String outFileName = destinationFolder + "textOverflowTest03.pdf";
String cmpFileName = sourceFolder + "cmp_textOverflowTest03.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
iText.Layout.Element.Text overflowText = new iText.Layout.Element.Text("This is a long-long and large text which will overflow"
).SetFontSize(25).SetFontColor(Color.RED);
@@ -82,7 +81,7 @@ public virtual void TextOverflowTest03() {
public virtual void TextOverflowTest04() {
String outFileName = destinationFolder + "textOverflowTest04.pdf";
String cmpFileName = sourceFolder + "cmp_textOverflowTest04.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph("ThisIsALongTextWithNoSpacesSoSplittingShouldBeForcedInThisCase").SetFontSize(20
));
diff --git a/itext.tests/itext.layout.tests/itext/layout/PositioningTest.cs b/itext.tests/itext.layout.tests/itext/layout/PositioningTest.cs
index 5a9ff7a7d9..f5ab7a6e2d 100644
--- a/itext.tests/itext.layout.tests/itext/layout/PositioningTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/PositioningTest.cs
@@ -1,9 +1,10 @@
using System;
-using System.IO;
+using iText.IO.Image;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
+using iText.Kernel.Pdf.Xobject;
using iText.Kernel.Utils;
using iText.Layout.Borders;
using iText.Layout.Element;
@@ -28,7 +29,7 @@ public static void BeforeClass() {
public virtual void RelativePositioningTest01() {
String outFileName = destinationFolder + "relativePositioningTest01.pdf";
String cmpFileName = sourceFolder + "cmp_relativePositioningTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph().SetBorder(new SolidBorder(new DeviceGray(0), 5)).SetWidth(300).SetPaddings(20
, 20, 20, 20).Add("Here is a line of text.").Add(new Text("This part is shifted\n up a bit,").SetRelativePosition
@@ -46,7 +47,7 @@ public virtual void RelativePositioningTest01() {
public virtual void RelativePositioningTest02() {
String outFileName = destinationFolder + "relativePositioningTest02.pdf";
String cmpFileName = sourceFolder + "cmp_relativePositioningTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph().SetBorder(new SolidBorder(new DeviceGray(0), 5)).SetWidth(180).SetPaddings(20
, 20, 20, 20).Add("Here is a line of text.").Add(new Text("This part is shifted\n up a bit,").SetRelativePosition
@@ -64,7 +65,7 @@ public virtual void RelativePositioningTest02() {
public virtual void FixedPositioningTest01() {
String outFileName = destinationFolder + "fixedPositioningTest01.pdf";
String cmpFileName = sourceFolder + "cmp_fixedPositioningTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
List list = new List(ListNumberingType.ROMAN_UPPER).SetFixedPosition(2, 300, 300, 50).SetBackgroundColor(Color
.BLUE).SetHeight(100);
@@ -81,7 +82,7 @@ public virtual void FixedPositioningTest01() {
public virtual void FixedPositioningTest02() {
String outFileName = destinationFolder + "fixedPositioningTest02.pdf";
String cmpFileName = sourceFolder + "cmp_fixedPositioningTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.GetPdfDocument().AddNewPage();
new PdfCanvas(document.GetPdfDocument().GetPage(1)).SetFillColor(Color.BLACK).Rectangle(300, 300, 100, 100
@@ -100,7 +101,7 @@ public virtual void FixedPositioningTest02() {
public virtual void ShowTextAlignedTest01() {
String outFileName = destinationFolder + "showTextAlignedTest01.pdf";
String cmpFileName = sourceFolder + "cmp_showTextAlignedTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
pdfDocument.AddNewPage();
PdfCanvas canvas = new PdfCanvas(pdfDocument.GetLastPage());
@@ -165,7 +166,7 @@ public virtual void ShowTextAlignedTest01() {
public virtual void ShowTextAlignedTest02() {
String outFileName = destinationFolder + "showTextAlignedTest02.pdf";
String cmpFileName = sourceFolder + "cmp_showTextAlignedTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
String watermarkText = "WATERMARK";
Paragraph watermark = new Paragraph(watermarkText);
@@ -181,6 +182,26 @@ public virtual void ShowTextAlignedTest02() {
, "diff"));
}
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void ShowTextAlignedTest03() {
+ String outFileName = destinationFolder + "showTextAlignedTest03.pdf";
+ String cmpFileName = sourceFolder + "cmp_showTextAlignedTest03.pdf";
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc);
+ iText.Layout.Element.Image img = new Image(ImageDataFactory.Create(sourceFolder + "bruno.jpg"));
+ float width = img.GetImageScaledWidth();
+ float height = img.GetImageScaledHeight();
+ PdfFormXObject template = new PdfFormXObject(new Rectangle(width, height));
+ iText.Layout.Canvas canvas = new iText.Layout.Canvas(template, pdfDoc);
+ canvas.Add(img).ShowTextAligned("HELLO BRUNO", width / 2, height / 2, TextAlignment.CENTER);
+ doc.Add(new iText.Layout.Element.Image(template));
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
private void DrawCross(PdfCanvas canvas, float x, float y) {
DrawLine(canvas, x - 50, y, x + 50, y);
DrawLine(canvas, x, y - 50, x, y + 50);
diff --git a/itext.tests/itext.layout.tests/itext/layout/PreLayoutTest.cs b/itext.tests/itext.layout.tests/itext/layout/PreLayoutTest.cs
index 56e45cd953..37dda4ae54 100644
--- a/itext.tests/itext.layout.tests/itext/layout/PreLayoutTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/PreLayoutTest.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Text;
using iText.IO.Font;
using iText.Kernel.Font;
@@ -31,7 +30,7 @@ public static void BeforeClass() {
public virtual void PreLayoutTest01() {
String outFileName = destinationFolder + "preLayoutTest01.pdf";
String cmpFileName = sourceFolder + "cmp_preLayoutTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument, PageSize.Default, false);
IList pageNumberTexts = new List();
IList pageNumberRenderers = new List();
@@ -66,7 +65,7 @@ public virtual void PreLayoutTest01() {
public virtual void PreLayoutTest02() {
String outFileName = destinationFolder + "preLayoutTest02.pdf";
String cmpFileName = sourceFolder + "cmp_preLayoutTest02.pdf";
- PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDoc, PageSize.Default, false);
document.Add(new Paragraph("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
StringBuilder text = new StringBuilder();
diff --git a/itext.tests/itext.layout.tests/itext/layout/RotationTest.cs b/itext.tests/itext.layout.tests/itext/layout/RotationTest.cs
index 80841d26ba..e392638d6c 100644
--- a/itext.tests/itext.layout.tests/itext/layout/RotationTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/RotationTest.cs
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using iText.IO;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
@@ -46,7 +45,7 @@ public static void BeforeClass() {
public virtual void FixedTextRotationTest01() {
String outFileName = destinationFolder + "fixedTextRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "fixedTextRotationTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
SolidBorder border = new SolidBorder(0.5f);
int x1 = 350;
@@ -73,7 +72,7 @@ public virtual void FixedTextRotationTest01() {
public virtual void FixedTextRotationTest02() {
String outFileName = destinationFolder + "fixedTextRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "fixedTextRotationTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
String longText = "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
+ "ooooooooooooooooooooooooooooooooooooooooooooooooooooooooong text";
@@ -90,7 +89,7 @@ public virtual void FixedTextRotationTest02() {
public virtual void FixedTextRotationTest03() {
String outFileName = destinationFolder + "fixedTextRotationTest03.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "fixedTextRotationTest03.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
String simpleText = "text simple text";
float x = 50;
@@ -111,7 +110,7 @@ public virtual void FixedTextRotationTest03() {
public virtual void FixedTextRotationTest04() {
String outFileName = destinationFolder + "fixedTextRotationTest04.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "fixedTextRotationTest04.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
String simpleText = "text simple text";
float x = 50;
@@ -128,18 +127,19 @@ public virtual void FixedTextRotationTest04() {
///
///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
[NUnit.Framework.Test]
public virtual void StaticTextRotationTest01() {
String outFileName = destinationFolder + "staticTextRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "staticTextRotationTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p = new Paragraph();
for (int i = 0; i < 7; ++i) {
p.Add(para2Text);
}
document.Add(p.SetRotationAngle((68 * Math.PI / 180)).SetBackgroundColor(Color.BLUE));
- document.Add(new Paragraph("text line text line text line text line text line text line text line text line text line text line text line text line text line"
+ document.Add(new Paragraph("text line text line text line text line text line text line text line text line text line text line text line"
));
document.Close();
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
@@ -148,11 +148,12 @@ public virtual void StaticTextRotationTest01() {
///
///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
[NUnit.Framework.Test]
public virtual void StaticTextRotationTest02() {
String outFileName = destinationFolder + "staticTextRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "staticTextRotationTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text));
document.Add(new Paragraph(para2Text).SetRotationAngle((Math.PI / 12)));
@@ -170,7 +171,7 @@ public virtual void StaticTextRotationTest02() {
public virtual void StaticTextRotationTest03() {
String outFileName = destinationFolder + "staticTextRotationTest03.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "staticTextRotationTest03.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text));
document.Add(new Paragraph(para2Text).SetRotationAngle((Math.PI / 6)).SetBackgroundColor(Color.RED));
@@ -187,7 +188,7 @@ public virtual void StaticTextRotationTest03() {
public virtual void StaticTextRotationTest04() {
String outFileName = destinationFolder + "staticTextRotationTest04.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "staticTextRotationTest04.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text));
document.Add(new Paragraph("short text string").SetRotationAngle((Math.PI / 6)).SetBackgroundColor(Color.RED
@@ -204,7 +205,7 @@ public virtual void StaticTextRotationTest04() {
public virtual void SplitTextRotationTest01() {
String outFileName = destinationFolder + "splitTextRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "splitTextRotationTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text));
document.Add(new Paragraph(para1Text).SetRotationAngle((Math.PI / 4)));
@@ -218,11 +219,12 @@ public virtual void SplitTextRotationTest01() {
///
///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
[NUnit.Framework.Test]
public virtual void SplitTextRotationTest02() {
String outFileName = destinationFolder + "splitTextRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "splitTextRotationTest02.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text));
document.Add(new Paragraph(para1Text));
@@ -240,12 +242,13 @@ public virtual void SplitTextRotationTest02() {
///
///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
[NUnit.Framework.Test]
public virtual void RotationInfiniteLoopTest01() {
String fileName = "rotationInfiniteLoopTest01.pdf";
String outFileName = destinationFolder + fileName;
String cmpFileName = sourceFolder + cmpPrefix + fileName;
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
pdfDocument.SetDefaultPageSize(PageSize.A5.Rotate());
Document document = new Document(pdfDocument);
document.Add(new Paragraph(para1Text).SetRotationAngle((Math.PI / 2)));
@@ -256,13 +259,13 @@ public virtual void RotationInfiniteLoopTest01() {
///
///
- [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 1)]
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
[NUnit.Framework.Test]
public virtual void RotationInfiniteLoopTest02() {
String fileName = "rotationInfiniteLoopTest02.pdf";
String outFileName = destinationFolder + fileName;
String cmpFileName = sourceFolder + cmpPrefix + fileName;
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
pdfDocument.SetDefaultPageSize(PageSize.A5.Rotate());
Document document = new Document(pdfDocument);
document.Add(new List().Add(para1Text).SetRotationAngle((Math.PI / 2)));
@@ -277,9 +280,7 @@ public virtual void RotationInfiniteLoopTest02() {
public virtual void TableRotationTest02() {
String outFileName = destinationFolder + "tableRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "tableRotationTest02.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 50, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1").SetRotationAngle
((Math.PI / 2)))).AddCell(new Cell().Add(new Paragraph("cell 1, 2").SetRotationAngle((Math.PI / 3)))).
@@ -291,15 +292,49 @@ public virtual void TableRotationTest02() {
, "diff"));
}
+ ///
+ ///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
+ [NUnit.Framework.Test]
+ public virtual void TableRotationTest03() {
+ String outFileName = destinationFolder + "tableRotationTest03.pdf";
+ String cmpFileName = sourceFolder + cmpPrefix + "tableRotationTest03.pdf";
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc);
+ Table table = new Table(new float[] { 25, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1").SetRotationAngle
+ ((Math.PI / 2)))).AddCell(new Cell().Add(new Paragraph("cell 1, 2").SetRotationAngle((Math.PI / 3)))).
+ AddCell(new Cell().Add(new Paragraph("cell 2, 1"))).AddCell(new Cell().Add(new Paragraph("cell 2, 2"))
+ ).AddCell(new Cell().Add(new Paragraph("cell 3, 1").SetRotationAngle(-(Math.PI / 2)))).AddCell(new Cell
+ ().Add(new Paragraph("cell 3, 2").SetRotationAngle((Math.PI))));
+ doc.Add(table);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void CellRotationTest01() {
+ String outFileName = destinationFolder + "cellRotationTest01.pdf";
+ String cmpFileName = sourceFolder + cmpPrefix + "cellRotationTest01.pdf";
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc);
+ Table table = new Table(1).SetWidth(50).AddCell(new Cell().Add(new Paragraph("Hello")).SetRotationAngle(Math
+ .PI * 70 / 180.0).SetBackgroundColor(Color.GREEN));
+ doc.Add(table);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , "diff"));
+ }
+
///
///
[NUnit.Framework.Test]
public virtual void DivRotationTest01() {
String outFileName = destinationFolder + "divRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "divRotationTest01.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Div div = new Div().SetBackgroundColor(Color.GREEN);
div.Add(new Paragraph(para1Text).SetBackgroundColor(Color.RED)).SetRotationAngle(Math.PI / 4);
@@ -314,14 +349,12 @@ public virtual void DivRotationTest01() {
///
///
- [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 1)]
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 2)]
[NUnit.Framework.Test]
public virtual void DivRotationTest02() {
String outFileName = destinationFolder + "divRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "divRotationTest02.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph(para1Text));
doc.Add(new Paragraph(para1Text));
@@ -343,9 +376,7 @@ public virtual void DivRotationTest02() {
public virtual void ListRotationTest01() {
String outFileName = destinationFolder + "listRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "listRotationTest01.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph(para1Text));
List list = new List().SetRotationAngle(3 * Math.PI / 4).SetBackgroundColor(Color.GREEN);
@@ -365,9 +396,7 @@ public virtual void ListRotationTest01() {
public virtual void ListRotationTest02() {
String outFileName = destinationFolder + "listRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "listRotationTest02.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph(para1Text));
doc.Add(new Paragraph(para1Text));
@@ -390,9 +419,7 @@ public virtual void ListRotationTest02() {
public virtual void AlignedTextRotationTest01() {
String outFileName = destinationFolder + "alignedTextRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "alignedTextRotationTest01.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph(para1Text));
Paragraph p = new Paragraph();
@@ -412,9 +439,7 @@ public virtual void AlignedTextRotationTest01() {
public virtual void InnerRotationTest01() {
String outFileName = destinationFolder + "innerRotationTest01.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "innerRotationTest01.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Div().SetBackgroundColor(Color.GREEN).SetHeight(300).SetWidth(300).Add(new Div().SetBackgroundColor
(Color.RED).SetHeight(100).SetWidth(100).SetRotationAngle(Math.PI / 4)).SetRotationAngle(Math.PI / 8));
@@ -425,14 +450,13 @@ public virtual void InnerRotationTest01() {
///
///
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
[NUnit.Framework.Test]
public virtual void InnerRotationTest02() {
String outFileName = destinationFolder + "innerRotationTest02.pdf";
String cmpFileName = sourceFolder + cmpPrefix + "innerRotationTest02.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
- Document doc = new Document(pdfDoc);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc, new PageSize(6400, 6400));
String longText = para1Text + para2Text + para3Text;
String extremeLongText = longText + longText + longText;
doc.Add(new Div().SetBackgroundColor(Color.GREEN).SetHeight(300).SetWidth(300).Add(new Div().SetBackgroundColor
diff --git a/itext.tests/itext.layout.tests/itext/layout/TableTest.cs b/itext.tests/itext.layout.tests/itext/layout/TableTest.cs
index 509a221673..36bcb4e563 100644
--- a/itext.tests/itext.layout.tests/itext/layout/TableTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/TableTest.cs
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using iText.IO;
using iText.IO.Image;
using iText.IO.Util;
@@ -42,9 +41,7 @@ public virtual void SimpleTableTest01() {
String testName = "tableTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 50, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1"))).AddCell
(new Cell().Add(new Paragraph("cell 1, 2")));
@@ -61,9 +58,7 @@ public virtual void SimpleTableTest02() {
String testName = "tableTest02.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 50, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1"))).AddCell
(new Cell().Add(new Paragraph("cell 1, 2"))).AddCell(new Cell().Add(new Paragraph("cell 2, 1"))).AddCell
@@ -82,9 +77,7 @@ public virtual void SimpleTableTest03() {
String testName = "tableTest03.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent1 = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n";
@@ -107,9 +100,7 @@ public virtual void SimpleTableTest04() {
String testName = "tableTest04.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -132,9 +123,7 @@ public virtual void SimpleTableTest05() {
String testName = "tableTest05.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -155,9 +144,7 @@ public virtual void SimpleTableTest06() {
String testName = "tableTest06.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -178,9 +165,7 @@ public virtual void SimpleTableTest07() {
String testName = "tableTest07.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -201,9 +186,7 @@ public virtual void SimpleTableTest08() {
String testName = "tableTest08.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -229,9 +212,7 @@ public virtual void SimpleTableTest09() {
String testName = "tableTest09.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -259,9 +240,7 @@ public virtual void SimpleTableTest10() {
String testName = "tableTest10.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph("Table 1"));
Table table = new Table(new float[] { 100, 100 }).AddCell(new Cell().Add(new Paragraph("1, 1"))).AddCell(new
@@ -293,9 +272,7 @@ public virtual void SimpleTableTest11() {
String testName = "tableTest11.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String shortTextContent = "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.";
String middleTextContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
@@ -325,9 +302,7 @@ public virtual void SimpleTableTest12() {
String testName = "tableTest12.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String shortTextContent = "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.";
String middleTextContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
@@ -362,9 +337,7 @@ public virtual void SimpleTableTest13() {
String testName = "tableTest13.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String shortTextContent = "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.";
String middleTextContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
@@ -392,9 +365,7 @@ public virtual void SimpleTableTest14() {
String testName = "tableTest14.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -424,9 +395,7 @@ public virtual void SimpleTableTest15() {
String testName = "tableTest15.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -458,9 +427,7 @@ public virtual void SimpleTableTest16() {
String testName = "tableTest16.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -486,9 +453,7 @@ public virtual void SimpleTableTest17() {
String testName = "tableTest17.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 50, 50, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1"))).AddCell
(new Cell().Add(new Paragraph("cell 1, 2"))).AddCell(new Cell().Add(new Paragraph("cell 1, 3")));
@@ -513,9 +478,7 @@ public virtual void SimpleTableTest18() {
String testName = "tableTest18.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
doc.Add(new Paragraph(textContent));
Table table = new Table(new float[] { 50, 50, 50 }).AddCell(new Cell().Add(new Paragraph("cell 1, 1"))).AddCell
@@ -541,9 +504,7 @@ public virtual void SimpleTableTest19() {
String testName = "tableTest19.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 130, 130, 260 }).AddCell(new Cell(3, 2).Add(new Paragraph("cell 1:2, 1:3\n"
+ textContent + textContent))).AddCell(new Cell().Add(new Paragraph("cell 1, 3\n" + textContent))).AddCell
@@ -569,9 +530,7 @@ public virtual void SimpleTableTest20() {
String testName = "tableTest20.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 130, 130, 260 }).AddCell(new Cell().Add(new iText.Layout.Element.Image
(ImageDataFactory.Create(sourceFolder + "red.png")))).AddCell(new Cell().Add(new Paragraph("cell 4, 2\n"
@@ -595,9 +554,7 @@ public virtual void SimpleTableTest21() {
String testName = "tableTest21.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -626,9 +583,7 @@ public virtual void BigRowspanTest01() {
String testName = "bigRowspanTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -654,9 +609,7 @@ public virtual void BigRowspanTest02() {
String testName = "bigRowspanTest02.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -682,9 +635,7 @@ public virtual void BigRowspanTest03() {
String testName = "bigRowspanTest03.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -708,9 +659,7 @@ public virtual void BigRowspanTest04() {
String testName = "bigRowspanTest04.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.\n"
+ "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.\n" + "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci.\n";
@@ -736,9 +685,7 @@ public virtual void DifferentPageOrientationTest01() {
String testName = "differentPageOrientationTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String textContent1 = "Video provides a powerful way to help you prove your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also type a keyword to search online for the video that best fits your document.";
String textContent2 = "To make your document look professionally produced, Word provides header, footer, cover page, and text box designs that complement each other. For example, you can add a matching cover page, header, and sidebar. Click Insert and then choose the elements you want from the different galleries.";
@@ -781,7 +728,7 @@ public virtual void ToLargeElementWithKeepTogetherPropertyInTableTest01() {
String testName = "toLargeElementWithKeepTogetherPropertyInTableTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Table table = new Table(1);
Cell cell = new Cell();
@@ -795,7 +742,7 @@ public virtual void ToLargeElementWithKeepTogetherPropertyInTableTest01() {
cell.Add(p);
table.AddCell(cell);
doc.Add(table);
- pdfDoc.Close();
+ doc.Close();
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
, testName + "_diff"));
}
@@ -808,8 +755,7 @@ public virtual void ToLargeElementInTableTest01() {
String testName = "toLargeElementInTableTest01.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- PdfDocument pdfDoc = new PdfDocument(new PdfWriter(new FileStream(destinationFolder + "toLargeElementInTableTest01.pdf"
- , FileMode.Create)));
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(destinationFolder + "toLargeElementInTableTest01.pdf"));
Document doc = new Document(pdfDoc);
Table table = new Table(new float[] { 5 });
Cell cell = new Cell();
@@ -817,7 +763,7 @@ public virtual void ToLargeElementInTableTest01() {
cell.Add(p);
table.AddCell(cell);
doc.Add(table);
- pdfDoc.Close();
+ doc.Close();
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
, testName + "_diff"));
}
@@ -829,9 +775,7 @@ public virtual void NestedTableSkipHeaderFooterTest() {
String testName = "nestedTableSkipHeaderFooter.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc, PageSize.A4.Rotate());
Table table = new Table(5);
table.AddHeaderCell(new Cell(1, 5).Add(new Paragraph("Table XYZ (Continued)")));
@@ -851,26 +795,30 @@ public virtual void NestedTableSkipHeaderFooterTest() {
///
///
- [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 1)]
+ [LogMessage(LogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA, Count = 9)]
[NUnit.Framework.Test]
- public virtual void SplitTableOnLowPage() {
- String testName = "splitTableOnLowPage.pdf";
+ public virtual void SplitTableOnShortPage() {
+ String testName = "splitTableOnShortPage.pdf";
String outFileName = destinationFolder + testName;
String cmpFileName = sourceFolder + "cmp_" + testName;
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
- Document doc = new Document(pdfDoc, new PageSize(300, 120));
+ Document doc = new Document(pdfDoc, new PageSize(300, 90));
doc.Add(new Paragraph("Table with setKeepTogether(true):"));
- Table table = new Table(2);
+ Table table = new Table(3);
table.SetKeepTogether(true);
- table.SetMarginTop(10);
Cell cell = new Cell(3, 1);
cell.Add("G");
cell.Add("R");
cell.Add("P");
table.AddCell(cell);
- table.AddCell("row 1");
- table.AddCell("row 2");
- table.AddCell("row 3");
+ table.AddCell("middle row 1");
+ cell = new Cell(3, 1);
+ cell.Add("A");
+ cell.Add("B");
+ cell.Add("C");
+ table.AddCell(cell);
+ table.AddCell("middle row 2");
+ table.AddCell("middle row 3");
doc.Add(table);
doc.Add(new AreaBreak());
doc.Add(new Paragraph("Table with setKeepTogether(false):"));
@@ -880,5 +828,31 @@ public virtual void SplitTableOnLowPage() {
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
, testName + "_diff"));
}
+
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void ImageInTableTest_HA() {
+ String testName = "imageInTableTest_HA.pdf";
+ String outFileName = destinationFolder + testName;
+ String cmpFileName = sourceFolder + "cmp_" + testName;
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
+ Document doc = new Document(pdfDoc);
+ PdfImageXObject xObject = new PdfImageXObject(ImageDataFactory.CreatePng(UrlUtil.ToURL(sourceFolder + "itext.png"
+ )));
+ iText.Layout.Element.Image imageL = new iText.Layout.Element.Image(xObject);
+ imageL.SetHorizontalAlignment(HorizontalAlignment.LEFT);
+ iText.Layout.Element.Image imageC = new iText.Layout.Element.Image(xObject);
+ imageC.SetHorizontalAlignment(HorizontalAlignment.CENTER);
+ iText.Layout.Element.Image imageR = new iText.Layout.Element.Image(xObject);
+ imageR.SetHorizontalAlignment(HorizontalAlignment.RIGHT);
+ doc.Add(new Paragraph("Table"));
+ Table table = new Table(1).AddCell(new Cell().Add(imageL)).AddCell(new Cell().Add(imageC)).AddCell(new Cell
+ ().Add(imageR));
+ doc.Add(table);
+ doc.Close();
+ NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, destinationFolder
+ , testName + "_diff"));
+ }
}
}
diff --git a/itext.tests/itext.layout.tests/itext/layout/TabsTest.cs b/itext.tests/itext.layout.tests/itext/layout/TabsTest.cs
index c547e1c1cb..5d91a66428 100644
--- a/itext.tests/itext.layout.tests/itext/layout/TabsTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/TabsTest.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
@@ -48,9 +47,7 @@ public static void BeforeClass() {
public virtual void DefaultTabsTest() {
String outFileName = destinationFolder + "defaultTabTest.pdf";
String cmpFileName = sourceFolder + "cmp_defaultTabTest.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
Paragraph p = new Paragraph();
AddTabbedTextToParagraph(p, text0, new float[0], null, null, null);
@@ -181,9 +178,7 @@ public virtual void SeveralTabsInRowTest() {
public virtual void OutOfPageBoundsTest() {
String outFileName = destinationFolder + "outOfPageBoundsTest.pdf";
String cmpFileName = sourceFolder + "cmp_outOfPageBoundsTest.pdf";
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
//tabstops out of page bounds
Paragraph p = new Paragraph();
@@ -231,9 +226,7 @@ public virtual void OutOfPageBoundsTest() {
///
private Document InitDocument(String outFileName) {
- FileStream file = new FileStream(outFileName, FileMode.Create);
- PdfWriter writer = new PdfWriter(file);
- PdfDocument pdfDoc = new PdfDocument(writer);
+ PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
pdfDoc.SetDefaultPageSize(PageSize.A4.Rotate());
return new Document(pdfDoc);
}
diff --git a/itext.tests/itext.layout.tests/itext/layout/TextWritingTest.cs b/itext.tests/itext.layout.tests/itext/layout/TextWritingTest.cs
index 2aca074c95..ba91679c0f 100644
--- a/itext.tests/itext.layout.tests/itext/layout/TextWritingTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/TextWritingTest.cs
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using iText.IO.Font;
using iText.Kernel.Colors;
using iText.Kernel.Font;
@@ -29,7 +28,7 @@ public virtual void TextRiseTest01() {
// CountryChunks example
String outFileName = destinationFolder + "textRiseTest01.pdf";
String cmpFileName = sourceFolder + "cmp_textRiseTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
PdfFont font = PdfFontFactory.CreateFont(FontConstants.HELVETICA_BOLD);
for (int i = 0; i < 10; i++) {
@@ -50,7 +49,7 @@ public virtual void TextRiseTest01() {
public virtual void TextRenderingModeTest01() {
String outFileName = destinationFolder + "textRenderingModeTest01.pdf";
String cmpFileName = sourceFolder + "cmp_textRenderingModeTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Text text1 = new Text("This is a fill and stroke text").SetTextRenderingMode(PdfCanvasConstants.TextRenderingMode
.FILL_STROKE).SetStrokeColor(Color.RED).SetStrokeWidth(0.1f);
@@ -73,7 +72,7 @@ public virtual void TextRenderingModeTest01() {
public virtual void LeadingTest01() {
String outFileName = destinationFolder + "leadingTest01.pdf";
String cmpFileName = sourceFolder + "cmp_leadingTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
Paragraph p1 = new Paragraph("first, leading of 150").SetFixedLeading(150);
document.Add(p1);
@@ -93,7 +92,7 @@ public virtual void LeadingTest01() {
public virtual void FirstLineIndentTest01() {
String outFileName = destinationFolder + "firstLineIndentTest01.pdf";
String cmpFileName = sourceFolder + "cmp_firstLineIndentTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.SetProperty(Property.FIRST_LINE_INDENT, 25);
document.Add(new Paragraph("Portable Document Format (PDF) is a file format used to present documents in a manner "
@@ -129,7 +128,7 @@ public virtual void FirstLineIndentTest01() {
public virtual void CharSpacingTest01() {
String outFileName = destinationFolder + "charSpacingTest01.pdf";
String cmpFileName = sourceFolder + "cmp_charSpacingTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
PdfFont font = PdfFontFactory.CreateFont(FontConstants.HELVETICA);
Paragraph p = new Paragraph().SetFont(font);
@@ -152,7 +151,7 @@ public virtual void CharSpacingTest01() {
public virtual void WordSpacingTest01() {
String outFileName = destinationFolder + "wordSpacingTest01.pdf";
String cmpFileName = sourceFolder + "cmp_wordSpacingTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
PdfFont font = PdfFontFactory.CreateFont(FontConstants.HELVETICA);
Paragraph p = new Paragraph().SetFont(font);
@@ -176,7 +175,7 @@ public virtual void WordSpacingTest01() {
public virtual void FontStyleSimulationTest01() {
String outFileName = destinationFolder + "fontStyleSimulationTest01.pdf";
String cmpFileName = sourceFolder + "cmp_fontStyleSimulationTest01.pdf";
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(outFileName, FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Document document = new Document(pdfDocument);
document.Add(new Paragraph("I'm underlined").SetUnderline());
document.Add(new Paragraph("I'm strikethrough").SetLineThrough());
diff --git a/itext.tests/itext.layout.tests/itext/layout/XMPWriterTest.cs b/itext.tests/itext.layout.tests/itext/layout/XMPWriterTest.cs
index 59ce1c9369..61a61ed06d 100644
--- a/itext.tests/itext.layout.tests/itext/layout/XMPWriterTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/XMPWriterTest.cs
@@ -1,5 +1,4 @@
using System;
-using System.IO;
using iText.IO.Source;
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
@@ -26,8 +25,7 @@ public static void BeforeClass() {
public virtual void CreatePdfTest() {
String fileName = "xmp_metadata.pdf";
// step 1
- PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new FileStream(destinationFolder + "xmp_metadata.pdf"
- , FileMode.Create)));
+ PdfDocument pdfDocument = new PdfDocument(new PdfWriter(destinationFolder + "xmp_metadata.pdf"));
Document document = new Document(pdfDocument);
// step 2
ByteArrayOutputStream os = new ByteArrayOutputStream();
diff --git a/itext.tests/itext.layout.tests/itext/layout/properties/PropertyTest.cs b/itext.tests/itext.layout.tests/itext/layout/properties/PropertyTest.cs
index fcb35b033b..f16ae90810 100644
--- a/itext.tests/itext.layout.tests/itext/layout/properties/PropertyTest.cs
+++ b/itext.tests/itext.layout.tests/itext/layout/properties/PropertyTest.cs
@@ -15,7 +15,7 @@ public virtual void PropertyUniquenessTest() {
int value = (int)field.GetValue(null);
maxFieldValue = Math.Max(maxFieldValue, value);
if (fieldValues.Contains(value)) {
- NUnit.Framework.Assert.Fail("Multiple fields with same value");
+ NUnit.Framework.Assert.Fail(String.Format("Multiple fields with same value: {0}", value));
}
fieldValues.Add(value);
}
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AlignmentTest/cmp_justifyAlignmentTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AlignmentTest/cmp_justifyAlignmentTest03.pdf
index ed37b22f45..81a82ff8ea 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AlignmentTest/cmp_justifyAlignmentTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AlignmentTest/cmp_justifyAlignmentTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest01.pdf
index 0b4f4d4e34..031545a7b0 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest02.pdf
index b8a41d8ab8..611f937a75 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_artifactTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest02.pdf
index 49b4b8afc0..d6c39faca1 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest03.pdf
index df19027f09..04962da55b 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_flushingTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest01.pdf
index b113f341c0..5ffc630086 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest02.pdf
index 659ee68753..b1364e05ce 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest03.pdf
index 7c892ab20f..1f66fe1a45 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest04.pdf
index f0193af157..b7054d706f 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest05.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest05.pdf
index 51ce12e0b7..d79e13da4c 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest05.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest05.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest06.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest06.pdf
index 795f1ad061..0d9d43ad3a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest06.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/AutoTaggingTest/cmp_tableTest06.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BackgroundColorTest/cmp_simpleBackgroundColorTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BackgroundColorTest/cmp_simpleBackgroundColorTest.pdf
new file mode 100644
index 0000000000..dec9202ab9
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BackgroundColorTest/cmp_simpleBackgroundColorTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_forcedPlacementTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_forcedPlacementTest01.pdf
new file mode 100644
index 0000000000..cc98f04423
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_forcedPlacementTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_infiniteLoopTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_infiniteLoopTest01.pdf
new file mode 100644
index 0000000000..c705163d76
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_infiniteLoopTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noHorizontalBorderTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noHorizontalBorderTest.pdf
new file mode 100644
index 0000000000..6f6179e810
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noHorizontalBorderTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noVerticalBorderTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noVerticalBorderTest.pdf
new file mode 100644
index 0000000000..34954571a9
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_noVerticalBorderTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_wideBorderTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_wideBorderTest01.pdf
new file mode 100644
index 0000000000..65f53da0e4
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/BorderTest/cmp_wideBorderTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage1.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage1.pdf
new file mode 100644
index 0000000000..d31b616993
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage1.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage2.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage2.pdf
new file mode 100644
index 0000000000..1409191cad
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/DefaultLayoutTest/cmp_addParagraphOnShortPage2.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawCheckCircularReferencesTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawCheckCircularReferencesTest.pdf
index 8414c2a1ed..894b3deae5 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawCheckCircularReferencesTest.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawCheckCircularReferencesTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawTest.pdf
index b81f6efb5e..b500cbab11 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawTest.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_flushOnDrawTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest09.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest09.pdf
new file mode 100644
index 0000000000..7ac0004388
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest09.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest10.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest10.pdf
new file mode 100644
index 0000000000..29f5cea933
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest10.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest11.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest11.pdf
new file mode 100644
index 0000000000..595a4c7022
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest11.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest12.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest12.pdf
new file mode 100644
index 0000000000..4095f15d80
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest12.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest13.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest13.pdf
new file mode 100644
index 0000000000..97258e5eff
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest13.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest14.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest14.pdf
new file mode 100644
index 0000000000..171f5523f9
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ImageTest/cmp_imageTest14.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest01.pdf
new file mode 100644
index 0000000000..80ae14e8b6
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest02.pdf
new file mode 100644
index 0000000000..6bda8d6615
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest03.pdf
new file mode 100644
index 0000000000..2f4c7e36e0
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest04.pdf
new file mode 100644
index 0000000000..c3ad295bf1
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest05.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest05.pdf
new file mode 100644
index 0000000000..239bc185ec
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest05.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest06.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest06.pdf
new file mode 100644
index 0000000000..14b330f5f5
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest06.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest07.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest07.pdf
new file mode 100644
index 0000000000..03ccf3cac4
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest07.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest08.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest08.pdf
new file mode 100644
index 0000000000..f86bb77865
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest08.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest09.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest09.pdf
new file mode 100644
index 0000000000..d9401d1570
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest09.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest10.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest10.pdf
new file mode 100644
index 0000000000..ca52ba1788
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/KeepWithNextTest/cmp_keepWithNextTest10.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest01.pdf
index 0bfc7c7cab..f1664a0ef4 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest02.pdf
index 0a5d37bfb4..1465d94ebe 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01A.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01A.pdf
index c7888ab5e4..cad2abf39c 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01A.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01A.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01B.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01B.pdf
index 2501c3e1fe..a3fac2052e 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01B.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest01B.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest02.pdf
index 58450066d7..9a76fcd701 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest03.pdf
index d10473f025..fcc61e987c 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest04.pdf
index b7f3abb1ef..e559483f70 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LargeElementTest/cmp_largeTableWithHeaderFooterTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorBackgroundTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorBackgroundTest01.pdf
new file mode 100644
index 0000000000..21f178625b
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorBackgroundTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorWidthPercentageTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorWidthPercentageTest01.pdf
new file mode 100644
index 0000000000..d28302cd31
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_lineSeparatorWidthPercentageTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest01.pdf
new file mode 100644
index 0000000000..eb0f786c6c
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest02.pdf
new file mode 100644
index 0000000000..f9a617f869
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LineSeparatorTest/cmp_rotatedLineSeparatorTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_borderedLinkTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_borderedLinkTest.pdf
new file mode 100644
index 0000000000..e0f1b4abfb
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_borderedLinkTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkInRotatedCell.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkInRotatedCell.pdf
new file mode 100644
index 0000000000..2b190f55c4
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkInRotatedCell.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest01.pdf
index 28801a27ea..087aa125ce 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest02.pdf
index 886b224ed2..4af571e4f4 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_linkTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkAtFixedPosition.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkAtFixedPosition.pdf
new file mode 100644
index 0000000000..7a0a6ae31f
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkAtFixedPosition.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkInnerRotation.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkInnerRotation.pdf
new file mode 100644
index 0000000000..d0d735eda0
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/LinkTest/cmp_rotatedLinkInnerRotation.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage1.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage1.pdf
new file mode 100644
index 0000000000..f879df11cb
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage1.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage2.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage2.pdf
new file mode 100644
index 0000000000..7496c68373
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/cmp_addListOnShortPage2.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/red.png b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/red.png
new file mode 100644
index 0000000000..797bcb18f3
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/ListTest/red.png differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/bruno.jpg b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/bruno.jpg
new file mode 100644
index 0000000000..67f19cc50b
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/bruno.jpg differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_fixedPositioningTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_fixedPositioningTest01.pdf
index 3596610400..b65c93d8d1 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_fixedPositioningTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_fixedPositioningTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest01.pdf
index 9354e74f86..be7eedea9b 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest02.pdf
index 481fee3ac7..7e80b4eb96 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest03.pdf
new file mode 100644
index 0000000000..5f88546192
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/PositioningTest/cmp_showTextAlignedTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_alignedTextRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_alignedTextRotationTest01.pdf
index 847f967d60..db69eb7c13 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_alignedTextRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_alignedTextRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_cellRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_cellRotationTest01.pdf
new file mode 100644
index 0000000000..b36868ced1
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_cellRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest01.pdf
index 7a4d573953..9e4accb006 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest02.pdf
index cba2db2a86..fcbc6e92e7 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_divRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest01.pdf
index b4243d82bb..06ff3e1da8 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest02.pdf
index 41430d8312..cf3d0de709 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest03.pdf
index 54e531b646..84cae572e6 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest04.pdf
index 2ac0c678a9..8266155e5f 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_fixedTextRotationTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest01.pdf
index 8ff82eb537..db22b44381 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest02.pdf
index 1a3c10c4a1..d1df9fcd7a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_innerRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest01.pdf
index 9e906c9fa4..97a29020d0 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest02.pdf
index 96eb9ac053..d816938deb 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_listRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest01.pdf
index cecd2e5fb1..b562d8145e 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest02.pdf
index 8e0a09872a..8765fbc631 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_rotationInfiniteLoopTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest01.pdf
index 8d7cc54d4d..53b893855c 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest02.pdf
index 74077af1ce..edbb8cca18 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_splitTextRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest01.pdf
index 776173656e..dbc93abefc 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest02.pdf
index 50eccfe136..caf547729e 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest03.pdf
index 351da2d925..053a11a50e 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest04.pdf
index 0199fc03d8..cbb9037741 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_staticTextRotationTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest02.pdf
index b4d463c073..99b139c537 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest03.pdf
new file mode 100644
index 0000000000..194d54b0f8
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/RotationTest/cmp_tableRotationTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_anchorTabStopsTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_anchorTabStopsTest.pdf
index 884de289bd..91781d2e48 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_anchorTabStopsTest.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_anchorTabStopsTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_outOfPageBoundsTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_outOfPageBoundsTest.pdf
index ec276f4ab6..7c8a1d3609 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_outOfPageBoundsTest.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_outOfPageBoundsTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_severalTabsInRowTest.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_severalTabsInRowTest.pdf
index 4c1650e09c..62a8c60dd5 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_severalTabsInRowTest.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TabTest/cmp_severalTabsInRowTest.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest01.pdf
index 539ea34ec5..f891fcacbc 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest02.pdf
index 84c4fbb35c..0721c7f0e5 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest03.pdf
index 35d2c52fec..62a4e7ae3a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest04.pdf
index 1f432764a6..fa8972d975 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_bigRowspanTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_differentPageOrientationTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_differentPageOrientationTest01.pdf
index 36756682a1..5a9ac8c789 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_differentPageOrientationTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_differentPageOrientationTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_imageInTableTest_HA.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_imageInTableTest_HA.pdf
new file mode 100644
index 0000000000..3a8bf442c2
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_imageInTableTest_HA.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_nestedTableSkipHeaderFooter.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_nestedTableSkipHeaderFooter.pdf
index b8d1d5b435..e5dc81c5ca 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_nestedTableSkipHeaderFooter.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_nestedTableSkipHeaderFooter.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_splitTableOnShortPage.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_splitTableOnShortPage.pdf
new file mode 100644
index 0000000000..25233f8495
Binary files /dev/null and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_splitTableOnShortPage.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest01.pdf
index ef2fb7b8c8..0fb837f7ba 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest02.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest02.pdf
index 44a95dffef..2fb1a571cf 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest02.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest02.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest03.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest03.pdf
index 5fd40553d3..ec02a6de47 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest03.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest03.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest04.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest04.pdf
index d1f549f816..cc3b875c0f 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest04.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest04.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest05.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest05.pdf
index d2e3a20d0c..14c604b1d0 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest05.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest05.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest06.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest06.pdf
index c976ccfe12..e56fa60a7e 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest06.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest06.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest07.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest07.pdf
index ee75fc19e0..70a8768f3a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest07.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest07.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest08.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest08.pdf
index c0385355bf..6736cb87b0 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest08.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest08.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest09.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest09.pdf
index 80d3a0ca81..262bc799d3 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest09.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest09.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest10.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest10.pdf
index bf7b30b027..aab11d05b9 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest10.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest10.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest11.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest11.pdf
index 16d485ff8c..af1956381a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest11.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest11.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest12.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest12.pdf
index d2cbb39a78..6296bb6edf 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest12.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest12.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest13.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest13.pdf
index 5ec17580c8..43e78811a4 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest13.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest13.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest14.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest14.pdf
index 24c1d6e82c..fcdd28fdfe 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest14.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest14.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest15.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest15.pdf
index 9ee54cb058..6aa05dab65 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest15.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest15.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest16.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest16.pdf
index 8a1e392d97..2c497d574f 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest16.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest16.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest17.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest17.pdf
index 37d2e7e1fd..b4aaf1a21a 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest17.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest17.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest18.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest18.pdf
index 33a4ff4e25..c79a56c025 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest18.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest18.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest19.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest19.pdf
index 97613023e3..fcf0f062a2 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest19.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest19.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest20.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest20.pdf
index 851ce18440..c1dd4fdff5 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest20.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest20.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest21.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest21.pdf
index 134363bb28..d63ea5040d 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest21.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_tableTest21.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementInTableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementInTableTest01.pdf
index ba6c0508e1..c4bb48637b 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementInTableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementInTableTest01.pdf differ
diff --git a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementWithKeepTogetherPropertyInTableTest01.pdf b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementWithKeepTogetherPropertyInTableTest01.pdf
index dd51d59629..0688bb85f2 100644
Binary files a/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementWithKeepTogetherPropertyInTableTest01.pdf and b/itext.tests/itext.layout.tests/resources/itext/layout/TableTest/cmp_toLargeElementWithKeepTogetherPropertyInTableTest01.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.pdfa.tests/Properties/AssemblyInfo.cs
index c1072681f5..ed959c8e36 100644
--- a/itext.tests/itext.pdfa.tests/Properties/AssemblyInfo.cs
+++ b/itext.tests/itext.pdfa.tests/Properties/AssemblyInfo.cs
@@ -15,5 +15,7 @@
[assembly: Guid("b7c0e021-71ac-4c97-9a51-8356f1bd53c7")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
+
+[assembly: NUnit.Framework.Timeout(300000)]
diff --git a/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj b/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj
index b10eee0524..7976396785 100644
--- a/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj
+++ b/itext.tests/itext.pdfa.tests/itext.pdfa.tests.csproj
@@ -35,7 +35,7 @@
- ..\..\packages\NUnit.3.2.1\lib\net40\nunit.framework.dll
+ $(SolutionDir)\packages\NUnit.3.2.1\lib\net40\nunit.framework.dll
diff --git a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfA1AnnotationCheckTest.cs b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfA1AnnotationCheckTest.cs
index 8a64dcbe8c..e0c8a313f5 100644
--- a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfA1AnnotationCheckTest.cs
+++ b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfA1AnnotationCheckTest.cs
@@ -115,7 +115,7 @@ public virtual void AnnotationCheckTest05() {
Rectangle rect = new Rectangle(100, 100, 100, 100);
PdfAnnotation annot = new PdfWidgetAnnotation(rect);
annot.SetFlag(PdfAnnotation.PRINT);
- PdfStream s = new PdfStream("Hello World".GetBytes());
+ PdfStream s = new PdfStream("Hello World".GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1));
annot.SetDownAppearance(new PdfDictionary());
annot.SetNormalAppearance(s);
page.AddAnnotation(annot);
diff --git a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFontTest.cs b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFontTest.cs
index a85d30e315..91cf9ffac2 100644
--- a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFontTest.cs
+++ b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFontTest.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using iText.IO.Font;
using iText.Kernel.Colors;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
@@ -226,6 +227,83 @@ public virtual void CidFontCheckTest3() {
CompareResult(outPdf, cmpPdf);
}
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void SymbolicTtfCharEncodingsPdfA1Test01() {
+ // encoding must not be specified
+ CreateDocumentWithFont("symbolicTtfCharEncodingsPdfA1Test01.pdf", "Symbols1.ttf", "", PdfAConformanceLevel
+ .PDF_A_1B);
+ }
+
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void SymbolicTtfCharEncodingsPdfA1Test02() {
+ // if you specify encoding, symbolic font is treated as non-symbolic
+ CreateDocumentWithFont("symbolicTtfCharEncodingsPdfA1Test02.pdf", "Symbols1.ttf", PdfEncodings.MACROMAN, PdfAConformanceLevel
+ .PDF_A_1B);
+ }
+
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void SymbolicTtfCharEncodingsPdfA1Test03() {
+ NUnit.Framework.Assert.That(() => {
+ // if you specify encoding, symbolic font is treated as non-symbolic
+ CreateDocumentWithFont("symbolicTtfCharEncodingsPdfA1Test03.pdf", "Symbols1.ttf", "ISO-8859-1", PdfAConformanceLevel
+ .PDF_A_1B);
+ }
+ , NUnit.Framework.Throws.TypeOf().With.Message.EqualTo(PdfAConformanceException.AllNonSymbolicTrueTypeFontShallSpecifyMacRomanOrWinAnsiEncodingAsTheEncodingEntry));
+;
+ }
+
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void NonSymbolicTtfCharEncodingsPdfA1Test01() {
+ // encoding must be either winansi or macroman, by default winansi is used
+ CreateDocumentWithFont("nonSymbolicTtfCharEncodingsPdfA1Test01.pdf", "FreeSans.ttf", PdfEncodings.WINANSI,
+ PdfAConformanceLevel.PDF_A_1B);
+ }
+
+ ///
+ ///
+ ///
+ [NUnit.Framework.Test]
+ public virtual void NonSymbolicTtfCharEncodingsPdfA1Test02() {
+ NUnit.Framework.Assert.That(() => {
+ // encoding must be either winansi or macroman, by default winansi is used
+ CreateDocumentWithFont("nonSymbolicTtfCharEncodingsPdfA1Test02.pdf", "FreeSans.ttf", "ISO-8859-1", PdfAConformanceLevel
+ .PDF_A_2B);
+ }
+ , NUnit.Framework.Throws.TypeOf().With.Message.EqualTo(PdfAConformanceException.AllNonSymbolicTrueTypeFontShallSpecifyMacRomanEncodingOrWinAnsiEncoding));
+;
+ }
+
+ ///
+ ///
+ private void CreateDocumentWithFont(String outFileName, String fontFileName, String encoding, PdfAConformanceLevel
+ conformanceLevel) {
+ String outPdf = outputDir + outFileName;
+ String cmpPdf = sourceFolder + "cmp/PdfAFontTest/cmp_" + outFileName;
+ PdfWriter writer = new PdfWriter(outPdf);
+ Stream @is = new FileStream(sourceFolder + "sRGB Color Space Profile.icm", FileMode.Open, FileAccess.Read);
+ PdfDocument doc = new PdfADocument(writer, conformanceLevel, new PdfOutputIntent("Custom", "", "http://www.color.org"
+ , "sRGB IEC61966-2.1", @is));
+ PdfPage page = doc.AddNewPage();
+ PdfFont font = PdfFontFactory.CreateFont(sourceFolder + fontFileName, encoding, true);
+ PdfCanvas canvas = new PdfCanvas(page);
+ canvas.SaveState().BeginText().MoveText(36, 700).SetFontAndSize(font, 12).ShowText("Hello World").EndText(
+ ).RestoreState();
+ doc.Close();
+ CompareResult(outPdf, cmpPdf);
+ }
+
///
///
private void CompareResult(String outPdf, String cmpPdf) {
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/Symbols1.ttf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/Symbols1.ttf
new file mode 100644
index 0000000000..5b4f4c79f4
Binary files /dev/null and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/Symbols1.ttf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfA2ActionCheckTest/cmp_pdfA2b_actionCheck15.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfA2ActionCheckTest/cmp_pdfA2b_actionCheck15.pdf
index e02cde9cc1..023485c666 100644
Binary files a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfA2ActionCheckTest/cmp_pdfA2b_actionCheck15.pdf and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfA2ActionCheckTest/cmp_pdfA2b_actionCheck15.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_nonSymbolicTtfCharEncodingsPdfA1Test01.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_nonSymbolicTtfCharEncodingsPdfA1Test01.pdf
new file mode 100644
index 0000000000..da68b9da76
Binary files /dev/null and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_nonSymbolicTtfCharEncodingsPdfA1Test01.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test01.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test01.pdf
new file mode 100644
index 0000000000..1b2caf0db3
Binary files /dev/null and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test01.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test02.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test02.pdf
new file mode 100644
index 0000000000..c21e229fad
Binary files /dev/null and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFontTest/cmp_symbolicTtfCharEncodingsPdfA1Test02.pdf differ
diff --git a/itext.tests/itext.sign.tests/Properties/AssemblyInfo.cs b/itext.tests/itext.sign.tests/Properties/AssemblyInfo.cs
index ffc8e54692..eb2a5f0392 100644
--- a/itext.tests/itext.sign.tests/Properties/AssemblyInfo.cs
+++ b/itext.tests/itext.sign.tests/Properties/AssemblyInfo.cs
@@ -15,5 +15,7 @@
[assembly: Guid("be15bdf3-b184-4e2f-8459-ebee3160e19d")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
+
+[assembly: NUnit.Framework.Timeout(300000)]
diff --git a/itext.tests/itext.sign.tests/itext.sign.tests.csproj b/itext.tests/itext.sign.tests/itext.sign.tests.csproj
index 6d084498be..6431b7517a 100644
--- a/itext.tests/itext.sign.tests/itext.sign.tests.csproj
+++ b/itext.tests/itext.sign.tests/itext.sign.tests.csproj
@@ -35,7 +35,7 @@
- ..\..\packages\NUnit.3.2.1\lib\net40\nunit.framework.dll
+ $(SolutionDir)\packages\NUnit.3.2.1\lib\net40\nunit.framework.dll
diff --git a/itext.tests/itext.sign.tests/itext/signatures/SigningTest.cs b/itext.tests/itext.sign.tests/itext/signatures/SigningTest.cs
index ee93d47ac7..52ebb20d92 100644
--- a/itext.tests/itext.sign.tests/itext/signatures/SigningTest.cs
+++ b/itext.tests/itext.sign.tests/itext/signatures/SigningTest.cs
@@ -93,7 +93,7 @@ public virtual void SigningIntoExistingFieldTest01()
.CADES, "Test 1", "TestCity", null, false);
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, sourceFolder
+ "cmp_" + fileName, destinationFolder, "diff_",
- new Dictionary>{ {1 , IO.Util.JavaUtil.ArraysAsList(new Rectangle(67, 725, 155, 15))}}));
+ new Dictionary>{ {1 , IO.Util.JavaUtil.ArraysAsList(new Rectangle(67, 725, 160, 15))}}));
}
///
@@ -111,7 +111,7 @@ public virtual void SigningIntoExistingFieldTest02()
.CADES, "Test 1", "TestCity", null, false);
NUnit.Framework.Assert.IsNull(new CompareTool().CompareVisually(dest, sourceFolder
+ "cmp_" + fileName, destinationFolder, "diff_",
- new Dictionary> { { 1, IO.Util.JavaUtil.ArraysAsList(new Rectangle(67, 725, 155, 15)) } }));
+ new Dictionary> { { 1, IO.Util.JavaUtil.ArraysAsList(new Rectangle(67, 725, 160, 15)) } }));
}
///
diff --git a/itext/itext.barcodes/Properties/AssemblyInfo.cs b/itext/itext.barcodes/Properties/AssemblyInfo.cs
index 776376d03b..decd87162c 100644
--- a/itext/itext.barcodes/Properties/AssemblyInfo.cs
+++ b/itext/itext.barcodes/Properties/AssemblyInfo.cs
@@ -21,5 +21,5 @@
[assembly: Guid("8694665a-5749-40c6-9e9c-53c686a77ad1")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.barcodes/itext/barcodes/BarcodeCodabar.cs b/itext/itext.barcodes/itext/barcodes/BarcodeCodabar.cs
index 3bca10e667..7a736a7487 100644
--- a/itext/itext.barcodes/itext/barcodes/BarcodeCodabar.cs
+++ b/itext/itext.barcodes/itext/barcodes/BarcodeCodabar.cs
@@ -114,7 +114,7 @@ public static byte[] GetBarsCodabar(String text) {
text = text.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
int len = text.Length;
if (len < 2) {
- throw new ArgumentException(PdfException.CodabarMustHaveAtLeastAStartAndStopCharacter);
+ throw new ArgumentException(PdfException.CodabarMustHaveAtLeastStartAndStopCharacter);
}
if (CHARS.IndexOf(text[0]) < START_STOP_IDX || CHARS.IndexOf(text[len - 1]) < START_STOP_IDX) {
throw new ArgumentException(PdfException.CodabarMustHaveOneAbcdAsStartStopCharacter);
@@ -123,10 +123,10 @@ public static byte[] GetBarsCodabar(String text) {
for (int k = 0; k < len; ++k) {
int idx = CHARS.IndexOf(text[k]);
if (idx >= START_STOP_IDX && k > 0 && k < len - 1) {
- throw new ArgumentException(PdfException.CodabarStartStopCharacterAreOnlyExtremes);
+ throw new ArgumentException(PdfException.InCodabarStartStopCharactersAreOnlyAllowedAtTheExtremes);
}
if (idx < 0) {
- throw new ArgumentException(PdfException.CodabarCharacterOneIsIllegal);
+ throw new ArgumentException(PdfException.IllegalCharacterInCodabarBarcode);
}
System.Array.Copy(BARS[idx], 0, bars, k * 8, 7);
}
diff --git a/itext/itext.barcodes/itext/barcodes/qrcode/EncodeHintType.cs b/itext/itext.barcodes/itext/barcodes/qrcode/EncodeHintType.cs
index 1341838ab4..8933a83537 100644
--- a/itext/itext.barcodes/itext/barcodes/qrcode/EncodeHintType.cs
+++ b/itext/itext.barcodes/itext/barcodes/qrcode/EncodeHintType.cs
@@ -53,6 +53,10 @@ public sealed class EncodeHintType {
public static readonly iText.Barcodes.Qrcode.EncodeHintType CHARACTER_SET = new iText.Barcodes.Qrcode.EncodeHintType
();
+ /// Specifies the minimal version level to use, for example in QR Codes (type Integer).
+ public static readonly iText.Barcodes.Qrcode.EncodeHintType MIN_VERSION_NR = new iText.Barcodes.Qrcode.EncodeHintType
+ ();
+
private EncodeHintType() {
}
}
diff --git a/itext/itext.barcodes/itext/barcodes/qrcode/Encoder.cs b/itext/itext.barcodes/itext/barcodes/qrcode/Encoder.cs
index 4091cd6af3..1109c39040 100644
--- a/itext/itext.barcodes/itext/barcodes/qrcode/Encoder.cs
+++ b/itext/itext.barcodes/itext/barcodes/qrcode/Encoder.cs
@@ -99,6 +99,15 @@ public static void Encode(String content, ErrorCorrectionLevel ecLevel, IDiction
if (encoding == null) {
encoding = DEFAULT_BYTE_MODE_ENCODING;
}
+ int desiredMinVersion = (hints == null || hints.Get(EncodeHintType.MIN_VERSION_NR) == null) ? 1 : (int)hints
+ .Get(EncodeHintType.MIN_VERSION_NR);
+ //Check if desired level is within bounds of [1,40]
+ if (desiredMinVersion < 1) {
+ desiredMinVersion = 1;
+ }
+ if (desiredMinVersion > 40) {
+ desiredMinVersion = 40;
+ }
// Step 1: Choose the mode (encoding).
Mode mode = ChooseMode(content, encoding);
// Step 2: Append "bytes" into "dataBits" in appropriate encoding.
@@ -106,7 +115,7 @@ public static void Encode(String content, ErrorCorrectionLevel ecLevel, IDiction
AppendBytes(content, mode, dataBits, encoding);
// Step 3: Initialize QR code that can contain "dataBits".
int numInputBytes = dataBits.SizeInBytes();
- InitQRCode(numInputBytes, ecLevel, mode, qrCode);
+ InitQRCode(numInputBytes, ecLevel, desiredMinVersion, mode, qrCode);
// Step 4: Build another bit vector that contains header and data.
BitVector headerAndDataBits = new BitVector();
// Step 4.5: Append ECI message if applicable
@@ -238,11 +247,12 @@ private static int ChooseMaskPattern(BitVector bits, ErrorCorrectionLevel ecLeve
/// modify "qrCode".
///
///
- private static void InitQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, Mode mode, QRCode qrCode) {
+ private static void InitQRCode(int numInputBytes, ErrorCorrectionLevel ecLevel, int desiredMinVersion, Mode
+ mode, QRCode qrCode) {
qrCode.SetECLevel(ecLevel);
qrCode.SetMode(mode);
// In the following comments, we use numbers of Version 7-H.
- for (int versionNum = 1; versionNum <= 40; versionNum++) {
+ for (int versionNum = desiredMinVersion; versionNum <= 40; versionNum++) {
Version version = Version.GetVersionForNumber(versionNum);
// numBytes = 196
int numBytes = version.GetTotalCodewords();
diff --git a/itext/itext.font-asian/Properties/AssemblyInfo.cs b/itext/itext.font-asian/Properties/AssemblyInfo.cs
index 4e62608a76..e314ade3ee 100644
--- a/itext/itext.font-asian/Properties/AssemblyInfo.cs
+++ b/itext/itext.font-asian/Properties/AssemblyInfo.cs
@@ -15,5 +15,5 @@
[assembly: Guid("0f10190c-7611-4378-a157-03bf2ed78e30")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.forms/Properties/AssemblyInfo.cs b/itext/itext.forms/Properties/AssemblyInfo.cs
index 8097d8f4aa..41c0f2cf6e 100644
--- a/itext/itext.forms/Properties/AssemblyInfo.cs
+++ b/itext/itext.forms/Properties/AssemblyInfo.cs
@@ -20,5 +20,5 @@
[assembly: Guid("2257d7e6-2873-4cfb-ac3c-b24765a4b3b1")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.forms/itext.forms.csproj b/itext/itext.forms/itext.forms.csproj
index fd32bbf386..d159beac66 100644
--- a/itext/itext.forms/itext.forms.csproj
+++ b/itext/itext.forms/itext.forms.csproj
@@ -31,6 +31,7 @@
TRACEprompt4
+ falsebin\Release\itext.forms.xml
diff --git a/itext/itext.forms/itext/forms/FormsExtensions.cs b/itext/itext.forms/itext/forms/FormsExtensions.cs
index 8abbd1c241..cbb7c57d63 100644
--- a/itext/itext.forms/itext/forms/FormsExtensions.cs
+++ b/itext/itext.forms/itext/forms/FormsExtensions.cs
@@ -46,6 +46,7 @@ source product.
using System.Linq;
using System.Collections.Generic;
using System.IO;
+using System.Text;
namespace iText.Forms {
internal static class FormsExtensions {
@@ -69,8 +70,24 @@ public static byte[] GetBytes(this String str) {
return System.Text.Encoding.UTF8.GetBytes(str);
}
+ public static byte[] GetBytes(this String str, Encoding encoding) {
+ return encoding.GetBytes(str);
+ }
+
public static T[] ToArray(this ICollection col, T[] toArray) {
- T[] r = col.ToArray();
+ T[] r;
+ int colSize = col.Count;
+ if (colSize <= toArray.Length) {
+ col.CopyTo(toArray, 0);
+ if (colSize != toArray.Length) {
+ toArray[colSize] = default(T);
+ }
+ r = toArray;
+ } else {
+ r = new T[colSize];
+ col.CopyTo(r, 0);
+ }
+
return r;
}
diff --git a/itext/itext.forms/itext/forms/PdfAcroForm.cs b/itext/itext.forms/itext/forms/PdfAcroForm.cs
index 3edd8b6d16..4f5777c380 100644
--- a/itext/itext.forms/itext/forms/PdfAcroForm.cs
+++ b/itext/itext.forms/itext/forms/PdfAcroForm.cs
@@ -61,6 +61,7 @@ public class PdfAcroForm : PdfObjectWrapper {
/// To be used with
///
/// .
+ ///
///
/// If set, the document contains at least one signature field. This flag
/// allows a conforming reader to enable user interface items (such as menu
@@ -75,6 +76,7 @@ public class PdfAcroForm : PdfObjectWrapper {
/// To be used with
///
/// .
+ ///
///
/// If set, the document contains signatures that may be invalidated if the
/// file is saved (written) in a way that alters its previous contents, as
@@ -235,6 +237,9 @@ public virtual void AddField(PdfFormField field, PdfPage page) {
}
GetFields().Add(fieldDic);
fields[field.GetFieldName().ToUnicodeString()] = field;
+ if (field.GetKids() != null) {
+ IterateFields(field.GetKids(), fields);
+ }
if (field.GetFormType() != null && (field.GetFormType().Equals(PdfName.Tx) || field.GetFormType().Equals(PdfName
.Ch))) {
IList resources = GetResources(field.GetPdfObject());
@@ -309,6 +314,7 @@ public virtual IDictionary GetFormFields() {
/// Sets the NeedAppearances boolean property on the AcroForm.
///
/// Sets the NeedAppearances boolean property on the AcroForm.
+ ///
///
/// NeedAppearances is a flag specifying whether to construct appearance
/// streams and appearance dictionaries for all widget annotations in the
@@ -325,6 +331,7 @@ public virtual iText.Forms.PdfAcroForm SetNeedAppearances(bool needAppearances)
/// Gets the NeedAppearances boolean property on the AcroForm.
///
/// Gets the NeedAppearances boolean property on the AcroForm.
+ ///
///
/// NeedAppearances is a flag specifying whether to construct appearance
/// streams and appearance dictionaries for all widget annotations in the
@@ -344,6 +351,7 @@ public virtual PdfBoolean GetNeedAppearances() {
/// Sets the SigFlags integer property on the AcroForm.
///
/// Sets the SigFlags integer property on the AcroForm.
+ ///
///
/// SigFlags is a set of flags specifying various document-level
/// characteristics related to signature fields.
@@ -367,6 +375,7 @@ public virtual iText.Forms.PdfAcroForm SetSignatureFlags(int sigFlags) {
///
/// Changes the SigFlags integer property on the AcroForm.
/// This method allows only to add flags, not to remove them.
+ ///
///
/// SigFlags is a set of flags specifying various document-level
/// characteristics related to signature fields.
@@ -391,6 +400,7 @@ public virtual iText.Forms.PdfAcroForm SetSignatureFlag(int sigFlag) {
/// Gets the SigFlags integer property on the AcroForm.
///
/// Gets the SigFlags integer property on the AcroForm.
+ ///
///
/// SigFlags is a set of flags specifying various document-level
/// characteristics related to signature fields
@@ -411,6 +421,7 @@ public virtual int GetSignatureFlags() {
/// Sets the CO array property on the AcroForm.
///
/// Sets the CO array property on the AcroForm.
+ ///
///
/// CO, Calculation Order, is an array of indirect references to
/// field dictionaries with calculation actions, defining the calculation
@@ -428,6 +439,7 @@ public virtual iText.Forms.PdfAcroForm SetCalculationOrder(PdfArray calculationO
/// Gets the CO array property on the AcroForm.
///
/// Gets the CO array property on the AcroForm.
+ ///
///
/// CO, Calculation Order, is an array of indirect references to
/// field dictionaries with calculation actions, defining the calculation
@@ -444,6 +456,7 @@ public virtual PdfArray GetCalculationOrder() {
/// Sets the DR dictionary property on the AcroForm.
///
/// Sets the DR dictionary property on the AcroForm.
+ ///
///
/// DR is a resource dictionary containing default resources
/// (such as fonts, patterns, or colour spaces) that shall be used by form
@@ -462,6 +475,7 @@ public virtual iText.Forms.PdfAcroForm SetDefaultResources(PdfDictionary default
/// Gets the DR dictionary property on the AcroForm.
///
/// Gets the DR dictionary property on the AcroForm.
+ ///
///
/// DR is a resource dictionary containing default resources
/// (such as fonts, patterns, or colour spaces) that shall be used by form
@@ -479,6 +493,7 @@ public virtual PdfDictionary GetDefaultResources() {
/// Sets the DA String property on the AcroForm.
///
/// Sets the DA String property on the AcroForm.
+ ///
/// This method sets a default (fallback value) for the DA
/// attribute of variable text
/// form field
@@ -486,7 +501,7 @@ public virtual PdfDictionary GetDefaultResources() {
///
/// a String containing a sequence of valid PDF syntax
/// current AcroForm
- ///
+ ///
public virtual iText.Forms.PdfAcroForm SetDefaultAppearance(String appearance) {
return Put(PdfName.DA, new PdfString(appearance));
}
@@ -494,6 +509,7 @@ public virtual iText.Forms.PdfAcroForm SetDefaultAppearance(String appearance) {
/// Gets the DA String property on the AcroForm.
///
/// Gets the DA String property on the AcroForm.
+ ///
/// This method returns the default (fallback value) for the DA
/// attribute of variable text
/// form field
@@ -507,6 +523,7 @@ public virtual PdfString GetDefaultAppearance() {
/// Sets the Q integer property on the AcroForm.
///
/// Sets the Q integer property on the AcroForm.
+ ///
/// This method sets a default (fallback value) for the Q
/// attribute of variable text
/// form field
@@ -514,7 +531,7 @@ public virtual PdfString GetDefaultAppearance() {
///
/// an integer representing a justification value
/// current AcroForm
- ///
+ ///
public virtual iText.Forms.PdfAcroForm SetDefaultJustification(int justification) {
return Put(PdfName.Q, new PdfNumber(justification));
}
@@ -522,13 +539,14 @@ public virtual iText.Forms.PdfAcroForm SetDefaultJustification(int justification
/// Gets the Q integer property on the AcroForm.
///
/// Gets the Q integer property on the AcroForm.
+ ///
/// This method gets the default (fallback value) for the Q
/// attribute of variable text
/// form field
/// s.
///
/// an integer representing a justification value
- ///
+ ///
public virtual PdfNumber GetDefaultJustification() {
return GetPdfObject().GetAsNumber(PdfName.Q);
}
@@ -536,6 +554,7 @@ public virtual PdfNumber GetDefaultJustification() {
/// Sets the XFA property on the AcroForm.
///
/// Sets the XFA property on the AcroForm.
+ ///
/// XFA can either be a
///
/// or a
@@ -552,6 +571,7 @@ public virtual iText.Forms.PdfAcroForm SetXFAResource(PdfStream xfaResource) {
/// Sets the XFA property on the AcroForm.
///
/// Sets the XFA property on the AcroForm.
+ ///
/// XFA can either be a
///
/// or a
@@ -621,9 +641,11 @@ public virtual bool IsGenerateAppearance() {
/// form field
/// s
/// that don't have one.
+ ///
/// Not generating appearances will speed up form flattening but the results
/// can be unexpected in Acrobat. Don't use it unless your environment is
/// well controlled. The default is true.
+ ///
/// If generateAppearance is set to true, then
/// NeedAppearances is set to false. This does not
/// apply vice versa.
@@ -710,7 +732,8 @@ public virtual void FlattenFields() {
}
}
}
- if (xObject != null) {
+ // Subtype is required key, if there is no Subtype it is invalid XObject. DEVSIX-725
+ if (xObject != null && xObject.GetPdfObject().Get(PdfName.Subtype) != null) {
Rectangle box = fieldObject.GetAsRectangle(PdfName.Rect);
if (page.IsFlushed()) {
throw new PdfException(PdfException.PageWasAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing
@@ -730,7 +753,7 @@ public virtual void FlattenFields() {
canvas.OpenTag(tagRef);
}
canvas.AddXObject(xObject, box.GetX(), box.GetY());
- if (document.IsTagged()) {
+ if (tagPointer != null) {
canvas.CloseTag();
}
}
@@ -894,8 +917,8 @@ protected override bool IsWrappedObjectMustBeIndirect() {
return false;
}
- private IDictionary IterateFields(PdfArray array) {
- IDictionary fields = new LinkedDictionary();
+ private IDictionary IterateFields(PdfArray array, IDictionary
+ fields) {
int index = 1;
foreach (PdfObject field in array) {
PdfFormField formField = PdfFormField.MakeFormField(field, document);
@@ -917,12 +940,16 @@ private IDictionary IterateFields(PdfArray array) {
}
fields[name] = formField;
if (formField.GetKids() != null) {
- fields.AddAll(IterateFields(formField.GetKids()));
+ IterateFields(formField.GetKids(), fields);
}
}
return fields;
}
+ private IDictionary IterateFields(PdfArray array) {
+ return IterateFields(array, new LinkedDictionary());
+ }
+
private PdfDictionary ProcessKids(PdfArray kids, PdfDictionary parent, PdfPage page) {
if (kids.Size() == 1) {
PdfDictionary kidDict = (PdfDictionary)kids.Get(0);
@@ -1140,14 +1167,7 @@ private ICollection PrepareFieldsForFlattening(PdfFormField field)
PdfArray kids = field.GetKids();
if (kids != null) {
foreach (PdfObject kid in kids) {
- PdfDictionary fieldDict;
- if (kid.IsIndirectReference()) {
- fieldDict = (PdfDictionary)((PdfIndirectReference)kid).GetRefersTo();
- }
- else {
- fieldDict = (PdfDictionary)kid;
- }
- PdfFormField kidField = new PdfFormField(fieldDict);
+ PdfFormField kidField = new PdfFormField((PdfDictionary)kid);
preparedFields.Add(kidField);
if (kidField.GetKids() != null) {
preparedFields.AddAll(PrepareFieldsForFlattening(kidField));
diff --git a/itext/itext.forms/itext/forms/PdfPageFormCopier.cs b/itext/itext.forms/itext/forms/PdfPageFormCopier.cs
index 819009b4ea..a87e4f7953 100644
--- a/itext/itext.forms/itext/forms/PdfPageFormCopier.cs
+++ b/itext/itext.forms/itext/forms/PdfPageFormCopier.cs
@@ -54,6 +54,14 @@ namespace iText.Forms {
/// A sample implementation of the {#link IPdfPageExtraCopier} interface which
/// copies only AcroForm fields to a new page.
///
+ ///
+ /// A sample implementation of the {#link IPdfPageExtraCopier} interface which
+ /// copies only AcroForm fields to a new page.
+ ///
+ /// NOTE: While it's absolutely not necessary to use the same PdfPageFormCopier instance for copying operations,
+ /// it is still worth to know that PdfPageFormCopier uses some caching logic which can potentially improve performance
+ /// in case of the reusing of the same instance.
+ ///
public class PdfPageFormCopier : IPdfPageExtraCopier {
internal PdfAcroForm formFrom;
@@ -63,6 +71,8 @@ public class PdfPageFormCopier : IPdfPageExtraCopier {
internal PdfDocument documentTo;
+ internal ILogger logger = LoggerFactory.GetLogger(typeof(PdfPageFormCopier));
+
public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
if (documentFrom != fromPage.GetDocument()) {
documentFrom = fromPage.GetDocument();
@@ -71,16 +81,15 @@ public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
if (documentTo != toPage.GetDocument()) {
documentTo = toPage.GetDocument();
formTo = PdfAcroForm.GetAcroForm(documentTo, true);
- if (formFrom != null) {
- //duplicate AcroForm dictionary
- IList excludedKeys = new List();
- excludedKeys.Add(PdfName.Fields);
- excludedKeys.Add(PdfName.DR);
- PdfDictionary dict = formFrom.GetPdfObject().CopyTo(documentTo, excludedKeys, false);
- formTo.GetPdfObject().MergeDifferent(dict);
- }
}
- IList usedParents = new List();
+ if (formFrom != null) {
+ //duplicate AcroForm dictionary
+ IList excludedKeys = new List();
+ excludedKeys.Add(PdfName.Fields);
+ excludedKeys.Add(PdfName.DR);
+ PdfDictionary dict = formFrom.GetPdfObject().CopyTo(documentTo, excludedKeys, false);
+ formTo.GetPdfObject().MergeDifferent(dict);
+ }
if (formFrom != null) {
IDictionary fieldsFrom = formFrom.GetFormFields();
if (fieldsFrom.Count > 0) {
@@ -90,19 +99,44 @@ public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
if (annot.GetSubtype().Equals(PdfName.Widget)) {
PdfDictionary parent = annot.GetPdfObject().GetAsDictionary(PdfName.Parent);
if (parent != null) {
- PdfString parentName = parent.GetAsString(PdfName.T);
+ PdfFormField parentField = GetParentField(parent, documentTo);
+ PdfString parentName = parentField.GetFieldName();
if (parentName == null) {
continue;
}
- if (!usedParents.Contains(parent)) {
- PdfFormField field = PdfFormField.MakeFormField(parent, toPage.GetDocument());
- field.GetKids().Clear();
+ if (!fieldsTo.ContainsKey(parentName.ToUnicodeString())) {
+ PdfFormField field = CreateParentFieldCopy(annot.GetPdfObject(), documentTo);
+ PdfArray kids = field.GetKids();
+ field.GetPdfObject().Remove(PdfName.Kids);
formTo.AddField(field, toPage);
- usedParents.Add(parent);
- field.AddKid((PdfWidgetAnnotation)annot);
+ field.GetPdfObject().Put(PdfName.Kids, kids);
}
else {
- parent.GetAsArray(PdfName.Kids).Add(annot.GetPdfObject());
+ PdfFormField field = PdfFormField.MakeFormField(annot.GetPdfObject(), documentTo);
+ PdfString fieldName = field.GetFieldName();
+ if (fieldName != null) {
+ PdfFormField existingField = fieldsTo.Get(fieldName.ToUnicodeString());
+ if (existingField != null) {
+ PdfFormField clonedField = PdfFormField.MakeFormField(field.GetPdfObject().Clone().MakeIndirect(documentTo
+ ), documentTo);
+ toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedField.GetPdfObject());
+ toPage.RemoveAnnotation(annot);
+ MergeFieldsWithTheSameName(existingField, clonedField);
+ }
+ else {
+ HashSet existingFields = new HashSet();
+ GetAllFieldNames(formTo.GetFields(), existingFields);
+ AddChildToExistingParent(annot.GetPdfObject(), existingFields);
+ }
+ }
+ else {
+ if (parentField.GetKids().Contains(field.GetPdfObject())) {
+ field = PdfFormField.MakeFormField(field.GetPdfObject().Clone().MakeIndirect(documentTo), documentTo);
+ toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(field.GetPdfObject());
+ toPage.RemoveAnnotation(annot);
+ }
+ parentField.AddKid(field);
+ }
}
}
else {
@@ -112,13 +146,21 @@ public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
annotNameString = annotName.ToUnicodeString();
}
if (annotNameString != null && fieldsFrom.ContainsKey(annotNameString)) {
- PdfFormField field = PdfFormField.MakeFormField(annot.GetPdfObject(), toPage.GetDocument());
- if (fieldsTo.ContainsKey(annotNameString)) {
- field = MergeFieldsWithTheSameName(field, fieldsTo.Get(annotNameString));
- ILogger logger = LoggerFactory.GetLogger(typeof(PdfPageFormCopier));
+ PdfFormField field = fieldsTo.Get(annotNameString);
+ if (field != null) {
+ PdfDictionary clonedAnnot = (PdfDictionary)annot.GetPdfObject().Clone().MakeIndirect(documentTo);
+ toPage.GetPdfObject().GetAsArray(PdfName.Annots).Add(clonedAnnot);
+ toPage.RemoveAnnotation(annot);
+ field = MergeFieldsWithTheSameName(field, PdfFormField.MakeFormField(clonedAnnot, toPage.GetDocument()));
logger.Warn(String.Format(LogMessageConstant.DOCUMENT_ALREADY_HAS_FIELD, annotNameString));
+ PdfArray kids = field.GetKids();
+ field.GetPdfObject().Remove(PdfName.Kids);
+ formTo.AddField(field, toPage);
+ field.GetPdfObject().Put(PdfName.Kids, kids);
+ }
+ else {
+ formTo.AddField(PdfFormField.MakeFormField(annot.GetPdfObject(), documentTo), null);
}
- formTo.AddField(field, null);
}
}
}
@@ -128,28 +170,93 @@ public virtual void Copy(PdfPage fromPage, PdfPage toPage) {
}
private PdfFormField MergeFieldsWithTheSameName(PdfFormField existingField, PdfFormField newField) {
- String fieldName = newField.GetFieldName().ToUnicodeString();
- existingField.GetPdfObject().Remove(PdfName.T);
- PdfFormField mergedField = formTo.GetField(fieldName);
- PdfArray kids = mergedField.GetKids();
+ String fullFieldName = newField.GetFieldName().ToUnicodeString();
+ PdfString fieldName = newField.GetPdfObject().GetAsString(PdfName.T);
+ newField.GetPdfObject().Remove(PdfName.T);
+ newField.GetPdfObject().Remove(PdfName.P);
+ existingField = formTo.GetField(fullFieldName);
+ PdfArray kids = existingField.GetKids();
if (kids != null && !kids.IsEmpty()) {
- mergedField.AddKid(existingField);
- return mergedField;
+ existingField.AddKid(newField);
+ return existingField;
}
- newField.GetPdfObject().Remove(PdfName.T);
- mergedField = PdfFormField.CreateEmptyField(documentTo);
- formTo.GetFields().Remove(newField.GetPdfObject());
- mergedField.Put(PdfName.FT, existingField.GetFormType()).Put(PdfName.T, new PdfString(fieldName));
+ existingField.GetPdfObject().Remove(PdfName.T);
+ existingField.GetPdfObject().Remove(PdfName.P);
+ formTo.GetFields().Remove(existingField.GetPdfObject());
+ PdfFormField mergedField = PdfFormField.CreateEmptyField(documentTo);
+ mergedField.Put(PdfName.FT, existingField.GetFormType()).Put(PdfName.T, fieldName);
PdfDictionary parent = existingField.GetParent();
if (parent != null) {
mergedField.Put(PdfName.Parent, parent);
+ PdfArray parentKids = parent.GetAsArray(PdfName.Kids);
+ for (int i = 0; i < parentKids.Size(); i++) {
+ PdfObject obj = parentKids.Get(i);
+ if (obj == existingField.GetPdfObject()) {
+ parentKids.Set(i, mergedField.GetPdfObject());
+ break;
+ }
+ }
}
kids = existingField.GetKids();
if (kids != null) {
mergedField.Put(PdfName.Kids, kids);
}
mergedField.AddKid(existingField).AddKid(newField);
+ PdfObject value = existingField.GetValue();
+ if (value != null) {
+ mergedField.Put(PdfName.V, existingField.GetPdfObject().Get(PdfName.V));
+ }
return mergedField;
}
+
+ private PdfFormField GetParentField(PdfDictionary parent, PdfDocument pdfDoc) {
+ PdfFormField parentField = PdfFormField.MakeFormField(parent, pdfDoc);
+ PdfDictionary parentOfParent = parentField.GetParent();
+ if (parentOfParent != null) {
+ parentField = GetParentField(parentOfParent, pdfDoc);
+ }
+ return parentField;
+ }
+
+ private PdfFormField CreateParentFieldCopy(PdfDictionary fieldDic, PdfDocument pdfDoc) {
+ fieldDic.Remove(PdfName.Kids);
+ PdfDictionary parent = fieldDic.GetAsDictionary(PdfName.Parent);
+ PdfFormField field = PdfFormField.MakeFormField(fieldDic, pdfDoc);
+ if (parent != null) {
+ field = CreateParentFieldCopy(parent, pdfDoc);
+ parent.Put(PdfName.Kids, new PdfArray(fieldDic));
+ }
+ return field;
+ }
+
+ private void AddChildToExistingParent(PdfDictionary fieldDic, ICollection existingFields) {
+ PdfDictionary parent = fieldDic.GetAsDictionary(PdfName.Parent);
+ PdfString parentName = parent.GetAsString(PdfName.T);
+ if (parentName != null) {
+ String name = parentName.ToUnicodeString();
+ if (existingFields.Contains(name)) {
+ PdfArray kids = parent.GetAsArray(PdfName.Kids);
+ kids.Add(fieldDic);
+ }
+ else {
+ parent.Put(PdfName.Kids, new PdfArray(fieldDic));
+ AddChildToExistingParent(parent, existingFields);
+ }
+ }
+ }
+
+ private void GetAllFieldNames(PdfArray fields, ICollection existingFields) {
+ foreach (PdfObject field in fields) {
+ PdfDictionary dic = (PdfDictionary)field;
+ PdfString name = dic.GetAsString(PdfName.T);
+ if (name != null) {
+ existingFields.Add(name.ToUnicodeString());
+ }
+ PdfArray kids = dic.GetAsArray(PdfName.Kids);
+ if (kids != null) {
+ GetAllFieldNames(kids, existingFields);
+ }
+ }
+ }
}
}
diff --git a/itext/itext.forms/itext/forms/fields/PdfFormField.cs b/itext/itext.forms/itext/forms/fields/PdfFormField.cs
index f786999244..993cb425ec 100644
--- a/itext/itext.forms/itext/forms/fields/PdfFormField.cs
+++ b/itext/itext.forms/itext/forms/fields/PdfFormField.cs
@@ -43,9 +43,12 @@ source product.
*/
using System;
using System.Collections.Generic;
+using System.Text;
+using iText.IO;
using iText.IO.Codec;
using iText.IO.Font;
using iText.IO.Image;
+using iText.IO.Log;
using iText.IO.Source;
using iText.Kernel;
using iText.Kernel.Colors;
@@ -64,6 +67,7 @@ namespace iText.Forms.Fields {
/// This class represents a single field or field group in an
/// AcroForm
/// .
+ ///
///
/// To be able to be wrapped with this
///
@@ -134,17 +138,17 @@ public class PdfFormField : PdfObjectWrapper {
protected internal PdfFont font;
- protected internal int fontSize;
+ protected internal float fontSize;
protected internal Color color;
protected internal int checkType;
- protected internal float borderWidth = 1;
+ protected internal float borderWidth = 0;
protected internal Color backgroundColor;
- protected internal Color borderColor = Color.BLACK;
+ protected internal Color borderColor;
protected internal int rotation = 0;
@@ -384,7 +388,7 @@ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, Strin
///
public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, String name, String value) {
try {
- return CreateText(doc, rect, name, value, PdfFontFactory.CreateFont(), DEFAULT_FONT_SIZE);
+ return CreateText(doc, rect, name, value, PdfFontFactory.CreateFont(), (float)DEFAULT_FONT_SIZE);
}
catch (System.IO.IOException e) {
throw new PdfException(e);
@@ -409,13 +413,13 @@ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, Strin
/// a
///
///
- /// a positive integer
+ /// the size of the font
///
/// a new
///
///
public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, String name, String value, PdfFont
- font, int fontSize) {
+ font, float fontSize) {
return CreateText(doc, rect, name, value, font, fontSize, false);
}
@@ -437,14 +441,75 @@ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, Strin
/// a
///
///
- /// a positive integer
+ /// the size of the font
+ ///
+ /// a new
+ ///
+ ///
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use CreateText(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.Rectangle, System.String, System.String, iText.Kernel.Font.PdfFont, float) instead."
+ )]
+ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, String name, String value, PdfFont
+ font, int fontSize) {
+ return CreateText(doc, rect, name, value, font, (float)fontSize, false);
+ }
+
+ ///
+ /// Creates a named
+ /// text form field
+ /// with an initial
+ /// value, with a specified font and font size.
+ ///
+ ///
+ /// the
+ ///
+ /// to create the text field in
+ ///
+ /// the location on the page for the text field
+ /// the name of the form field
+ /// the initial value
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
/// true for multiline text field
///
/// a new
///
///
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use CreateText(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.Rectangle, System.String, System.String, iText.Kernel.Font.PdfFont, float, bool) instead."
+ )]
public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, String name, String value, PdfFont
font, int fontSize, bool multiline) {
+ return CreateText(doc, rect, name, value, font, (float)fontSize, multiline);
+ }
+
+ ///
+ /// Creates a named
+ /// text form field
+ /// with an initial
+ /// value, with a specified font and font size.
+ ///
+ ///
+ /// the
+ ///
+ /// to create the text field in
+ ///
+ /// the location on the page for the text field
+ /// the name of the form field
+ /// the initial value
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ /// true for multiline text field
+ ///
+ /// a new
+ ///
+ ///
+ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, String name, String value, PdfFont
+ font, float fontSize, bool multiline) {
PdfWidgetAnnotation annot = new PdfWidgetAnnotation(rect);
PdfTextFormField field = new PdfTextFormField(annot, doc);
field.SetMultiline(multiline);
@@ -473,16 +538,46 @@ public static PdfTextFormField CreateText(PdfDocument doc, Rectangle rect, Strin
/// a
///
///
- /// a positive integer
+ /// the size of the font
///
/// a new
///
///
public static PdfTextFormField CreateMultilineText(PdfDocument doc, Rectangle rect, String name, String value
- , PdfFont font, int fontSize) {
+ , PdfFont font, float fontSize) {
return CreateText(doc, rect, name, value, font, fontSize, true);
}
+ ///
+ /// Creates a named
+ /// multilined text form field
+ /// with an initial
+ /// value, with a specified font and font size.
+ ///
+ ///
+ /// the
+ ///
+ /// to create the text field in
+ ///
+ /// the location on the page for the text field
+ /// the name of the form field
+ /// the initial value
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ ///
+ /// a new
+ ///
+ ///
+ [System.ObsoleteAttribute(@"use CreateMultilineText(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.Rectangle, System.String, System.String, iText.Kernel.Font.PdfFont, float) instead"
+ )]
+ public static PdfTextFormField CreateMultilineText(PdfDocument doc, Rectangle rect, String name, String value
+ , PdfFont font, int fontSize) {
+ return CreateText(doc, rect, name, value, font, (float)fontSize, true);
+ }
+
///
/// Creates a named
/// multiline text form field
@@ -506,7 +601,7 @@ public static PdfTextFormField CreateMultilineText(PdfDocument doc, Rectangle re
public static PdfTextFormField CreateMultilineText(PdfDocument doc, Rectangle rect, String name, String value
) {
try {
- return CreateText(doc, rect, name, value, PdfFontFactory.CreateFont(), DEFAULT_FONT_SIZE, true);
+ return CreateText(doc, rect, name, value, PdfFontFactory.CreateFont(), (float)DEFAULT_FONT_SIZE, true);
}
catch (System.IO.IOException e) {
throw new PdfException(e);
@@ -598,8 +693,8 @@ public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, i
public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, String name, String value,
PdfArray options, int flags) {
try {
- return CreateChoice(doc, rect, name, value, PdfFontFactory.CreateFont(), DEFAULT_FONT_SIZE, options, flags
- );
+ return CreateChoice(doc, rect, name, value, PdfFontFactory.CreateFont(), (float)DEFAULT_FONT_SIZE, options
+ , flags);
}
catch (System.IO.IOException e) {
throw new PdfException(e);
@@ -624,7 +719,7 @@ public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, S
/// a
///
///
- /// a positive integer
+ /// the size of the font
///
/// an array of
///
@@ -640,8 +735,49 @@ public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, S
/// a new
///
///
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use CreateChoice(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.Rectangle, System.String, System.String, iText.Kernel.Font.PdfFont, float, iText.Kernel.Pdf.PdfArray, int) instead"
+ )]
public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, String name, String value,
PdfFont font, int fontSize, PdfArray options, int flags) {
+ return CreateChoice(doc, rect, name, value, font, (float)fontSize, options, flags);
+ }
+
+ ///
+ /// Creates a
+ /// choice form field
+ /// with custom
+ /// behavior and layout, on a specified location.
+ ///
+ ///
+ /// the
+ ///
+ /// to create the choice field in
+ ///
+ /// the location on the page for the choice field
+ /// the name of the form field
+ /// the initial value
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ ///
+ /// an array of
+ ///
+ /// objects that each represent
+ /// the 'on' state of one of the choices.
+ ///
+ ///
+ /// an int, containing a set of binary behavioral
+ /// flags. Do binary OR on this int to set the
+ /// flags you require.
+ ///
+ ///
+ /// a new
+ ///
+ ///
+ public static PdfChoiceFormField CreateChoice(PdfDocument doc, Rectangle rect, String name, String value,
+ PdfFont font, float fontSize, PdfArray options, int flags) {
PdfWidgetAnnotation annot = new PdfWidgetAnnotation(rect);
iText.Forms.Fields.PdfFormField field = new PdfChoiceFormField(annot, doc);
field.font = font;
@@ -824,7 +960,7 @@ public static PdfButtonFormField CreatePushButton(PdfDocument doc, Rectangle rec
) {
PdfButtonFormField field;
try {
- field = CreatePushButton(doc, rect, name, caption, PdfFontFactory.CreateFont(), DEFAULT_FONT_SIZE);
+ field = CreatePushButton(doc, rect, name, caption, PdfFontFactory.CreateFont(), (float)DEFAULT_FONT_SIZE);
}
catch (System.IO.IOException e) {
throw new PdfException(e);
@@ -850,13 +986,43 @@ public static PdfButtonFormField CreatePushButton(PdfDocument doc, Rectangle rec
/// a
///
///
- /// a positive integer
+ /// the size of the font
///
/// a new
///
///
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use CreatePushButton(iText.Kernel.Pdf.PdfDocument, iText.Kernel.Geom.Rectangle, System.String, System.String, iText.Kernel.Font.PdfFont, float) instead."
+ )]
public static PdfButtonFormField CreatePushButton(PdfDocument doc, Rectangle rect, String name, String caption
, PdfFont font, int fontSize) {
+ return CreatePushButton(doc, rect, name, caption, font, (float)fontSize);
+ }
+
+ ///
+ /// Creates a
+ ///
+ /// as a push button without data, with
+ /// its caption in a custom font.
+ ///
+ ///
+ /// the
+ ///
+ /// to create the radio group in
+ ///
+ /// the location on the page for the field
+ /// the name of the form field
+ /// the text to display on the button
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ ///
+ /// a new
+ ///
+ ///
+ public static PdfButtonFormField CreatePushButton(PdfDocument doc, Rectangle rect, String name, String caption
+ , PdfFont font, float fontSize) {
PdfWidgetAnnotation annot = new PdfWidgetAnnotation(rect);
PdfButtonFormField field = new PdfButtonFormField(annot, doc);
field.SetPushButton(true);
@@ -1115,9 +1281,6 @@ public static PdfChoiceFormField CreateList(PdfDocument doc, Rectangle rect, Str
///
public static iText.Forms.Fields.PdfFormField MakeFormField(PdfObject pdfObject, PdfDocument document) {
iText.Forms.Fields.PdfFormField field = null;
- if (pdfObject.IsIndirectReference()) {
- pdfObject = ((PdfIndirectReference)pdfObject).GetRefersTo();
- }
if (pdfObject.IsDictionary()) {
PdfDictionary dictionary = (PdfDictionary)pdfObject;
PdfName formType = dictionary.GetAsName(PdfName.FT);
@@ -1239,9 +1402,22 @@ public virtual iText.Forms.Fields.PdfFormField SetValue(String value, bool gener
/// a
///
///
- /// a positive integer
+ /// the size of the font
/// the edited field
+ [System.ObsoleteAttribute(@"Use SetValue(System.String, iText.Kernel.Font.PdfFont, float) instead")]
public virtual iText.Forms.Fields.PdfFormField SetValue(String value, PdfFont font, int fontSize) {
+ return SetValue(value, font, (float)fontSize);
+ }
+
+ /// Set text field value with given font and size
+ /// text value
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ /// the edited field
+ public virtual iText.Forms.Fields.PdfFormField SetValue(String value, PdfFont font, float fontSize) {
PdfName formType = GetFormType();
if (!formType.Equals(PdfName.Tx) && !formType.Equals(PdfName.Ch)) {
return SetValue(value);
@@ -1505,7 +1681,7 @@ public virtual iText.Forms.Fields.PdfFormField SetFieldFlag(int flag, bool value
return SetFieldFlags(flags);
}
- /// If true, the field can contain multiple lines of text; if false, the field???s text is restricted to a single line.
+ /// If true, the field can contain multiple lines of text; if false, the field's text is restricted to a single line.
///
/// whether the field can span over multiple lines.
public virtual bool IsMultiline() {
@@ -1685,7 +1861,7 @@ public virtual IList GetWidgets() {
///
/// Gets default appearance string containing a sequence of valid page-content graphics or text state operators that
- /// define such properties as the field???s text size and color.
+ /// define such properties as the field's text size and color.
///
///
/// the default appearance graphics, as a
@@ -1697,12 +1873,12 @@ public virtual PdfString GetDefaultAppearance() {
///
/// Sets default appearance string containing a sequence of valid page-content graphics or text state operators that
- /// define such properties as the field???s text size and color.
+ /// define such properties as the field's text size and color.
///
/// a valid sequence of PDF content stream syntax
/// the edited field
public virtual iText.Forms.Fields.PdfFormField SetDefaultAppearance(String defaultAppearance) {
- byte[] b = defaultAppearance.GetBytes();
+ byte[] b = defaultAppearance.GetBytes(Encoding.UTF8);
int len = b.Length;
for (int k = 0; k < len; ++k) {
if (b[k] == '\n') {
@@ -1800,9 +1976,10 @@ public virtual PdfFont GetFont() {
/// appearance after setting the new value.
///
/// the new font to be set
- public virtual void SetFont(PdfFont font) {
+ public virtual iText.Forms.Fields.PdfFormField SetFont(PdfFont font) {
this.font = font;
RegenerateField();
+ return this;
}
/// Basic setter for the fontSize property.
@@ -1811,9 +1988,21 @@ public virtual void SetFont(PdfFont font) {
/// field appearance after setting the new value.
///
/// the new font size to be set
- public virtual void SetFontSize(int fontSize) {
+ public virtual iText.Forms.Fields.PdfFormField SetFontSize(float fontSize) {
this.fontSize = fontSize;
RegenerateField();
+ return this;
+ }
+
+ /// Basic setter for the fontSize property.
+ ///
+ /// Basic setter for the fontSize property. Regenerates the
+ /// field appearance after setting the new value.
+ ///
+ /// the new font size to be set
+ public virtual iText.Forms.Fields.PdfFormField SetFontSize(int fontSize) {
+ SetFontSize((float)fontSize);
+ return this;
}
///
@@ -1826,10 +2015,11 @@ public virtual void SetFontSize(int fontSize) {
///
/// the new font to be set
/// the new font size to be set
- public virtual void SetFontAndSize(PdfFont font, int fontSize) {
+ public virtual iText.Forms.Fields.PdfFormField SetFontAndSize(PdfFont font, int fontSize) {
this.font = font;
this.fontSize = fontSize;
RegenerateField();
+ return this;
}
/// Basic setter for the backgroundColor property.
@@ -1838,7 +2028,7 @@ public virtual void SetFontAndSize(PdfFont font, int fontSize) {
/// the field appearance after setting the new value.
///
/// the new color to be set
- public virtual void SetBackgroundColor(Color backgroundColor) {
+ public virtual iText.Forms.Fields.PdfFormField SetBackgroundColor(Color backgroundColor) {
this.backgroundColor = backgroundColor;
PdfDictionary mk = GetWidgets()[0].GetAppearanceCharacteristics();
if (mk == null) {
@@ -1846,6 +2036,7 @@ public virtual void SetBackgroundColor(Color backgroundColor) {
}
mk.Put(PdfName.BG, new PdfArray(backgroundColor.GetColorValue()));
RegenerateField();
+ return this;
}
/// Basic setter for the degRotation property.
@@ -1854,7 +2045,7 @@ public virtual void SetBackgroundColor(Color backgroundColor) {
/// the field appearance after setting the new value.
///
/// the new degRotation to be set
- public virtual void SetRotation(int degRotation) {
+ public virtual iText.Forms.Fields.PdfFormField SetRotation(int degRotation) {
if (degRotation % 90 != 0) {
throw new ArgumentException("degRotation.must.be.a.multiple.of.90");
}
@@ -1868,10 +2059,12 @@ public virtual void SetRotation(int degRotation) {
PdfDictionary mk = GetWidgets()[0].GetAppearanceCharacteristics();
if (mk == null) {
mk = new PdfDictionary();
+ this.Put(PdfName.MK, mk);
}
mk.Put(PdfName.R, new PdfNumber(degRotation));
this.rotation = degRotation;
RegenerateField();
+ return this;
}
///
@@ -1899,14 +2092,14 @@ public virtual iText.Forms.Fields.PdfFormField SetAction(PdfAction action) {
/// method
///
/// the new checkbox marker
- public virtual void SetCheckType(int checkType) {
+ public virtual iText.Forms.Fields.PdfFormField SetCheckType(int checkType) {
if (checkType < TYPE_CHECK || checkType > TYPE_STAR) {
checkType = TYPE_CROSS;
}
this.checkType = checkType;
text = typeChars[checkType - 1];
if (pdfAConformanceLevel != null) {
- return;
+ return this;
}
try {
font = PdfFontFactory.CreateFont(FontConstants.ZAPFDINGBATS);
@@ -1914,6 +2107,7 @@ public virtual void SetCheckType(int checkType) {
catch (System.IO.IOException e) {
throw new PdfException(e);
}
+ return this;
}
///
@@ -1952,6 +2146,10 @@ public virtual iText.Forms.Fields.PdfFormField SetVisibility(int visibility) {
public virtual bool RegenerateField() {
PdfName type = GetFormType();
String value = GetValueAsString();
+ PdfPage page = null;
+ if (GetWidgets().Count > 0) {
+ page = GetWidgets()[0].GetPage();
+ }
if (PdfName.Tx.Equals(type) || PdfName.Ch.Equals(type)) {
try {
PdfDictionary apDic = GetPdfObject().GetAsDictionary(PdfName.AP);
@@ -1969,10 +2167,94 @@ public virtual bool RegenerateField() {
}
Object[] fontAndSize = GetFontAndSize(asNormal);
PdfFont localFont = (PdfFont)fontAndSize[0];
- int fontSz = (int)fontAndSize[1];
- if (fontSz == 0) {
- fontSz = DEFAULT_FONT_SIZE;
+ float fontSize = (float)fontAndSize[1];
+ if (fontSize == 0) {
+ fontSize = (float)DEFAULT_FONT_SIZE;
+ }
+ //Apply Page rotation
+ int pageRotation = 0;
+ if (page != null) {
+ pageRotation = page.GetRotation();
+ //Clockwise, so negative
+ pageRotation *= -1;
}
+ PdfArray matrix;
+ if (pageRotation % 90 == 0) {
+ //Cast angle to [-360, 360]
+ double angle = pageRotation % 360;
+ //Get angle in radians
+ angle = DegreeToRadians(angle);
+ //rotate the bounding box
+ Rectangle rect = bBox.ToRectangle();
+ //Calculate origin offset
+ double translationWidth = 0;
+ double translationHeight = 0;
+ if (angle >= -1 * Math.PI && angle <= -1 * Math.PI / 2) {
+ translationWidth = rect.GetWidth();
+ }
+ if (angle <= -1 * Math.PI) {
+ translationHeight = rect.GetHeight();
+ }
+ //Store rotation and translation in the matrix
+ matrix = new PdfArray(new double[] { Math.Cos(angle), -Math.Sin(angle), Math.Sin(angle), Math.Cos(angle),
+ translationWidth, translationHeight });
+ //If the angle is a multiple of 90 and not a multiple of 180, height and width of the bounding box need to be switched
+ if (angle % (Math.PI / 2) == 0 && angle % (Math.PI) != 0) {
+ rect.SetWidth(bBox.ToRectangle().GetHeight());
+ rect.SetHeight(bBox.ToRectangle().GetWidth());
+ }
+ // Adapt origin
+ rect.SetX(rect.GetX() + (float)translationWidth);
+ rect.SetY(rect.GetY() + (float)translationHeight);
+ //Copy Bounding box
+ bBox = new PdfArray(rect);
+ }
+ else {
+ //Avoid NPE when handling corrupt pdfs
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Forms.Fields.PdfFormField));
+ logger.Error(LogMessageConstant.INCORRECT_PAGEROTATION);
+ matrix = new PdfArray(new double[] { 1, 0, 0, 1, 0, 0 });
+ }
+ //Apply field rotation
+ float fieldRotation = 0;
+ if (this.GetPdfObject().GetAsDictionary(PdfName.MK) != null && this.GetPdfObject().GetAsDictionary(PdfName
+ .MK).Get(PdfName.R) != null) {
+ fieldRotation = (float)this.GetPdfObject().GetAsDictionary(PdfName.MK).GetAsFloat(PdfName.R);
+ //Get relative field rotation
+ fieldRotation += pageRotation;
+ }
+ if (fieldRotation % 90 == 0) {
+ //Cast angle to [-360, 360]
+ double angle = fieldRotation % 360;
+ //Get angle in radians
+ angle = DegreeToRadians(angle);
+ //Calculate origin offset
+ double translationWidth = CalculateTranslationWidthAfterFieldRot(bBox.ToRectangle(), DegreeToRadians(pageRotation
+ ), angle);
+ double translationHeight = CalculateTranslationHeightAfterFieldRot(bBox.ToRectangle(), DegreeToRadians(pageRotation
+ ), angle);
+ //Concatenate rotation and translation into the matrix
+ Matrix currentMatrix = new Matrix(matrix.GetAsNumber(0).FloatValue(), matrix.GetAsNumber(1).FloatValue(),
+ matrix.GetAsNumber(2).FloatValue(), matrix.GetAsNumber(3).FloatValue(), matrix.GetAsNumber(4).FloatValue
+ (), matrix.GetAsNumber(5).FloatValue());
+ Matrix toConcatenate = new Matrix((float)Math.Cos(angle), (float)(-Math.Sin(angle)), (float)(Math.Sin(angle
+ )), (float)(Math.Cos(angle)), (float)translationWidth, (float)translationHeight);
+ currentMatrix = currentMatrix.Multiply(toConcatenate);
+ matrix = new PdfArray(new float[] { currentMatrix.Get(0), currentMatrix.Get(1), currentMatrix.Get(3), currentMatrix
+ .Get(4), currentMatrix.Get(6), currentMatrix.Get(7) });
+ //Construct bounding box
+ Rectangle rect = bBox.ToRectangle();
+ //If the angle is a multiple of 90 and not a multiple of 180, height and width of the bounding box need to be switched
+ if (angle % (Math.PI / 2) == 0 && angle % (Math.PI) != 0) {
+ rect.SetWidth(bBox.ToRectangle().GetHeight());
+ rect.SetHeight(bBox.ToRectangle().GetWidth());
+ }
+ rect.SetX(rect.GetX() + (float)translationWidth);
+ rect.SetY(rect.GetY() + (float)translationHeight);
+ //Copy Bounding box
+ bBox = new PdfArray(rect);
+ }
+ //Create appearance
PdfFormXObject appearance = null;
if (asNormal != null) {
appearance = new PdfFormXObject(asNormal);
@@ -1983,12 +2265,16 @@ public virtual bool RegenerateField() {
appearance = new PdfFormXObject(new Rectangle(0, 0, bBox.ToRectangle().GetWidth(), bBox.ToRectangle().GetHeight
()));
}
+ if (matrix != null) {
+ appearance.Put(PdfName.Matrix, matrix);
+ }
+ //Create text appearance
if (PdfName.Tx.Equals(type)) {
if (!IsMultiline()) {
- DrawTextAppearance(bBox.ToRectangle(), localFont, fontSz, value, appearance);
+ DrawTextAppearance(bBox.ToRectangle(), localFont, fontSize, value, appearance);
}
else {
- DrawMultiLineTextAppearance(bBox.ToRectangle(), localFont, fontSz, value, appearance);
+ DrawMultiLineTextAppearance(bBox.ToRectangle(), localFont, fontSize, value, appearance);
}
}
else {
@@ -2002,7 +2288,7 @@ public virtual bool RegenerateField() {
}
value = OptionsArrayToString(options);
}
- DrawMultiLineTextAppearance(bBox.ToRectangle(), localFont, fontSz, value, appearance);
+ DrawMultiLineTextAppearance(bBox.ToRectangle(), localFont, fontSize, value, appearance);
}
appearance.GetResources().AddFont(GetDocument(), localFont);
PdfDictionary ap = new PdfDictionary();
@@ -2043,8 +2329,8 @@ public virtual bool RegenerateField() {
}
Object[] fontAndSize = GetFontAndSize(asNormal);
PdfFont localFont = (PdfFont)fontAndSize[0];
- int fontSz = (int)fontAndSize[1];
- appearance = DrawPushButtonAppearance(rect.GetWidth(), rect.GetHeight(), value, localFont, fontSz);
+ float fontSize = (float)fontAndSize[1];
+ appearance = DrawPushButtonAppearance(rect.GetWidth(), rect.GetHeight(), value, localFont, fontSize);
appearance.GetResources().AddFont(GetDocument(), localFont);
}
}
@@ -2119,16 +2405,143 @@ public virtual bool RegenerateField() {
return true;
}
+ ///
+ /// Calculate the necessary height offset after applying field rotation
+ /// so that the origin of the bounding box is the lower left corner with respect to the field text.
+ ///
+ /// bounding box rectangle before rotation
+ /// rotation of the page
+ /// rotation of the field relative to the page
+ /// translation value for height
+ private float CalculateTranslationHeightAfterFieldRot(Rectangle bBox, double pageRotation, double relFieldRotation
+ ) {
+ if (relFieldRotation == 0) {
+ return 0.0f;
+ }
+ if (pageRotation == 0) {
+ if (relFieldRotation == Math.PI / 2) {
+ return bBox.GetHeight();
+ }
+ if (relFieldRotation == Math.PI) {
+ return bBox.GetHeight();
+ }
+ }
+ if (pageRotation == -Math.PI / 2) {
+ if (relFieldRotation == -Math.PI / 2) {
+ return bBox.GetWidth() - bBox.GetHeight();
+ }
+ if (relFieldRotation == Math.PI / 2) {
+ return bBox.GetHeight();
+ }
+ if (relFieldRotation == Math.PI) {
+ return bBox.GetWidth();
+ }
+ }
+ if (pageRotation == -Math.PI) {
+ if (relFieldRotation == -1 * Math.PI) {
+ return bBox.GetHeight();
+ }
+ if (relFieldRotation == -1 * Math.PI / 2) {
+ return bBox.GetHeight() - bBox.GetWidth();
+ }
+ if (relFieldRotation == Math.PI / 2) {
+ return bBox.GetWidth();
+ }
+ }
+ if (pageRotation == -3 * Math.PI / 2) {
+ if (relFieldRotation == -3 * Math.PI / 2) {
+ return bBox.GetWidth();
+ }
+ if (relFieldRotation == -Math.PI) {
+ return bBox.GetWidth();
+ }
+ }
+ return 0.0f;
+ }
+
+ ///
+ /// Calculate the necessary width offset after applying field rotation
+ /// so that the origin of the bounding box is the lower left corner with respect to the field text.
+ ///
+ /// bounding box rectangle before rotation
+ /// rotation of the page
+ /// rotation of the field relative to the page
+ /// translation value for width
+ private float CalculateTranslationWidthAfterFieldRot(Rectangle bBox, double pageRotation, double relFieldRotation
+ ) {
+ if (relFieldRotation == 0) {
+ return 0.0f;
+ }
+ if (pageRotation == 0 && (relFieldRotation == Math.PI || relFieldRotation == 3 * Math.PI / 2)) {
+ return bBox.GetWidth();
+ }
+ if (pageRotation == -Math.PI / 2) {
+ if (relFieldRotation == -Math.PI / 2 || relFieldRotation == Math.PI) {
+ return bBox.GetHeight();
+ }
+ }
+ if (pageRotation == -Math.PI) {
+ if (relFieldRotation == -1 * Math.PI) {
+ return bBox.GetWidth();
+ }
+ if (relFieldRotation == -1 * Math.PI / 2) {
+ return bBox.GetHeight();
+ }
+ if (relFieldRotation == Math.PI / 2) {
+ return -1 * (bBox.GetHeight() - bBox.GetWidth());
+ }
+ }
+ if (pageRotation == -3 * Math.PI / 2) {
+ if (relFieldRotation == -3 * Math.PI / 2) {
+ return -1 * (bBox.GetWidth() - bBox.GetHeight());
+ }
+ if (relFieldRotation == -Math.PI) {
+ return bBox.GetHeight();
+ }
+ if (relFieldRotation == -Math.PI / 2) {
+ return bBox.GetWidth();
+ }
+ }
+ return 0.0f;
+ }
+
/// Gets the border width for the field.
/// the current border width.
public virtual float GetBorderWidth() {
+ PdfDictionary bs = GetWidgets()[0].GetBorderStyle();
+ if (bs != null) {
+ PdfNumber w = bs.GetAsNumber(PdfName.W);
+ if (w != null) {
+ borderWidth = w.FloatValue();
+ }
+ }
return borderWidth;
}
/// Sets the border width for the field.
/// the new border width.
- public virtual void SetBorderWidth(float borderWidth) {
+ public virtual iText.Forms.Fields.PdfFormField SetBorderWidth(float borderWidth) {
+ PdfDictionary bs = GetWidgets()[0].GetBorderStyle();
+ if (bs == null) {
+ bs = new PdfDictionary();
+ Put(PdfName.BS, bs);
+ }
+ bs.Put(PdfName.W, new PdfNumber(borderWidth));
this.borderWidth = borderWidth;
+ RegenerateField();
+ return this;
+ }
+
+ public virtual iText.Forms.Fields.PdfFormField SetBorderStyle(PdfDictionary style) {
+ //PdfDictionary bs = getWidgets().get(0).getBorderStyle();
+ GetWidgets()[0].SetBorderStyle(style);
+ // if (bs == null) {
+ // bs = new PdfDictionary();
+ // put(PdfName.BS, bs);
+ // }
+ // bs.put(PdfName.S, style);
+ RegenerateField();
+ return this;
}
/// Sets the Border Color.
@@ -2139,6 +2552,7 @@ public virtual iText.Forms.Fields.PdfFormField SetBorderColor(Color color) {
PdfDictionary mk = GetWidgets()[0].GetAppearanceCharacteristics();
if (mk == null) {
mk = new PdfDictionary();
+ Put(PdfName.MK, mk);
}
mk.Put(PdfName.BC, new PdfArray(color.GetColorValue()));
RegenerateField();
@@ -2246,14 +2660,7 @@ public virtual String[] GetAppearanceStates() {
PdfArray kids = GetKids();
if (kids != null) {
foreach (PdfObject kid in kids) {
- PdfDictionary kidDic;
- if (kid.IsIndirectReference()) {
- kidDic = (PdfDictionary)((PdfIndirectReference)kid).GetRefersTo();
- }
- else {
- kidDic = (PdfDictionary)kid;
- }
- iText.Forms.Fields.PdfFormField fld = new iText.Forms.Fields.PdfFormField(kidDic);
+ iText.Forms.Fields.PdfFormField fld = new iText.Forms.Fields.PdfFormField((PdfDictionary)kid);
String[] states = fld.GetAppearanceStates();
foreach (String state in states) {
names.Add(state);
@@ -2360,14 +2767,24 @@ protected internal static PdfArray ProcessOptions(String[] options) {
return array;
}
- protected internal virtual String GenerateDefaultAppearanceString(PdfFont font, int fontSize, PdfResources
- res) {
+ protected internal virtual String GenerateDefaultAppearanceString(PdfFont font, float fontSize, Color color
+ , PdfResources res) {
PdfStream stream = new PdfStream();
PdfCanvas canvas = new PdfCanvas(stream, res, GetDocument());
- canvas.SetFontAndSize(font, fontSize).ResetFillColorRgb();
+ canvas.SetFontAndSize(font, fontSize);
+ if (color != null) {
+ canvas.SetColor(color, true);
+ }
return iText.IO.Util.JavaUtil.GetStringForBytes(stream.GetBytes());
}
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use GenerateDefaultAppearanceString(iText.Kernel.Font.PdfFont, float, iText.Kernel.Colors.Color, iText.Kernel.Pdf.PdfResources) instead."
+ )]
+ protected internal virtual String GenerateDefaultAppearanceString(PdfFont font, int fontSize, PdfResources
+ res) {
+ return GenerateDefaultAppearanceString(font, (float)fontSize, color, res);
+ }
+
///
protected internal virtual Object[] GetFontAndSize(PdfDictionary asNormal) {
Object[] fontAndSize = new Object[2];
@@ -2375,11 +2792,20 @@ protected internal virtual Object[] GetFontAndSize(PdfDictionary asNormal) {
if (asNormal != null) {
resources = asNormal.GetAsDictionary(PdfName.Resources);
}
+ if (resources == null) {
+ PdfDocument document = GetDocument();
+ if (document != null) {
+ PdfDictionary acroformDictionary = document.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.AcroForm);
+ if (acroformDictionary != null) {
+ resources = acroformDictionary.GetAsDictionary(PdfName.DR);
+ }
+ }
+ }
if (resources != null) {
PdfDictionary fontDic = resources.GetAsDictionary(PdfName.Font);
- if (fontDic != null) {
- String str = GetDefaultAppearance().ToUnicodeString();
- Object[] dab = SplitDAelements(str);
+ PdfString defaultAppearance = GetDefaultAppearance();
+ if (fontDic != null && defaultAppearance != null) {
+ Object[] dab = SplitDAelements(defaultAppearance.ToUnicodeString());
PdfName fontName = new PdfName(dab[DA_FONT].ToString());
if (font != null) {
fontAndSize[0] = font;
@@ -2408,7 +2834,7 @@ protected internal virtual Object[] GetFontAndSize(PdfDictionary asNormal) {
fontAndSize[1] = fontSize;
}
else {
- fontAndSize[1] = DEFAULT_FONT_SIZE;
+ fontAndSize[1] = (float)DEFAULT_FONT_SIZE;
}
}
}
@@ -2423,7 +2849,7 @@ protected internal virtual Object[] GetFontAndSize(PdfDictionary asNormal) {
fontAndSize[1] = fontSize;
}
else {
- fontAndSize[1] = DEFAULT_FONT_SIZE;
+ fontAndSize[1] = (float)DEFAULT_FONT_SIZE;
}
}
return fontAndSize;
@@ -2444,13 +2870,15 @@ protected internal static Object[] SplitDAelements(String da) {
if (@operator.Equals("Tf")) {
if (stack.Count >= 2) {
ret[DA_FONT] = stack[stack.Count - 2];
- ret[DA_SIZE] = System.Convert.ToInt32(stack[stack.Count - 1]);
+ ret[DA_SIZE] = System.Convert.ToSingle(stack[stack.Count - 1], System.Globalization.CultureInfo.InvariantCulture
+ );
}
}
else {
if (@operator.Equals("g")) {
if (stack.Count >= 1) {
- float gray = System.Convert.ToSingle(stack[stack.Count - 1]);
+ float gray = System.Convert.ToSingle(stack[stack.Count - 1], System.Globalization.CultureInfo.InvariantCulture
+ );
if (gray != 0) {
ret[DA_COLOR] = new DeviceGray(gray);
}
@@ -2459,19 +2887,26 @@ protected internal static Object[] SplitDAelements(String da) {
else {
if (@operator.Equals("rg")) {
if (stack.Count >= 3) {
- float red = System.Convert.ToSingle(stack[stack.Count - 3]);
- float green = System.Convert.ToSingle(stack[stack.Count - 2]);
- float blue = System.Convert.ToSingle(stack[stack.Count - 1]);
+ float red = System.Convert.ToSingle(stack[stack.Count - 3], System.Globalization.CultureInfo.InvariantCulture
+ );
+ float green = System.Convert.ToSingle(stack[stack.Count - 2], System.Globalization.CultureInfo.InvariantCulture
+ );
+ float blue = System.Convert.ToSingle(stack[stack.Count - 1], System.Globalization.CultureInfo.InvariantCulture
+ );
ret[DA_COLOR] = new DeviceRgb(red, green, blue);
}
}
else {
if (@operator.Equals("k")) {
if (stack.Count >= 4) {
- float cyan = System.Convert.ToSingle(stack[stack.Count - 4]);
- float magenta = System.Convert.ToSingle(stack[stack.Count - 3]);
- float yellow = System.Convert.ToSingle(stack[stack.Count - 2]);
- float black = System.Convert.ToSingle(stack[stack.Count - 1]);
+ float cyan = System.Convert.ToSingle(stack[stack.Count - 4], System.Globalization.CultureInfo.InvariantCulture
+ );
+ float magenta = System.Convert.ToSingle(stack[stack.Count - 3], System.Globalization.CultureInfo.InvariantCulture
+ );
+ float yellow = System.Convert.ToSingle(stack[stack.Count - 2], System.Globalization.CultureInfo.InvariantCulture
+ );
+ float black = System.Convert.ToSingle(stack[stack.Count - 1], System.Globalization.CultureInfo.InvariantCulture
+ );
ret[DA_COLOR] = new DeviceCmyk(cyan, magenta, yellow, black);
}
}
@@ -2496,19 +2931,14 @@ protected internal static Object[] SplitDAelements(String da) {
/// a
///
///
- /// a positive integer
+ /// the size of the font
/// the initial value
- ///
- /// the
- /// Form XObject
- /// that was drawn
- ///
- protected internal virtual void DrawTextAppearance(Rectangle rect, PdfFont font, int fontSize, String value
+ protected internal virtual void DrawTextAppearance(Rectangle rect, PdfFont font, float fontSize, String value
, PdfFormXObject appearance) {
PdfStream stream = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
PdfResources resources = appearance.GetResources();
PdfCanvas canvas = new PdfCanvas(stream, resources, GetDocument());
- SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, resources));
+ SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, color, resources));
float height = rect.GetHeight();
float width = rect.GetWidth();
PdfFormXObject xObject = new PdfFormXObject(new Rectangle(0, 0, width, height));
@@ -2526,7 +2956,7 @@ protected internal virtual void DrawTextAppearance(Rectangle rect, PdfFont font,
if (justification == null) {
justification = 0;
}
- float x = 0;
+ float x = 2;
TextAlignment? textAlignment = TextAlignment.LEFT;
if (justification == ALIGN_RIGHT) {
textAlignment = TextAlignment.RIGHT;
@@ -2538,26 +2968,43 @@ protected internal virtual void DrawTextAppearance(Rectangle rect, PdfFont font,
x = rect.GetWidth() / 2;
}
}
- new iText.Layout.Canvas(canvas, GetDocument(), new Rectangle(0, -height, 0, 2 * height)).ShowTextAligned(paragraph
- , x, rect.GetHeight() / 2, textAlignment, VerticalAlignment.MIDDLE);
+ iText.Layout.Canvas modelCanvas = new iText.Layout.Canvas(canvas, GetDocument(), new Rectangle(0, -height,
+ 0, 2 * height));
+ modelCanvas.SetProperty(Property.APPEARANCE_STREAM_LAYOUT, true);
+ modelCanvas.ShowTextAligned(paragraph, x, rect.GetHeight() / 2, textAlignment, VerticalAlignment.MIDDLE);
canvas.RestoreState().EndVariableText();
appearance.GetPdfObject().SetData(stream.GetBytes());
}
+ /// Draws the visual appearance of text in a form field.
+ /// the location on the page for the list field
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ /// the initial value
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use DrawTextAppearance(iText.Kernel.Geom.Rectangle, iText.Kernel.Font.PdfFont, float, System.String, iText.Kernel.Pdf.Xobject.PdfFormXObject) instead."
+ )]
+ protected internal virtual void DrawTextAppearance(Rectangle rect, PdfFont font, int fontSize, String value
+ , PdfFormXObject appearance) {
+ DrawTextAppearance(rect, font, (float)fontSize, value, appearance);
+ }
+
/// Draws the visual appearance of multiline text in a form field.
/// the location on the page for the list field
///
/// a
///
///
- /// a positive integer
+ /// the size of the font
/// the initial value
- protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfFont font, int fontSize, String
- value, PdfFormXObject appearance) {
+ protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfFont font, float fontSize,
+ String value, PdfFormXObject appearance) {
PdfStream stream = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
PdfResources resources = appearance.GetResources();
PdfCanvas canvas = new PdfCanvas(stream, resources, GetDocument());
- SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, resources));
+ SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, color, resources));
float width = rect.GetWidth();
float height = rect.GetHeight();
IList strings = font.SplitString(value, fontSize, width - 6);
@@ -2565,6 +3012,7 @@ protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfF
canvas.BeginVariableText().SaveState().Rectangle(3, 3, width - 6, height - 6).Clip().NewPath();
iText.Layout.Canvas modelCanvas = new iText.Layout.Canvas(canvas, GetDocument(), new Rectangle(3, 0, Math.
Max(0, width - 6), Math.Max(0, height - 2)));
+ modelCanvas.SetProperty(Property.APPEARANCE_STREAM_LAYOUT, true);
for (int index = 0; index < strings.Count; index++) {
bool? isFull = modelCanvas.GetRenderer().GetPropertyAsBoolean(Property.FULL);
if (true.Equals(isFull)) {
@@ -2594,6 +3042,21 @@ protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfF
appearance.GetPdfObject().SetData(stream.GetBytes());
}
+ /// Draws the visual appearance of multiline text in a form field.
+ /// the location on the page for the list field
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ /// the initial value
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use DrawMultiLineTextAppearance(iText.Kernel.Geom.Rectangle, iText.Kernel.Font.PdfFont, float, System.String, iText.Kernel.Pdf.Xobject.PdfFormXObject) instead."
+ )]
+ protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfFont font, int fontSize, String
+ value, PdfFormXObject appearance) {
+ DrawMultiLineTextAppearance(rect, font, (float)fontSize, value, appearance);
+ }
+
/// Draws a border using the borderWidth and borderColor of the form field.
///
/// the
@@ -2605,6 +3068,8 @@ protected internal virtual void DrawMultiLineTextAppearance(Rectangle rect, PdfF
protected internal virtual void DrawBorder(PdfCanvas canvas, PdfFormXObject xObject, float width, float height
) {
canvas.SaveState();
+ float borderWidth = GetBorderWidth();
+ PdfDictionary bs = GetWidgets()[0].GetBorderStyle();
if (borderWidth < 0) {
borderWidth = 0;
}
@@ -2617,7 +3082,40 @@ protected internal virtual void DrawBorder(PdfCanvas canvas, PdfFormXObject xObj
}
if (borderWidth > 0) {
borderWidth = Math.Max(1, borderWidth);
- canvas.SetStrokeColor(borderColor).SetLineWidth(borderWidth).Rectangle(0, 0, width, height).Stroke();
+ canvas.SetStrokeColor(borderColor).SetLineWidth(borderWidth);
+ if (bs != null) {
+ PdfName borderType = bs.GetAsName(PdfName.S);
+ if (borderType != null && borderType.Equals(PdfName.D)) {
+ PdfArray dashArray = bs.GetAsArray(PdfName.D);
+ if (dashArray != null) {
+ int unitsOn = dashArray.GetAsNumber(0) != null ? dashArray.GetAsNumber(0).IntValue() : 0;
+ int unitsOff = dashArray.GetAsNumber(1) != null ? dashArray.GetAsNumber(1).IntValue() : 0;
+ canvas.SetLineDash(unitsOn, unitsOff, 0);
+ }
+ }
+ }
+ canvas.Rectangle(0, 0, width, height).Stroke();
+ }
+ ApplyRotation(xObject, height, width);
+ canvas.RestoreState();
+ }
+
+ protected internal virtual void DrawRadioBorder(PdfCanvas canvas, PdfFormXObject xObject, float width, float
+ height) {
+ canvas.SaveState();
+ float borderWidth = GetBorderWidth();
+ float cx = width / 2;
+ float cy = height / 2;
+ if (borderWidth < 0) {
+ borderWidth = 0;
+ }
+ float r = (Math.Min(width, height) - borderWidth) / 2;
+ if (backgroundColor != null) {
+ canvas.SetFillColor(backgroundColor).Circle(cx, cy, r + borderWidth / 2).Fill();
+ }
+ if (borderWidth > 0 && borderColor != null) {
+ borderWidth = Math.Max(1, borderWidth);
+ canvas.SetStrokeColor(borderColor).SetLineWidth(borderWidth).Circle(cx, cy, r).Stroke();
}
ApplyRotation(xObject, height, width);
canvas.RestoreState();
@@ -2633,11 +3131,11 @@ protected internal virtual void DrawRadioAppearance(float width, float height, S
Rectangle rect = new Rectangle(0, 0, width, height);
PdfFormXObject xObjectOn = new PdfFormXObject(rect);
PdfFormXObject xObjectOff = new PdfFormXObject(rect);
- DrawBorder(canvasOn, xObjectOn, width, height);
+ DrawRadioBorder(canvasOn, xObjectOn, width, height);
DrawRadioField(canvasOn, width, height, true);
PdfStream streamOff = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
PdfCanvas canvasOff = new PdfCanvas(streamOff, new PdfResources(), GetDocument());
- DrawBorder(canvasOff, xObjectOff, width, height);
+ DrawRadioBorder(canvasOff, xObjectOff, width, height);
if (pdfAConformanceLevel != null && (pdfAConformanceLevel.GetPart().Equals("2") || pdfAConformanceLevel.GetPart
().Equals("3"))) {
xObjectOn.GetResources();
@@ -2695,16 +3193,16 @@ protected internal virtual void DrawCheckAppearance(float width, float height, S
PdfFormXObject xObjectOn = new PdfFormXObject(rect);
PdfFormXObject xObjectOff = new PdfFormXObject(rect);
DrawBorder(canvasOn, xObjectOn, width, height);
- DrawCheckBox(canvasOn, width, height, DEFAULT_FONT_SIZE, true);
+ DrawCheckBox(canvasOn, width, height, (float)DEFAULT_FONT_SIZE, true);
PdfStream streamOff = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
PdfCanvas canvasOff = new PdfCanvas(streamOff, new PdfResources(), GetDocument());
DrawBorder(canvasOff, xObjectOff, width, height);
- DrawCheckBox(canvasOff, width, height, DEFAULT_FONT_SIZE, false);
+ DrawCheckBox(canvasOff, width, height, (float)DEFAULT_FONT_SIZE, false);
PdfWidgetAnnotation widget = GetWidgets()[0];
xObjectOn.GetPdfObject().GetOutputStream().WriteBytes(streamOn.GetBytes());
xObjectOn.GetResources().AddFont(GetDocument(), GetFont());
- SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize == 0 ? DEFAULT_FONT_SIZE : fontSize, xObjectOn
- .GetResources()));
+ SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize == 0 ? (float)DEFAULT_FONT_SIZE : fontSize
+ , color, xObjectOn.GetResources()));
xObjectOff.GetPdfObject().GetOutputStream().WriteBytes(streamOff.GetBytes());
xObjectOff.GetResources().AddFont(GetDocument(), GetFont());
PdfDictionary normalAppearance = new PdfDictionary();
@@ -2770,13 +3268,13 @@ protected internal virtual void DrawPdfA2CheckAppearance(float width, float heig
/// a
///
///
- /// a positive integer
+ /// the size of the font
///
/// a new
///
///
protected internal virtual PdfFormXObject DrawPushButtonAppearance(float width, float height, String text,
- PdfFont font, int fontSize) {
+ PdfFont font, float fontSize) {
PdfStream stream = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
PdfCanvas canvas = new PdfCanvas(stream, new PdfResources(), GetDocument());
PdfFormXObject xObject = new PdfFormXObject(new Rectangle(0, 0, width, height));
@@ -2798,7 +3296,7 @@ protected internal virtual PdfFormXObject DrawPushButtonAppearance(float width,
}
else {
DrawButton(canvas, 0, 0, width, height, text, font, fontSize);
- SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, new PdfResources()));
+ SetDefaultAppearance(GenerateDefaultAppearanceString(font, fontSize, color, new PdfResources()));
xObject.GetResources().AddFont(GetDocument(), font);
}
}
@@ -2806,6 +3304,26 @@ protected internal virtual PdfFormXObject DrawPushButtonAppearance(float width,
return xObject;
}
+ /// Draws the appearance for a push button.
+ /// the width of the pushbutton
+ /// the width of the pushbutton
+ /// the text to display on the button
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ ///
+ /// a new
+ ///
+ ///
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use DrawPushButtonAppearance(float, float, System.String, iText.Kernel.Font.PdfFont, float) instead."
+ )]
+ protected internal virtual PdfFormXObject DrawPushButtonAppearance(float width, float height, String text,
+ PdfFont font, int fontSize) {
+ return DrawPushButtonAppearance(width, height, text, font, (float)fontSize);
+ }
+
/// Performs the low-level drawing operations to draw a button object.
///
/// the
@@ -2821,16 +3339,42 @@ protected internal virtual PdfFormXObject DrawPushButtonAppearance(float width,
/// a
///
///
- /// a positive integer
+ /// the size of the font
protected internal virtual void DrawButton(PdfCanvas canvas, float x, float y, float width, float height,
- String text, PdfFont font, int fontSize) {
+ String text, PdfFont font, float fontSize) {
if (color == null) {
color = Color.BLACK;
}
Paragraph paragraph = new Paragraph(text).SetFont(font).SetFontSize(fontSize).SetMargin(0).SetMultipliedLeading
(1).SetVerticalAlignment(VerticalAlignment.MIDDLE);
- new iText.Layout.Canvas(canvas, GetDocument(), new Rectangle(0, -height, width, 2 * height)).ShowTextAligned
- (paragraph, width / 2, height / 2, TextAlignment.CENTER, VerticalAlignment.MIDDLE);
+ iText.Layout.Canvas modelCanvas = new iText.Layout.Canvas(canvas, GetDocument(), new Rectangle(0, -height,
+ width, 2 * height));
+ modelCanvas.SetProperty(Property.APPEARANCE_STREAM_LAYOUT, true);
+ modelCanvas.ShowTextAligned(paragraph, width / 2, height / 2, TextAlignment.CENTER, VerticalAlignment.MIDDLE
+ );
+ }
+
+ /// Performs the low-level drawing operations to draw a button object.
+ ///
+ /// the
+ ///
+ /// of the page to draw on.
+ ///
+ /// the x coordinate of the lower left corner of the button rectangle
+ /// the y coordinate of the lower left corner of the button rectangle
+ /// the width of the button
+ /// the width of the button
+ /// the text to display on the button
+ ///
+ /// a
+ ///
+ ///
+ /// the size of the font
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use DrawButton(iText.Kernel.Pdf.Canvas.PdfCanvas, float, float, float, float, System.String, iText.Kernel.Font.PdfFont, float) instead."
+ )]
+ protected internal virtual void DrawButton(PdfCanvas canvas, float x, float y, float width, float height,
+ String text, PdfFont font, int fontSize) {
+ DrawButton(canvas, x, y, width, height, text, font, (float)fontSize);
}
/// Performs the low-level drawing operations to draw a checkbox object.
@@ -2841,10 +3385,10 @@ protected internal virtual void DrawButton(PdfCanvas canvas, float x, float y, f
///
/// the width of the button
/// the width of the button
- /// a positive integer
+ /// the size of the font
/// the boolean value of the checkbox
- protected internal virtual void DrawCheckBox(PdfCanvas canvas, float width, float height, int fontSize, bool
- on) {
+ protected internal virtual void DrawCheckBox(PdfCanvas canvas, float width, float height, float fontSize,
+ bool on) {
if (!on) {
return;
}
@@ -2861,6 +3405,23 @@ protected internal virtual void DrawCheckBox(PdfCanvas canvas, float width, floa
(text, fontSize)) / 2, (height - ufont.GetAscent(text, fontSize)) / 2).ShowText(text).EndText();
}
+ /// Performs the low-level drawing operations to draw a checkbox object.
+ ///
+ /// the
+ ///
+ /// of the page to draw on.
+ ///
+ /// the width of the button
+ /// the width of the button
+ /// the size of the font
+ /// the boolean value of the checkbox
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use DrawCheckBox(iText.Kernel.Pdf.Canvas.PdfCanvas, float, float, float, bool) instead."
+ )]
+ protected internal virtual void DrawCheckBox(PdfCanvas canvas, float width, float height, int fontSize, bool
+ on) {
+ DrawCheckBox(canvas, width, height, (float)fontSize, on);
+ }
+
protected internal virtual void DrawPdfACheckBox(PdfCanvas canvas, float width, float height, bool on) {
if (!on) {
return;
@@ -2900,7 +3461,8 @@ protected internal virtual void DrawPdfACheckBox(PdfCanvas canvas, float width,
canvas.SaveState();
canvas.ResetFillColorRgb();
canvas.ConcatMatrix(width, 0, 0, height, 0, 0);
- canvas.GetContentStream().GetOutputStream().WriteBytes(appearanceString.GetBytes());
+ canvas.GetContentStream().GetOutputStream().WriteBytes(appearanceString.GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1
+ ));
canvas.RestoreState();
}
@@ -2961,5 +3523,9 @@ private String OptionsArrayToString(PdfArray options) {
value = value.JSubstring(0, value.Length - 1);
return value;
}
+
+ private static double DegreeToRadians(double angle) {
+ return Math.PI * angle / 180.0;
+ }
}
}
diff --git a/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs b/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
index 0b09259a9c..2a1e8ede02 100644
--- a/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
+++ b/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
@@ -67,7 +67,6 @@ protected internal PdfTextFormField(PdfWidgetAnnotation widget, PdfDocument pdfD
protected internal PdfTextFormField(PdfDictionary pdfObject)
: base(pdfObject) {
- SetBorderWidth(0);
}
/// Returns Tx, the form type for textual form fields.
diff --git a/itext/itext.forms/itext/forms/xfa/XfaForm.cs b/itext/itext.forms/itext/forms/xfa/XfaForm.cs
index 70f06c5460..4f178b033f 100644
--- a/itext/itext.forms/itext/forms/xfa/XfaForm.cs
+++ b/itext/itext.forms/itext/forms/xfa/XfaForm.cs
@@ -673,6 +673,8 @@ private void ExtractNodes()
{
datasetsNode = (XElement)xfaNodes["datasets"];
datasetsSom = new Xml2SomDatasets(datasetsNode.FirstNode);
+ XElement dataNode = FindDataNode(datasetsNode);
+ datasetsSom = new Xml2SomDatasets(dataNode != null ? dataNode : datasetsNode.FirstNode);
}
if (datasetsNode == null)
{
@@ -714,6 +716,12 @@ private XNode GetFirstElementNode(XNode src)
return result;
}
+ private XElement FindDataNode(XElement datasetsNode)
+ {
+ return datasetsNode.Element("{xfa}data");
+ }
+
+
private class UpperCaseUTF8Encoding : UTF8Encoding
{
// Code from a blog http://www.distribucon.com/blog/CategoryView,category,XML.aspx
diff --git a/itext/itext.forms/itext/forms/xfa/Xml2SomDatasets.cs b/itext/itext.forms/itext/forms/xfa/Xml2SomDatasets.cs
index 3b3b3413d2..9a10bad2b7 100644
--- a/itext/itext.forms/itext/forms/xfa/Xml2SomDatasets.cs
+++ b/itext/itext.forms/itext/forms/xfa/Xml2SomDatasets.cs
@@ -44,7 +44,6 @@ source product.
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Xml;
using System.Xml.Linq;
namespace iText.Forms.Xfa
@@ -162,29 +161,21 @@ private void ProcessDatasetsInternal(XNode n)
String s = EscapeSom(((XElement) n2).Name.LocalName);
int? i = ss.Get(s);
if (i == null)
- {
- i = 0;
- }
- else
- {
- i += 1;
- }
- ss[s] = i;
- if (HasChildren(n2))
- {
- stack.Push(s + "[" + i.ToString() + "]");
- ProcessDatasetsInternal(n2);
- stack.Pop();
- }
- else
- {
- stack.Push(s + "[" + i.ToString() + "]");
- String unstack = PrintStack();
- order.Add(unstack);
- InverseSearchAdd(unstack);
- name2Node[unstack] = n2;
- stack.Pop();
- }
+ i = 0;
+ else
+ i = i + 1;
+ ss[s] = i;
+ stack.Push(string.Format("{0}[{1}]", s, i));
+ if (HasChildren(n2))
+ {
+ ProcessDatasetsInternal(n2);
+ }
+ String unstack = PrintStack();
+ order.Add(unstack);
+ InverseSearchAdd(unstack);
+ name2Node[unstack] = n2;
+ stack.Pop();
+
}
n2 = n2 is XElement ? ((XElement) n2).NextNode : (n2 is XText ? ((XText)n2).NextNode : null);
}
diff --git a/itext/itext.hyph/Properties/AssemblyInfo.cs b/itext/itext.hyph/Properties/AssemblyInfo.cs
index 184652d85c..8a81341ea8 100644
--- a/itext/itext.hyph/Properties/AssemblyInfo.cs
+++ b/itext/itext.hyph/Properties/AssemblyInfo.cs
@@ -15,5 +15,5 @@
[assembly: Guid("56137079-541a-425a-ab97-43af63793c97")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.io/Properties/AssemblyInfo.cs b/itext/itext.io/Properties/AssemblyInfo.cs
index 25113447cb..3d106d1ee6 100644
--- a/itext/itext.io/Properties/AssemblyInfo.cs
+++ b/itext/itext.io/Properties/AssemblyInfo.cs
@@ -21,5 +21,5 @@
[assembly: Guid("39631ecb-1d39-4eb2-b775-37bd34cbf5a4")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.io/itext/io/IOException.cs b/itext/itext.io/itext/io/IOException.cs
index 9cdaaebac2..ac2777e261 100644
--- a/itext/itext.io/itext/io/IOException.cs
+++ b/itext/itext.io/itext/io/IOException.cs
@@ -46,217 +46,294 @@ source product.
using iText.IO.Util;
namespace iText.IO {
+ /// Exception class for exceptions in io module.
public class IOException : Exception {
- public const String _1BitSamplesAreNotSupportedForHorizontalDifferencingPredictor = "{0} bit.samples.are.not.supported.for.horizontal.differencing.predictor";
+ public const String _1BitSamplesAreNotSupportedForHorizontalDifferencingPredictor = "{0} bit samples are not supported for horizontal differencing predictor.";
- public const String _1CorruptedJfifMarker = "{0} corrupted.jfif.marker";
+ public const String _1CorruptedJfifMarker = "{0} corrupted jfif marker.";
- public const String _1IsNotAValidJpegFile = "{0} is.not.a.valid.jpeg.file";
+ public const String _1IsNotAValidJpegFile = "{0} is not a valid jpeg file.";
- public const String _1MustHave8BitsPerComponent = "{0} must.have.8.bits.per.component";
+ public const String _1MustHave8BitsPerComponent = "{0} must have 8 bits per component.";
- public const String _1UnsupportedJpegMarker2 = "{0} unsupported.jpeg.marker {1}";
+ public const String _1UnsupportedJpegMarker2 = "{0} unsupported jpeg marker {1}.";
- public const String _1IsNotAnAfmOrPfmFontFile = "{0} is.not.an.afm.or.pfm.font.file";
+ public const String _1IsNotAnAfmOrPfmFontFile = "{0} is not an afm or pfm font file.";
public const String _1NotFoundAsFileOrResource = "{0} not found as file or resource.";
- public const String AllFillBitsPrecedingEolCodeMustBe0 = "all.fill.bits.preceding.eol.code.must.be.0";
+ public const String AllFillBitsPrecedingEolCodeMustBe0 = "All fill bits preceding eol code must be 0.";
- public const String BadEndiannessTagNot0x4949Or0x4d4d = "bad.endianness.tag.not.0x4949.or.0x4d4d";
+ [Obsolete]
+ public const String BadEndiannessTagNot0x4949Or0x4d4d = "Bad endianness tag not 0x4949 or 0x4d4d.";
- public const String BadMagicNumberShouldBe42 = "bad.magic.number.should.be.42";
+ public const String BadEndiannessTag0x4949Or0x4d4d = "Bad endianness tag: 0x4949 or 0x4d4d.";
- public const String BitsPerComponentMustBe1_2_4or8 = "bits.per.component.must.be.1.2.4.or.8";
+ public const String BadMagicNumberShouldBe42 = "Bad magic number. Should be 42.";
- public const String BitsPerSample1IsNotSupported = "bits.per.sample {0} is.not.supported";
+ public const String BitsPerComponentMustBe1_2_4or8 = "Bits per component must be 1, 2, 4 or 8.";
- public const String BmpImageException = "bmp.image.exception";
+ public const String BitsPerSample1IsNotSupported = "Bits per sample {0} is not supported.";
- public const String BytesCanBeAssignedToByteArrayOutputStreamOnly = "bytes.can.be.assigned.to.bytearrayoutputstream.only";
+ public const String BmpImageException = "Bmp image exception.";
- public const String BytesCanBeResetInByteArrayOutputStreamOnly = "bytes.can.be.reset.in.bytearrayoutputstream.only";
+ public const String BytesCanBeAssignedToByteArrayOutputStreamOnly = "Bytes can be assigned to ByteArrayOutputStream only.";
- public const String CannotGetTiffImageColor = "cannot.get.tiff.image.color";
+ public const String BytesCanBeResetInByteArrayOutputStreamOnly = "Bytes can be reset in ByteArrayOutputStream only.";
- public const String CannotFind1Frame = "cannot.find {0} frame";
+ public const String CannotGetTiffImageColor = "Cannot get TIFF image color.";
- public const String CannotHandleBoxSizesHigherThan2_32 = "cannot.handle.box.sizes.higher.than.2.32";
+ public const String CannotFind1Frame = "Cannot find {0} frame.";
- public const String CannotInflateTiffImage = "cannot.inflate.tiff.image";
+ public const String CannotHandleBoxSizesHigherThan2_32 = "Cannot handle box sizes higher than 2^32.";
- public const String CannotReadTiffImage = "cannot.read.tiff.image";
+ public const String CannotInflateTiffImage = "Cannot inflate TIFF image.";
- public const String CannotWriteByte = "cannot.write.byte";
+ public const String CannotReadTiffImage = "Cannot read TIFF image.";
- public const String CannotWriteBytes = "cannot.write.bytes";
+ public const String CannotWriteByte = "Cannot write byte.";
- public const String CannotWriteFloatNumber = "cannot.write.float.number";
+ public const String CannotWriteBytes = "Cannot write bytes.";
- public const String CannotWriteIntNumber = "cannot.write.int.number";
+ public const String CannotWriteFloatNumber = "Cannot write float number.";
- public const String CcittCompressionTypeMustBeCcittg4Ccittg3_1dOrCcittg3_2d = "ccitt.compression.type.must.be.ccittg4.ccittg3.1d.or.ccittg3.2d";
+ public const String CannotWriteIntNumber = "Cannot write int number.";
+ public const String CcittCompressionTypeMustBeCcittg4Ccittg3_1dOrCcittg3_2d = "CCITT compression type must be CCITTG4, CCITTG3_1D or CCITTG3_2D.";
+
+ [Obsolete]
public const String TheCmap1WasNotFound = "The CMap {0} was not found";
- public const String ComponentsMustBe1_3Or4 = "components.must.be.1.3.or.4";
+ public const String Cmap1WasNotFound = "The CMap {0} was not found.";
+
+ public const String ComponentsMustBe1_3Or4 = "Components must be 1, 3 or 4.";
- public const String Compression1IsNotSupported = "compression {0} is.not.supported";
+ public const String Compression1IsNotSupported = "Compression {0} is not supported.";
- public const String ColorDepthIsNotSupported = "the.color.depth {0} is.not.supported";
+ public const String ColorDepthIsNotSupported = "The color depth {0} is not supported.";
- public const String ColorSpaceIsNotSupported = "the.color.space {0} is.not.supported";
+ public const String ColorSpaceIsNotSupported = "The color space {0} is not supported.";
- public const String CompressionJpegIsOnlySupportedWithASingleStripThisImageHas1Strips = "compression.jpeg.is.only.supported.with.a.single.strip.this.image.has {0} strips";
+ public const String CompressionJpegIsOnlySupportedWithASingleStripThisImageHas1Strips = "Compression jpeg is only supported with a single strip. This image has {0} strips.";
+ [Obsolete]
public const String DirectoryNumberTooLarge = "directory.number.too.large";
- public const String EolCodeWordEncounteredInBlackRun = "eol.code.word.encountered.in.black.run";
+ public const String DirectoryNumberIsTooLarge = "Directory number is too large.";
+
+ public const String EolCodeWordEncounteredInBlackRun = "EOL code word encountered in Black run.";
+
+ public const String EolCodeWordEncounteredInWhiteRun = "EOL code word encountered in White run.";
+
+ public const String ErrorAtFilePointer1 = "Error at file pointer {0}.";
+
+ public const String ErrorReadingString = "Error reading string.";
+
+ public const String ErrorWithJpMarker = "Error with JP marker.";
+
+ public const String ExpectedFtypMarker = "Expected FTYP marker.";
+
+ public const String ExpectedIhdrMarker = "Expected IHDR marker.";
+
+ public const String ExpectedJpMarker = "Expected JP marker.";
+
+ public const String ExpectedJp2hMarker = "Expected JP2H marker.";
+
+ public const String ExtraSamplesAreNotSupported = "Extra samples are not supported.";
+
+ public const String FdfStartxrefNotFound = "FDF startxref not found.";
+
+ public const String FirstScanlineMustBe1dEncoded = "First scanline must be 1D encoded.";
+
+ public const String FontFile1NotFound = "Font file {0} not found.";
+
+ public const String ImageFormatCannotBeRecognized = "Image format cannot be recognized.";
- public const String EolCodeWordEncounteredInWhiteRun = "eol.code.word.encountered.in.white.run";
+ public const String GifImageException = "GIF image exception.";
- public const String ErrorAtFilePointer1 = "error.at.file.pointer {0}";
+ public const String GtNotExpected = "'>' not expected.";
- public const String ErrorReadingString = "error.reading.string";
+ public const String GifSignatureNotFound = "GIF signature not found.";
- public const String ErrorWithJpMarker = "error.with.jp.marker";
+ public const String IllegalValueForPredictorInTiffFile = "Illegal value for predictor in TIFF file.";
- public const String ExpectedFtypMarker = "expected.ftyp.marker";
+ [Obsolete]
+ public const String Font1IsNotRecognized = "Font {0} is not recognized";
- public const String ExpectedIhdrMarker = "expected.ihdr.marker";
+ [Obsolete]
+ public const String FontIsNotRecognized = "Font is not recognized";
- public const String ExpectedJpMarker = "expected.jp.marker";
+ [Obsolete]
+ public const String ImageCanNotBeAnImageMask = "Image can not be an image mask.";
- public const String ExpectedJp2hMarker = "expected.jp2h.marker";
+ public const String ImageIsNotMaskYouMustCallImageDataMakeMask = "Image is not a mask. You must call ImageData#makeMask().";
- public const String ExtraSamplesAreNotSupported = "extra.samples.are.not.supported";
+ public const String ImageMaskCannotContainAnotherImageMask = "Image mask cannot contain another image mask.";
- public const String FdfStartxrefNotFound = "fdf.startxref.not.found";
+ [Obsolete]
+ public const String ImageMaskIsNotAMaskDidYouDoMakeMask = "Image is not a mask. You must call ImageData#makeMask().";
- public const String FirstScanlineMustBe1dEncoded = "first.scanline.must.be.1d.encoded";
+ public const String IncompletePalette = "Incomplete palette.";
- public const String FontFile1NotFound = "font.file {0} not.found";
+ [Obsolete]
+ public const String InvalidTTCFile = "{0} is not a valid TTC file.";
- public const String ImageFormatCannotBeRecognized = "image.format.cannot.be.recognized";
+ public const String InvalidTtcFile = "{0} is not a valid TTC file.";
- public const String GifImageException = "gif.image.exception";
+ public const String InvalidBmpFileCompression = "Invalid BMP file compression.";
- public const String GtNotExpected = "gt.not.expected";
+ public const String InvalidCodeEncountered = "Invalid code encountered.";
- public const String GifSignatureNotFound = "gif.signature.not.found";
+ public const String InvalidCodeEncounteredWhileDecoding2dGroup3CompressedData = "Invalid code encountered while decoding 2D group 3 compressed data.";
- public const String IllegalValueForPredictorInTiffFile = "illegal.value.for.predictor.in.tiff.file";
+ public const String InvalidCodeEncounteredWhileDecoding2dGroup4CompressedData = "Invalid code encountered while decoding 2D group 4 compressed data.";
- public const String Font1IsNotRecognized = "font {0} is.not.recognized";
+ public const String InvalidIccProfile = "Invalid ICC profile.";
- public const String FontIsNotRecognized = "font.is.not.recognized";
+ public const String InvalidJpeg2000File = "Invalid JPEG2000 file.";
- public const String ImageCanNotBeAnImageMask = "image.can.not.be.an.image.mask";
+ [Obsolete]
+ public const String InvalidMagicValueForBmpFile = "Invalid magic value for bmp file. Must be 'BM'";
- public const String ImageMaskCannotContainAnotherImageMask = "image.mask.cannot.contain.another.image.mask";
+ public const String InvalidMagicValueForBmpFileMustBeBM = "Invalid magic value for bmp file. Must be 'BM'";
- public const String ImageMaskIsNotAMaskDidYouDoMakeMask = "image.mask.is.not.a.mask.did.you.do.makemask";
+ public const String IoException = "I/O exception.";
- public const String IncompletePalette = "incomplete.palette";
+ public const String Jbig2ImageException = "JBIG2 image exception.";
- public const String InvalidTTCFile = "{0} is.not.a.valid.ttc.file";
+ public const String JpegImageException = "JPEG image exception.";
- public const String InvalidBmpFileCompression = "invalid.bmp.file.compression";
+ public const String Jpeg2000ImageException = "JPEG2000 image exception.";
- public const String InvalidCodeEncountered = "invalid.code.encountered";
+ [Obsolete]
+ public const String MissingTagSForOjpegCompression = "Missing tag(s) for OJPEG compression";
- public const String InvalidCodeEncounteredWhileDecoding2dGroup3CompressedData = "invalid.code.encountered.while.decoding.2d.group.3.compressed.data";
+ public const String MissingTagsForOjpegCompression = "Missing tag(s) for OJPEG compression";
- public const String InvalidCodeEncounteredWhileDecoding2dGroup4CompressedData = "invalid.code.encountered.while.decoding.2d.group.4.compressed.data";
+ public const String NValueIsNotSupported = "N value {1} is not supported.";
- public const String InvalidIccProfile = "invalid.icc.profile";
+ public const String PageNumberMustBeGtEq1 = "Page number must be >= 1.";
- public const String InvalidJpeg2000File = "invalid.jpeg2000.file";
+ [System.ObsoleteAttribute(@"because naming clash with Com itextpdf io font PdfEncodings may produce confusion with imports Superseded by CharacterCodeException"
+ )]
+ public const String PdfEncodings = "Pdf encodings.";
- public const String InvalidMagicValueForBmpFile = "invalid.magic.value.for.bmp.file";
+ public const String CharacterCodeException = "Character code exception.";
- public const String IoException = "io.exception";
+ public const String PdfHeaderNotFound = "PDF header not found.";
- public const String Jbig2ImageException = "jbig2.image.exception";
+ public const String PdfStartxrefNotFound = "PDF startxref not found.";
- public const String JpegImageException = "jpeg.image.exception";
+ public const String Photometric1IsNotSupported = "Photometric {0} is not supported.";
- public const String Jpeg2000ImageException = "jpeg2000.image.exception";
+ public const String PlanarImagesAreNotSupported = "Planar images are not supported.";
- public const String MissingTagSForOjpegCompression = "missing.tag.s.for.ojpeg.compression";
+ [Obsolete]
+ public const String PngFilterUnknown = "PNG filter unknown.";
- public const String NValueIsNotSupported = "N.value.1.is.not.supported";
+ public const String UnknownPngFilter = "Unknown PNG filter.";
- public const String PageNumberMustBeGtEq1 = "page.number.must.be.gt.eq {0}";
+ public const String PngImageException = "PNG image exception.";
- public const String PdfEncodings = "pdf.encodings";
+ [Obsolete]
+ public const String PrematureEofWhileReadingJpg = "Premature EOF while reading JPEG.";
- public const String PdfHeaderNotFound = "pdf.header.not.found";
+ public const String PrematureEofWhileReadingJpeg = "Premature EOF while reading JPEG.";
- public const String PdfStartxrefNotFound = "pdf.startxref.not.found";
+ public const String ScanlineMustBeginWithEolCodeWord = "Scanline must begin with EOL code word.";
- public const String Photometric1IsNotSupported = "photometric.1.is.not.supported";
+ public const String ThisImageCanNotBeAnImageMask = "This image can not be an image mask.";
- public const String PlanarImagesAreNotSupported = "planar.images.are.not.supported";
+ public const String Tiff50StyleLzwCodesAreNotSupported = "TIFF 5.0-style LZW codes are not supported.";
- public const String PngFilterUnknown = "png.filter.unknown";
+ public const String TiffFillOrderTagMustBeEither1Or2 = "TIFF_FILL_ORDER tag must be either 1 or 2.";
- public const String PngImageException = "png.image.exception";
+ public const String TiffImageException = "TIFF image exception.";
- public const String PrematureEofWhileReadingJpg = "premature.eof.while.reading.jpg";
+ [Obsolete]
+ public const String TTCIndexDoesNotExistInFile = "TTC index doesn't exist in ttc file.";
- public const String ScanlineMustBeginWithEolCodeWord = "scanline.must.begin.with.eol.code.word";
+ public const String TtcIndexDoesNotExistInThisTtcFile = "TTC index doesn't exist in this TTC file.";
- public const String Tiff50StyleLzwCodesAreNotSupported = "tiff.5.0.style.lzw.codes.are.not.supported";
+ public const String TilesAreNotSupported = "Tiles are not supported.";
- public const String TiffFillOrderTagMustBeEither1Or2 = "tiff.fill.order.tag.must.be.either.1.or.2";
+ public const String TransparencyLengthMustBeEqualTo2WithCcittImages = "Transparency length must be equal to 2 with CCITT images";
- public const String TiffImageException = "tiff.image.exception";
+ public const String TypeOfFont1IsNotRecognized = "Type of font {0} is not recognized.";
- public const String TTCIndexDoesNotExistInFile = "ttc.index.doesn't.exist.in.ttc.file";
+ public const String TypeOfFontIsNotRecognized = "Type of font is not recognized.";
- public const String TilesAreNotSupported = "tiles.are.not.supported";
+ public const String UnexpectedCloseBracket = "Unexpected close bracket.";
- public const String TransparencyLengthMustBeEqualTo2WithCcittImages = "transparency.length.must.be.equal.to.2.with.ccitt.images";
+ public const String UnexpectedGtGt = "Unexpected '>>'.";
- public const String UnexpectedCloseBracket = "unexpected.close.bracket";
+ public const String UnknownCompressionType1 = "Unknown compression type {0}.";
- public const String UnexpectedGtGt = "unexpected.gt.gt";
+ public const String UnknownIOException = "Unknown I/O exception.";
- public const String UnknownCompressionType1 = "unknown.compression.type {0}";
+ public const String UnsupportedBoxSizeEqEq0 = "Unsupported box size == 0.";
- public const String UnknownIOException = "unknown.io.exception";
+ public const String UnsupportedEncodingException = "Unsupported encoding exception.";
- public const String UnsupportedBoxSizeEqEq0 = "unsupported.box.size.eq.eq.0";
+ [Obsolete]
+ public const String WrongNumberOfComponentsInIccProfile = "ICC profile contains {0} components the image data contains {1} components.";
- public const String WrongNumberOfComponentsInIccProfile = "icc.profile.contains {0} components.the.image.data.contains {2} components";
+ public const String IccProfileContains0ComponentsWhileImageDataContains1Components = "ICC profile contains {0} components, while the image data contains {1} components.";
+ /// Object for more details
protected internal Object obj;
private IList
- /// the name of the font or its location on file
+ /// the name of the font or its location on file
/// returns a new font. This font may come from the cache
///
- public static FontProgram CreateFont(String name) {
- return CreateFont(name, null, true);
+ public static FontProgram CreateFont(String fontProgram) {
+ return CreateFont(fontProgram, null, DEFAULT_CACHED);
}
/// Creates a new font.
@@ -157,15 +160,15 @@ public static FontProgram CreateFont(String name) {
/// createFont(name, encoding, embedded, true, null, null);
///
///
- /// the name of the font or its location on file
+ /// the name of the font or its location on file
///
- /// ttrue if the font comes from the cache or is added to
+ /// true if the font comes from the cache or is added to
/// the cache if new, false if the font is always created new
///
/// returns a new font. This font may come from the cache
///
- public static FontProgram CreateFont(String font, bool cached) {
- return CreateFont(font, null, cached);
+ public static FontProgram CreateFont(String fontProgram, bool cached) {
+ return CreateFont(fontProgram, null, cached);
}
/// Creates a new font.
@@ -203,7 +206,7 @@ public static FontProgram CreateFont(String font, bool cached) {
/// "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
///
///
- ///
+ ///
/// the true type font or the afm in a byte array
/// an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances.
/// This parameter is useful for FontProgramFactory that may have to check many invalid font names before finding the right one
@@ -213,8 +216,8 @@ public static FontProgram CreateFont(String font, bool cached) {
/// is true, otherwise it will always be created new
///
///
- public static FontProgram CreateFont(byte[] font) {
- return CreateFont(null, font, false);
+ public static FontProgram CreateFont(byte[] fontProgram) {
+ return CreateFont(null, fontProgram, DEFAULT_CACHED);
}
/// Creates a new font.
@@ -274,53 +277,68 @@ public static FontProgram CreateFont(String name, byte[] font, bool cached) {
bool isBuiltinFonts14 = FontConstants.BUILTIN_FONTS_14.Contains(name);
bool isCidFont = !isBuiltinFonts14 && FontCache.IsPredefinedCidFont(baseName);
FontProgram fontFound;
- if (cached && name != null) {
- fontFound = FontCache.GetFont(name);
+ String fontKey = null;
+ if (cached) {
+ if (name != null) {
+ fontKey = name;
+ }
+ else {
+ fontKey = iText.IO.Util.JavaUtil.IntegerToString(ArrayUtil.HashCode(font));
+ }
+ fontFound = FontCache.GetFont(fontKey);
if (fontFound != null) {
return fontFound;
}
}
+ FontProgram fontBuilt = null;
if (name == null) {
if (font != null) {
try {
- return new TrueTypeFont(font);
+ fontBuilt = new TrueTypeFont(font);
}
catch (Exception) {
}
- try {
- return new Type1Font(null, null, font, null);
- }
- catch (Exception) {
+ if (fontBuilt == null) {
+ try {
+ fontBuilt = new Type1Font(null, null, font, null);
+ }
+ catch (Exception) {
+ }
}
}
- throw new iText.IO.IOException(iText.IO.IOException.FontIsNotRecognized);
- }
- FontProgram fontBuilt;
- if (isBuiltinFonts14 || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm") ||
- name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".pfm")) {
- fontBuilt = new Type1Font(name, null, font, null);
}
else {
- if (baseName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || baseName.ToLower
- (System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || baseName.ToLower(System.Globalization.CultureInfo.InvariantCulture
- ).IndexOf(".ttc,") > 0) {
- if (font != null) {
- fontBuilt = new TrueTypeFont(font);
- }
- else {
- fontBuilt = new TrueTypeFont(name);
- }
+ if (isBuiltinFonts14 || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm") ||
+ name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".pfm")) {
+ fontBuilt = new Type1Font(name, null, font, null);
}
else {
- if (isCidFont) {
- fontBuilt = new CidFont(name, FontCache.GetCompatibleCmaps(baseName));
+ if (baseName.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || baseName.ToLower
+ (System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || baseName.ToLower(System.Globalization.CultureInfo.InvariantCulture
+ ).IndexOf(".ttc,") > 0) {
+ if (font != null) {
+ fontBuilt = new TrueTypeFont(font);
+ }
+ else {
+ fontBuilt = new TrueTypeFont(name);
+ }
}
else {
- throw new iText.IO.IOException(iText.IO.IOException.Font1IsNotRecognized).SetMessageParams(name);
+ if (isCidFont) {
+ fontBuilt = new CidFont(name, FontCache.GetCompatibleCmaps(baseName));
+ }
}
}
}
- return cached ? FontCache.SaveFont(fontBuilt, name) : fontBuilt;
+ if (fontBuilt == null) {
+ if (name != null) {
+ throw new iText.IO.IOException(iText.IO.IOException.TypeOfFont1IsNotRecognized).SetMessageParams(name);
+ }
+ else {
+ throw new iText.IO.IOException(iText.IO.IOException.TypeOfFontIsNotRecognized);
+ }
+ }
+ return cached ? FontCache.SaveFont(fontBuilt, fontKey) : fontBuilt;
}
// todo make comment relevant to type 1 font creation
@@ -378,14 +396,21 @@ public static FontProgram CreateFont(String name, byte[] font, bool cached) {
///
public static FontProgram CreateType1Font(String name, byte[] afm, byte[] pfb, bool cached) {
FontProgram fontProgram;
- if (cached && name != null) {
- fontProgram = FontCache.GetFont(name);
+ String fontKey = null;
+ if (cached) {
+ if (name != null) {
+ fontKey = name;
+ }
+ else {
+ fontKey = iText.IO.Util.JavaUtil.IntegerToString(ArrayUtil.HashCode(afm));
+ }
+ fontProgram = FontCache.GetFont(fontKey);
if (fontProgram != null) {
return fontProgram;
}
}
fontProgram = new Type1Font(name, null, afm, pfb);
- return cached && name != null ? FontCache.SaveFont(fontProgram, name) : fontProgram;
+ return cached ? FontCache.SaveFont(fontProgram, fontKey) : fontProgram;
}
///
@@ -408,7 +433,7 @@ public static FontProgram CreateType1Font(String metricsPath, String binaryPath,
///
public static FontProgram CreateType1Font(String metricsPath, String binaryPath) {
- return CreateType1Font(metricsPath, binaryPath, true);
+ return CreateType1Font(metricsPath, binaryPath, DEFAULT_CACHED);
}
///
@@ -449,7 +474,7 @@ public static FontProgram CreateType1Font(String metricsPath, String binaryPath)
/// "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
///
///
- /// location of true type collection file (*.ttc)
+ /// location of true type collection file (*.ttc)
/// the encoding to be applied to this font
///
/// true if the font comes from the cache or is added to
@@ -460,29 +485,30 @@ public static FontProgram CreateType1Font(String metricsPath, String binaryPath)
/// is true, otherwise it will always be created new
///
///
- public static FontProgram CreateFont(String ttcPath, int ttcIndex, bool cached) {
+ public static FontProgram CreateFont(String ttc, int ttcIndex, bool cached) {
if (cached) {
- FontProgram fontFound = FontCache.GetFont(ttcPath + ttcIndex);
+ FontProgram fontFound = FontCache.GetFont(ttc + ttcIndex);
if (fontFound != null) {
return fontFound;
}
}
- FontProgram fontBuilt = new TrueTypeFont(ttcPath, ttcIndex);
- return cached ? FontCache.SaveFont(fontBuilt, ttcPath + ttcIndex) : fontBuilt;
+ FontProgram fontBuilt = new TrueTypeFont(ttc, ttcIndex);
+ return cached ? FontCache.SaveFont(fontBuilt, ttc + ttcIndex) : fontBuilt;
}
///
public static FontProgram CreateFont(byte[] ttc, int ttcIndex, bool cached) {
+ String fontKey = null;
if (cached) {
- String ttcNameKey = String.Format("{0}{1}", ArrayUtil.HashCode(ttc), ttcIndex);
- FontProgram fontFound = FontCache.GetFont(ttcNameKey);
+ fontKey = iText.IO.Util.JavaUtil.IntegerToString(ArrayUtil.HashCode(ttc)) + iText.IO.Util.JavaUtil.IntegerToString
+ (ttcIndex);
+ FontProgram fontFound = FontCache.GetFont(fontKey);
if (fontFound != null) {
return fontFound;
}
}
FontProgram fontBuilt = new TrueTypeFont(ttc, ttcIndex);
- String ttcNameKey_1 = String.Format("{0}{1}", ArrayUtil.HashCode(ttc), ttcIndex);
- return cached ? FontCache.SaveFont(fontBuilt, ttcNameKey_1) : fontBuilt;
+ return cached ? FontCache.SaveFont(fontBuilt, fontKey) : fontBuilt;
}
///
diff --git a/itext/itext.io/itext/io/font/FontRegisterProvider.cs b/itext/itext.io/itext/io/font/FontRegisterProvider.cs
index 7e70246774..5125ab8152 100644
--- a/itext/itext.io/itext/io/font/FontRegisterProvider.cs
+++ b/itext/itext.io/itext/io/font/FontRegisterProvider.cs
@@ -66,7 +66,7 @@ internal class FontRegisterProvider {
private readonly IDictionary> fontFamilies = new Dictionary>();
/// Creates new FontRegisterProvider
- public FontRegisterProvider() {
+ internal FontRegisterProvider() {
fontNames[FontConstants.COURIER.ToLower(System.Globalization.CultureInfo.InvariantCulture)] = FontConstants
.COURIER;
fontNames[FontConstants.COURIER_BOLD.ToLower(System.Globalization.CultureInfo.InvariantCulture)] = FontConstants
@@ -128,7 +128,7 @@ public FontRegisterProvider() {
/// the style of this font
/// the Font constructed based on the parameters
///
- public virtual FontProgram GetFont(String fontName, int style) {
+ internal virtual FontProgram GetFont(String fontName, int style) {
return GetFont(fontName, style, true);
}
@@ -141,7 +141,7 @@ public virtual FontProgram GetFont(String fontName, int style) {
///
/// the Font constructed based on the parameters
///
- public virtual FontProgram GetFont(String fontName, int style, bool cached) {
+ internal virtual FontProgram GetFont(String fontName, int style, bool cached) {
if (fontName == null) {
return null;
}
@@ -199,37 +199,37 @@ protected internal virtual FontProgram GetFontProgram(String fontName, bool cach
/// the font family
/// the font name
/// the font path
- public virtual void RegisterFontFamily(String familyName, String fullName, String path) {
+ internal virtual void RegisterFontFamily(String familyName, String fullName, String path) {
if (path != null) {
fontNames[fullName] = path;
}
- IList tmp;
+ IList family;
lock (fontFamilies) {
- tmp = fontFamilies.Get(familyName);
- if (tmp == null) {
- tmp = new List();
- fontFamilies[familyName] = tmp;
+ family = fontFamilies.Get(familyName);
+ if (family == null) {
+ family = new List();
+ fontFamilies[familyName] = family;
}
}
- lock (tmp) {
- if (!tmp.Contains(fullName)) {
+ lock (family) {
+ if (!family.Contains(fullName)) {
int fullNameLength = fullName.Length;
bool inserted = false;
- for (int j = 0; j < tmp.Count; ++j) {
- if (tmp[j].Length >= fullNameLength) {
- tmp.Add(j, fullName);
+ for (int j = 0; j < family.Count; ++j) {
+ if (family[j].Length >= fullNameLength) {
+ family.Add(j, fullName);
inserted = true;
break;
}
}
if (!inserted) {
- tmp.Add(fullName);
+ family.Add(fullName);
String newFullName = fullName.ToLower(System.Globalization.CultureInfo.InvariantCulture);
if (newFullName.EndsWith("regular")) {
//remove "regular" at the end of the font name
newFullName = newFullName.JSubstring(0, newFullName.Length - 7).Trim();
//insert this font name at the first position for higher priority
- tmp.Add(0, fullName.JSubstring(0, newFullName.Length));
+ family.Add(0, fullName.JSubstring(0, newFullName.Length));
}
}
}
@@ -238,14 +238,14 @@ public virtual void RegisterFontFamily(String familyName, String fullName, Strin
/// Register a ttf- or a ttc-file.
/// the path to a ttf- or ttc-file
- public virtual void RegisterFont(String path) {
+ internal virtual void RegisterFont(String path) {
RegisterFont(path, null);
}
/// Register a font file and use an alias for the font contained in it.
/// the path to a font file
/// the alias you want to use for the font
- public virtual void RegisterFont(String path, String alias) {
+ internal virtual void RegisterFont(String path, String alias) {
try {
if (path.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || path.ToLower(System.Globalization.CultureInfo.InvariantCulture
).EndsWith(".otf") || path.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,")
@@ -309,18 +309,21 @@ public virtual void RegisterFont(String path, String alias) {
}
else {
if (path.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttc")) {
- if (alias != null) {
- LOGGER.Error("You can't define an alias for a true type collection.");
- }
- TrueTypeCollection ttc = new TrueTypeCollection(path, PdfEncodings.WINANSI);
+ TrueTypeCollection ttc = new TrueTypeCollection(path);
for (int i = 0; i < ttc.GetTTCSize(); i++) {
- RegisterFont(path + "," + i);
+ String fullPath = path + "," + i;
+ if (alias != null) {
+ RegisterFont(fullPath, alias + "," + i);
+ }
+ else {
+ RegisterFont(fullPath);
+ }
}
}
else {
if (path.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm") || path.ToLower(System.Globalization.CultureInfo.InvariantCulture
).EndsWith(".pfm")) {
- FontProgram fontProgram = FontProgramFactory.CreateFont(path, false);
+ FontProgram fontProgram = FontProgramFactory.CreateFont(path);
String fullName = fontProgram.GetFontNames().GetFullName()[0][3].ToLower(System.Globalization.CultureInfo.InvariantCulture
);
String familyName = fontProgram.GetFontNames().GetFamilyName()[0][3].ToLower(System.Globalization.CultureInfo.InvariantCulture
@@ -343,7 +346,7 @@ public virtual void RegisterFont(String path, String alias) {
// remove regular and correct last symbol
// do this job to give higher priority to regular fonts in comparison with light, narrow, etc
// Don't use this method for not regular fonts!
- protected internal virtual bool SaveCopyOfRegularFont(String regularFontName, String path) {
+ internal virtual bool SaveCopyOfRegularFont(String regularFontName, String path) {
//remove "regular" at the end of the font name
String alias = regularFontName.JSubstring(0, regularFontName.Length - 7).Trim();
if (!fontNames.ContainsKey(alias)) {
@@ -356,7 +359,7 @@ protected internal virtual bool SaveCopyOfRegularFont(String regularFontName, St
/// Register all the fonts in a directory.
/// the directory
/// the number of fonts registered
- public virtual int RegisterFontDirectory(String dir) {
+ internal virtual int RegisterFontDirectory(String dir) {
return RegisterFontDirectory(dir, false);
}
@@ -364,7 +367,7 @@ public virtual int RegisterFontDirectory(String dir) {
/// the directory
/// recursively scan subdirectories if true
/// the number of fonts registered
- public virtual int RegisterFontDirectory(String dir, bool scanSubdirectories) {
+ internal virtual int RegisterFontDirectory(String dir, bool scanSubdirectories) {
LOGGER.Debug(String.Format("Registering directory {0}, looking for fonts", dir));
int count = 0;
try {
@@ -408,7 +411,7 @@ public virtual int RegisterFontDirectory(String dir, bool scanSubdirectories) {
/// Linux and Solaris.
///
/// the number of fonts registered
- public virtual int RegisterSystemFontDirectories() {
+ internal virtual int RegisterSystemFontDirectories() {
int count = 0;
String[] withSubDirs = new String[] { FileUtil.GetFontsDir(), "/usr/share/X11/fonts", "/usr/X/lib/X11/fonts"
, "/usr/openwin/lib/X11/fonts", "/usr/share/fonts", "/usr/X11R6/lib/X11/fonts" };
@@ -424,20 +427,20 @@ public virtual int RegisterSystemFontDirectories() {
/// Gets a set of registered font names.
/// a set of registered fonts
- public virtual ICollection GetRegisteredFonts() {
+ internal virtual ICollection GetRegisteredFonts() {
return fontNames.Keys;
}
/// Gets a set of registered font names.
/// a set of registered font families
- public virtual ICollection GetRegisteredFontFamilies() {
+ internal virtual ICollection GetRegisteredFontFamilies() {
return fontFamilies.Keys;
}
/// Checks if a certain font is registered.
/// the name of the font that has to be checked.
/// true if the font is found
- public virtual bool IsRegisteredFont(String fontname) {
+ internal virtual bool IsRegisteredFont(String fontname) {
return fontNames.ContainsKey(fontname.ToLower(System.Globalization.CultureInfo.InvariantCulture));
}
}
diff --git a/itext/itext.io/itext/io/font/PdfEncodings.cs b/itext/itext.io/itext/io/font/PdfEncodings.cs
index 2b1ee818eb..8b66fe8486 100644
--- a/itext/itext.io/itext/io/font/PdfEncodings.cs
+++ b/itext/itext.io/itext/io/font/PdfEncodings.cs
@@ -270,7 +270,7 @@ public static byte[] ConvertToBytes(String text, String encoding) {
return EncodingUtil.ConvertToBytes(text.ToCharArray(), encoding);
}
catch (System.IO.IOException e) {
- throw new iText.IO.IOException(iText.IO.IOException.PdfEncodings, e);
+ throw new iText.IO.IOException(iText.IO.IOException.CharacterCodeException, e);
}
}
@@ -325,7 +325,7 @@ public static byte[] ConvertToBytes(char ch, String encoding) {
return EncodingUtil.ConvertToBytes(new char[] { ch }, encoding);
}
catch (System.IO.IOException e) {
- throw new iText.IO.IOException(iText.IO.IOException.PdfEncodings, e);
+ throw new iText.IO.IOException(iText.IO.IOException.CharacterCodeException, e);
}
}
@@ -383,7 +383,7 @@ public static String ConvertToString(byte[] bytes, String encoding) {
return EncodingUtil.ConvertToString(bytes, encoding);
}
catch (ArgumentException e) {
- throw new iText.IO.IOException(iText.IO.IOException.PdfEncodings, e);
+ throw new iText.IO.IOException(iText.IO.IOException.UnsupportedEncodingException, e);
}
}
diff --git a/itext/itext.io/itext/io/font/TrueTypeCollection.cs b/itext/itext.io/itext/io/font/TrueTypeCollection.cs
index 54c4781138..38745eec34 100644
--- a/itext/itext.io/itext/io/font/TrueTypeCollection.cs
+++ b/itext/itext.io/itext/io/font/TrueTypeCollection.cs
@@ -50,32 +50,52 @@ namespace iText.IO.Font {
public class TrueTypeCollection {
protected internal RandomAccessFileOrArray raf;
- internal String encoding;
+ private int TTCSize = 0;
- internal int TTCSize = 0;
+ private String ttcPath;
- internal String ttcPath;
+ private byte[] ttc;
- internal byte[] ttc;
-
- internal bool cached = false;
+ private bool cached = true;
///
- public TrueTypeCollection(byte[] ttc, String encoding) {
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use TrueTypeCollection(byte[]) instead")]
+ public TrueTypeCollection(byte[] ttc, String encoding)
+ : this(ttc) {
+ }
+
+ ///
+ /// Creates a new
+ ///
+ /// instance by its bytes.
+ ///
+ /// the byte contents of the collection
+ /// in case the input in mal-formatted
+ public TrueTypeCollection(byte[] ttc) {
raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource(ttc));
this.ttc = ttc;
- this.encoding = encoding;
InitFontSize();
}
///
- public TrueTypeCollection(String ttcPath, String encoding) {
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use TrueTypeCollection(System.String) instead")]
+ public TrueTypeCollection(String ttcPath, String encoding)
+ : this(ttcPath) {
+ }
+
+ ///
+ /// Creates a new
+ ///
+ /// instance by its file path.
+ ///
+ /// the path of the collection
+ /// in case the input in mal-formatted
+ public TrueTypeCollection(String ttcPath) {
if (!FileUtil.FileExists(ttcPath)) {
throw new iText.IO.IOException(iText.IO.IOException.FontFile1NotFound).SetMessageParams(ttcPath);
}
raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource(ttcPath));
this.ttcPath = ttcPath;
- this.encoding = encoding;
InitFontSize();
}
@@ -85,7 +105,7 @@ public TrueTypeCollection(String ttcPath, String encoding) {
///
public virtual FontProgram GetFontByTccIndex(int ttcIndex) {
if (ttcIndex > TTCSize - 1) {
- throw new iText.IO.IOException(iText.IO.IOException.TTCIndexDoesNotExistInFile);
+ throw new iText.IO.IOException(iText.IO.IOException.TtcIndexDoesNotExistInThisTtcFile);
}
if (ttcPath != null) {
return FontProgramFactory.CreateFont(ttcPath, ttcIndex, cached);
@@ -101,10 +121,22 @@ public virtual int GetTTCSize() {
return TTCSize;
}
+ ///
+ /// Indicates if fonts created by the call to
+ ///
+ /// will be cached or not.
+ ///
+ /// true if the created fonts will be cached, false otherwise
public virtual bool IsCached() {
return cached;
}
+ ///
+ /// Sets if fonts created by the call to
+ ///
+ /// will be cached or not.
+ ///
+ /// true if the created fonts will be cached, false otherwise
public virtual void SetCached(bool cached) {
this.cached = cached;
}
diff --git a/itext/itext.io/itext/io/font/TrueTypeFont.cs b/itext/itext.io/itext/io/font/TrueTypeFont.cs
index cb5a15aa92..1021bb7903 100644
--- a/itext/itext.io/itext/io/font/TrueTypeFont.cs
+++ b/itext/itext.io/itext/io/font/TrueTypeFont.cs
@@ -198,6 +198,10 @@ public virtual GlyphPositioningTableReader GetGposTable() {
return gposTable;
}
+ public virtual OpenTypeGdefTableReader GetGdefTable() {
+ return gdefTable;
+ }
+
public virtual byte[] GetSubset(ICollection glyphs, bool subset) {
try {
return fontParser.GetSubset(glyphs, subset);
@@ -216,6 +220,7 @@ protected internal virtual void ReadGdefTable() {
else {
gdefTable = new OpenTypeGdefTableReader(fontParser.raf, 0);
}
+ gdefTable.ReadTable();
}
///
diff --git a/itext/itext.io/itext/io/font/Type1Font.cs b/itext/itext.io/itext/io/font/Type1Font.cs
index 63d43c192f..e934d02e47 100644
--- a/itext/itext.io/itext/io/font/Type1Font.cs
+++ b/itext/itext.io/itext/io/font/Type1Font.cs
@@ -131,7 +131,7 @@ public override bool HasKernPairs() {
public override int GetKerning(Glyph first, Glyph second) {
if (first.HasValidUnicode() && second.HasValidUnicode()) {
- long record = ((long)first.GetUnicode() << 32) + (int)second.GetUnicode();
+ long record = ((long)first.GetUnicode() << 32) + second.GetUnicode();
if (kernPairs.ContainsKey(record)) {
return (int)kernPairs.Get(record);
}
@@ -163,7 +163,7 @@ public virtual bool SetKerning(int first, int second, int kern) {
/// Glyph name
/// Glyph instance if found, otherwise null.
public virtual Glyph GetGlyph(String name) {
- int unicode = (int)AdobeGlyphList.NameToUnicode(name);
+ int unicode = AdobeGlyphList.NameToUnicode(name);
if (unicode != -1) {
return GetGlyph((int)unicode);
}
@@ -406,7 +406,7 @@ protected internal virtual void Process() {
}
}
}
- int unicode = (int)AdobeGlyphList.NameToUnicode(N);
+ int unicode = AdobeGlyphList.NameToUnicode(N);
Glyph glyph = new Glyph(C, WX, unicode, B);
if (C >= 0) {
codeToGlyph[C] = glyph;
@@ -433,10 +433,7 @@ protected internal virtual void Process() {
// nonbreakingspace;00A0
// space;0020
if (!unicodeToGlyph.ContainsKey(0x00A0)) {
- Glyph space = null;
- if (unicodeToGlyph.ContainsKey(0x0020)) {
- space = unicodeToGlyph.Get(0x0020);
- }
+ Glyph space = unicodeToGlyph.Get(0x0020);
if (space != null) {
unicodeToGlyph[0x00A0] = new Glyph(space.GetCode(), space.GetWidth(), 0x00A0, space.GetBbox());
}
@@ -470,8 +467,8 @@ protected internal virtual void Process() {
String first = tok.NextToken();
String second = tok.NextToken();
int? width = (int)float.Parse(tok.NextToken(), System.Globalization.CultureInfo.InvariantCulture);
- int firstUni = (int)AdobeGlyphList.NameToUnicode(first);
- int secondUni = (int)AdobeGlyphList.NameToUnicode(second);
+ int firstUni = AdobeGlyphList.NameToUnicode(first);
+ int secondUni = AdobeGlyphList.NameToUnicode(second);
if (firstUni != -1 && secondUni != -1) {
long record = ((long)firstUni << 32) + secondUni;
kernPairs[record] = width;
diff --git a/itext/itext.io/itext/io/font/cmap/CMapLocationResource.cs b/itext/itext.io/itext/io/font/cmap/CMapLocationResource.cs
index be550ee089..3d67028064 100644
--- a/itext/itext.io/itext/io/font/cmap/CMapLocationResource.cs
+++ b/itext/itext.io/itext/io/font/cmap/CMapLocationResource.cs
@@ -55,7 +55,7 @@ public virtual PdfTokenizer GetLocation(String location) {
String fullName = FontConstants.CMAP_RESOURCE_PATH + location;
Stream inp = ResourceUtil.GetResourceStream(fullName);
if (inp == null) {
- throw new iText.IO.IOException(iText.IO.IOException.TheCmap1WasNotFound).SetMessageParams(fullName);
+ throw new iText.IO.IOException(iText.IO.IOException.Cmap1WasNotFound).SetMessageParams(fullName);
}
return new PdfTokenizer(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource(inp)));
}
diff --git a/itext/itext.io/itext/io/font/otf/ActualTextIterator.cs b/itext/itext.io/itext/io/font/otf/ActualTextIterator.cs
index 4578dc4ade..d894145560 100644
--- a/itext/itext.io/itext/io/font/otf/ActualTextIterator.cs
+++ b/itext/itext.io/itext/io/font/otf/ActualTextIterator.cs
@@ -151,7 +151,7 @@ private bool GlyphLinePartNeedsActualText(GlyphLine.GlyphLinePart glyphLinePart)
break;
}
// TODO zero glyph is a special case. Unicode might be special
- toUnicodeMapResult.Append(TextUtil.ConvertFromUtf32((int) currentGlyph.GetUnicode()));
+ toUnicodeMapResult.Append(TextUtil.ConvertFromUtf32(currentGlyph.GetUnicode()));
}
return needsActualText || !toUnicodeMapResult.ToString().Equals(glyphLinePart.actualText
);
diff --git a/itext/itext.io/itext/io/font/otf/Glyph.cs b/itext/itext.io/itext/io/font/otf/Glyph.cs
index 5c2ace4ed2..dcc93f5c7a 100644
--- a/itext/itext.io/itext/io/font/otf/Glyph.cs
+++ b/itext/itext.io/itext/io/font/otf/Glyph.cs
@@ -69,7 +69,7 @@ public class Glyph
internal short yAdvance = 0;
- internal byte anchorDelta = 0;
+ internal short anchorDelta = 0;
public Glyph(int code, int width, int unicode)
: this(code, width, unicode, null, false)
@@ -133,7 +133,7 @@ public Glyph(iText.IO.Font.Otf.Glyph glyph, int xPlacement, int yPlacement,
this.yPlacement = (short)yPlacement;
this.xAdvance = (short)xAdvance;
this.yAdvance = (short)yAdvance;
- this.anchorDelta = (byte)anchorDelta;
+ this.anchorDelta = (short)anchorDelta;
}
public Glyph(iText.IO.Font.Otf.Glyph glyph, int unicode)
@@ -227,12 +227,16 @@ public virtual void SetYAdvance(short yAdvance)
this.yAdvance = yAdvance;
}
- public virtual byte GetAnchorDelta()
+ public virtual short GetAnchorDelta()
{
return anchorDelta;
- }
+ }
+
+ public void SetAnchorDelta(short anchorDelta) {
+ this.anchorDelta = anchorDelta;
+ }
- public virtual bool HasOffsets()
+ public virtual bool HasOffsets()
{
return xPlacement != 0 || yPlacement != 0 || xAdvance != 0 || yAdvance != 0;
}
diff --git a/itext/itext.io/itext/io/font/otf/GlyphLine.cs b/itext/itext.io/itext/io/font/otf/GlyphLine.cs
index d6dfd8090a..11969503a9 100644
--- a/itext/itext.io/itext/io/font/otf/GlyphLine.cs
+++ b/itext/itext.io/itext/io/font/otf/GlyphLine.cs
@@ -113,7 +113,7 @@ public virtual String ToUnicodeString(int start, int end) {
}
else {
if (glyphs[i].HasValidUnicode()) {
- str.Append(TextUtil.ConvertFromUtf32((int)glyphs[i].GetUnicode()));
+ str.Append(TextUtil.ConvertFromUtf32(glyphs[i].GetUnicode()));
}
}
}
@@ -193,7 +193,7 @@ public virtual void SubstituteManyToOne(OpenTypeFontTableReader tableReader, int
}
else {
if (currentGlyph.HasValidUnicode()) {
- chars.Append(TextUtil.ConvertFromUtf32((int)currentGlyph.GetUnicode()));
+ chars.Append(TextUtil.ConvertFromUtf32(currentGlyph.GetUnicode()));
}
}
for (int j = 0; j < rightPartLen; ++j) {
@@ -204,7 +204,7 @@ public virtual void SubstituteManyToOne(OpenTypeFontTableReader tableReader, int
}
else {
if (currentGlyph.HasValidUnicode()) {
- chars.Append(TextUtil.ConvertFromUtf32((int)currentGlyph.GetUnicode()));
+ chars.Append(TextUtil.ConvertFromUtf32(currentGlyph.GetUnicode()));
}
}
RemoveGlyph(gidx.idx--);
@@ -225,11 +225,11 @@ public virtual void SubstituteOneToOne(OpenTypeFontTableReader tableReader, int
}
else {
if (newGlyph.HasValidUnicode()) {
- newGlyph.SetChars(TextUtil.ConvertFromUtf32((int)newGlyph.GetUnicode()));
+ newGlyph.SetChars(TextUtil.ConvertFromUtf32(newGlyph.GetUnicode()));
}
else {
if (oldGlyph.HasValidUnicode()) {
- newGlyph.SetChars(TextUtil.ConvertFromUtf32((int)oldGlyph.GetUnicode()));
+ newGlyph.SetChars(TextUtil.ConvertFromUtf32(oldGlyph.GetUnicode()));
}
}
}
diff --git a/itext/itext.io/itext/io/font/otf/GlyphPositioningTableReader.cs b/itext/itext.io/itext/io/font/otf/GlyphPositioningTableReader.cs
index ac93815a80..e7254c6d82 100644
--- a/itext/itext.io/itext/io/font/otf/GlyphPositioningTableReader.cs
+++ b/itext/itext.io/itext/io/font/otf/GlyphPositioningTableReader.cs
@@ -83,6 +83,10 @@ protected internal override OpenTableLookup ReadLookupTable(int lookupType, int
return new GposLookupType5(this, lookupFlag, subTableLocations);
}
+ case 6: {
+ return new GposLookupType6(this, lookupFlag, subTableLocations);
+ }
+
default: {
return null;
}
diff --git a/itext/itext.io/itext/io/font/otf/GposLookupType6.cs b/itext/itext.io/itext/io/font/otf/GposLookupType6.cs
new file mode 100644
index 0000000000..3ddfc4e7b0
--- /dev/null
+++ b/itext/itext.io/itext/io/font/otf/GposLookupType6.cs
@@ -0,0 +1,153 @@
+/*
+This file is part of the iText (R) project.
+Copyright (c) 1998-2016 iText Group NV
+Authors: Bruno Lowagie, Paulo Soares, et al.
+
+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
+ITEXT GROUP. ITEXT 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://itextpdf.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 iText.
+
+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 iText 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 iText with a closed
+source product.
+
+For more information, please contact iText Software Corp. at this
+address: sales@itextpdf.com
+*/
+using System.Collections.Generic;
+
+namespace iText.IO.Font.Otf {
+ ///
+ /// Lookup Type 6:
+ /// MarkToMark Attachment Positioning Subtable
+ ///
+ public class GposLookupType6 : OpenTableLookup {
+ private readonly IList marksbases;
+
+ ///
+ public GposLookupType6(OpenTypeFontTableReader openReader, int lookupFlag, int[] subTableLocations)
+ : base(openReader, lookupFlag, subTableLocations) {
+ marksbases = new List();
+ ReadSubTables();
+ }
+
+ public override bool TransformOne(GlyphLine line) {
+ if (line.idx >= line.end) {
+ return false;
+ }
+ if (openReader.IsSkip(line.Get(line.idx).GetCode(), lookupFlag)) {
+ line.idx++;
+ return false;
+ }
+ bool changed = false;
+ OpenTableLookup.GlyphIndexer gi = null;
+ foreach (GposLookupType6.MarkToBaseMark mb in marksbases) {
+ OtfMarkRecord omr = mb.marks.Get(line.Get(line.idx).GetCode());
+ if (omr == null) {
+ continue;
+ }
+ if (gi == null) {
+ gi = new OpenTableLookup.GlyphIndexer();
+ gi.idx = line.idx;
+ gi.line = line;
+ while (true) {
+ int prev = gi.idx;
+ // avoid attaching this mark glyph to another very distant mark glyph
+ bool foundBaseGlyph = false;
+ gi.PreviousGlyph(openReader, lookupFlag);
+ if (gi.idx != -1) {
+ for (int i = gi.idx; i < prev; i++) {
+ if (openReader.GetGlyphClass(line.Get(i).GetCode()) == OtfClass.GLYPH_BASE) {
+ foundBaseGlyph = true;
+ break;
+ }
+ }
+ }
+ if (foundBaseGlyph) {
+ gi.glyph = null;
+ break;
+ }
+ if (gi.glyph == null) {
+ break;
+ }
+ if (mb.baseMarks.ContainsKey(gi.glyph.GetCode())) {
+ break;
+ }
+ }
+ if (gi.glyph == null) {
+ break;
+ }
+ }
+ GposAnchor[] gpas = mb.baseMarks.Get(gi.glyph.GetCode());
+ if (gpas == null) {
+ continue;
+ }
+ int markClass = omr.markClass;
+ GposAnchor baseAnchor = gpas[markClass];
+ GposAnchor markAnchor = omr.anchor;
+ line.Set(line.idx, new Glyph(line.Get(line.idx), -markAnchor.XCoordinate + baseAnchor.XCoordinate, -markAnchor
+ .YCoordinate + baseAnchor.YCoordinate, 0, 0, gi.idx - line.idx));
+ changed = true;
+ break;
+ }
+ line.idx++;
+ return changed;
+ }
+
+ ///
+ protected internal override void ReadSubTable(int subTableLocation) {
+ openReader.rf.Seek(subTableLocation);
+ openReader.rf.ReadUnsignedShort();
+ //skip format, always 1
+ int markCoverageLocation = openReader.rf.ReadUnsignedShort() + subTableLocation;
+ int baseCoverageLocation = openReader.rf.ReadUnsignedShort() + subTableLocation;
+ int classCount = openReader.rf.ReadUnsignedShort();
+ int markArrayLocation = openReader.rf.ReadUnsignedShort() + subTableLocation;
+ int baseArrayLocation = openReader.rf.ReadUnsignedShort() + subTableLocation;
+ IList markCoverage = openReader.ReadCoverageFormat(markCoverageLocation);
+ IList baseCoverage = openReader.ReadCoverageFormat(baseCoverageLocation);
+ IList markRecords = OtfReadCommon.ReadMarkArray(openReader, markArrayLocation);
+ GposLookupType6.MarkToBaseMark markToBaseMark = new GposLookupType6.MarkToBaseMark();
+ for (int k = 0; k < markCoverage.Count; ++k) {
+ markToBaseMark.marks[markCoverage[k]] = markRecords[k];
+ }
+ IList baseArray = OtfReadCommon.ReadBaseArray(openReader, classCount, baseArrayLocation);
+ for (int k_1 = 0; k_1 < baseCoverage.Count; ++k_1) {
+ markToBaseMark.baseMarks[baseCoverage[k_1]] = baseArray[k_1];
+ }
+ marksbases.Add(markToBaseMark);
+ }
+
+ private class MarkToBaseMark {
+ public readonly IDictionary marks = new Dictionary();
+
+ public readonly IDictionary baseMarks = new Dictionary();
+ }
+ }
+}
diff --git a/itext/itext.io/itext/io/font/otf/GsubLookupType1.cs b/itext/itext.io/itext/io/font/otf/GsubLookupType1.cs
index 395d3175bb..d678a2b432 100644
--- a/itext/itext.io/itext/io/font/otf/GsubLookupType1.cs
+++ b/itext/itext.io/itext/io/font/otf/GsubLookupType1.cs
@@ -43,17 +43,18 @@ source product.
*/
using System;
using System.Collections.Generic;
+using iText.IO.Util;
namespace iText.IO.Font.Otf {
/// LookupType 1: Single Substitution Subtable
/// psoares
public class GsubLookupType1 : OpenTableLookup {
- private IDictionary substMap;
+ private IntHashtable substMap;
///
public GsubLookupType1(OpenTypeFontTableReader openReader, int lookupFlag, int[] subTableLocations)
: base(openReader, lookupFlag, subTableLocations) {
- substMap = new Dictionary();
+ substMap = new IntHashtable();
ReadSubTables();
}
@@ -64,9 +65,9 @@ public override bool TransformOne(GlyphLine line) {
Glyph g = line.Get(line.idx);
bool changed = false;
if (!openReader.IsSkip(g.GetCode(), lookupFlag)) {
- int? substCode = substMap.Get(g.GetCode());
- if (substCode != null) {
- line.SubstituteOneToOne(openReader, (int)substCode);
+ int substCode = substMap.Get(g.GetCode());
+ if (substCode != 0) {
+ line.SubstituteOneToOne(openReader, substCode);
changed = true;
}
}
@@ -84,7 +85,7 @@ protected internal override void ReadSubTable(int subTableLocation) {
IList coverageGlyphIds = openReader.ReadCoverageFormat(subTableLocation + coverage);
foreach (int coverageGlyphId in coverageGlyphIds) {
int substituteGlyphId = coverageGlyphId + deltaGlyphID;
- substMap[coverageGlyphId] = substituteGlyphId;
+ substMap.Put(coverageGlyphId, substituteGlyphId);
}
}
else {
@@ -97,7 +98,7 @@ protected internal override void ReadSubTable(int subTableLocation) {
}
IList coverageGlyphIds = openReader.ReadCoverageFormat(subTableLocation + coverage);
for (int k_1 = 0; k_1 < glyphCount; ++k_1) {
- substMap[coverageGlyphIds[k_1]] = substitute[k_1];
+ substMap.Put(coverageGlyphIds[k_1], substitute[k_1]);
}
}
else {
diff --git a/itext/itext.io/itext/io/font/otf/OpenTypeFontTableReader.cs b/itext/itext.io/itext/io/font/otf/OpenTypeFontTableReader.cs
index f094dd92de..c2ed7fe844 100644
--- a/itext/itext.io/itext/io/font/otf/OpenTypeFontTableReader.cs
+++ b/itext/itext.io/itext/io/font/otf/OpenTypeFontTableReader.cs
@@ -159,6 +159,10 @@ public virtual bool IsSkip(int glyph, int flag) {
return gdef.IsSkip(glyph, flag);
}
+ public virtual int GetGlyphClass(int glyphCode) {
+ return gdef.GetGlyphClassTable().GetOtfClass(glyphCode);
+ }
+
public virtual int GetUnitsPerEm() {
return unitsPerEm;
}
diff --git a/itext/itext.io/itext/io/font/otf/OpenTypeGdefTableReader.cs b/itext/itext.io/itext/io/font/otf/OpenTypeGdefTableReader.cs
index 6d96b02e7f..79e5e76cbb 100644
--- a/itext/itext.io/itext/io/font/otf/OpenTypeGdefTableReader.cs
+++ b/itext/itext.io/itext/io/font/otf/OpenTypeGdefTableReader.cs
@@ -45,12 +45,6 @@ source product.
namespace iText.IO.Font.Otf {
public class OpenTypeGdefTableReader {
- private readonly int GLYPH_SKIP_BASE = 1;
-
- private readonly int GLYPH_SKIP_MARK = 2;
-
- private readonly int GLYPH_SKIP_LIGATURE = 3;
-
private readonly int FLAG_IGNORE_BASE = 2;
private readonly int FLAG_IGNORE_LIGATURE = 4;
@@ -94,20 +88,24 @@ public virtual void ReadTable() {
public virtual bool IsSkip(int glyph, int flag) {
if (glyphClass != null && (flag & (FLAG_IGNORE_BASE | FLAG_IGNORE_LIGATURE | FLAG_IGNORE_MARK)) != 0) {
int cla = glyphClass.GetOtfClass(glyph);
- if (cla == GLYPH_SKIP_BASE && (flag & FLAG_IGNORE_BASE) != 0) {
+ if (cla == OtfClass.GLYPH_BASE && (flag & FLAG_IGNORE_BASE) != 0) {
return true;
}
- if (cla == GLYPH_SKIP_MARK && (flag & FLAG_IGNORE_MARK) != 0) {
+ if (cla == OtfClass.GLYPH_MARK && (flag & FLAG_IGNORE_MARK) != 0) {
return true;
}
- if (cla == GLYPH_SKIP_LIGATURE && (flag & FLAG_IGNORE_LIGATURE) != 0) {
+ if (cla == OtfClass.GLYPH_LIGATURE && (flag & FLAG_IGNORE_LIGATURE) != 0) {
return true;
}
}
- if (markAttachmentClass != null && (flag >> 8) > 0) {
+ if (markAttachmentClass != null && markAttachmentClass.GetOtfClass(glyph) > 0 && (flag >> 8) > 0) {
return markAttachmentClass.GetOtfClass(glyph) != (flag >> 8);
}
return false;
}
+
+ public virtual OtfClass GetGlyphClassTable() {
+ return glyphClass;
+ }
}
}
diff --git a/itext/itext.io/itext/io/font/otf/OtfClass.cs b/itext/itext.io/itext/io/font/otf/OtfClass.cs
index a45d207302..e1029067fe 100644
--- a/itext/itext.io/itext/io/font/otf/OtfClass.cs
+++ b/itext/itext.io/itext/io/font/otf/OtfClass.cs
@@ -46,6 +46,12 @@ source product.
namespace iText.IO.Font.Otf {
public class OtfClass {
+ public const int GLYPH_BASE = 1;
+
+ public const int GLYPH_LIGATURE = 2;
+
+ public const int GLYPH_MARK = 3;
+
private IntHashtable mapClass = new IntHashtable();
///
@@ -84,6 +90,10 @@ public virtual int GetOtfClass(int glyph) {
return mapClass.Get(glyph);
}
+ public virtual bool IsMarkOtfClass(int glyph) {
+ return HasClass(glyph) && GetOtfClass(glyph) == GLYPH_MARK;
+ }
+
public virtual bool HasClass(int glyph) {
return mapClass.ContainsKey(glyph);
}
diff --git a/itext/itext.io/itext/io/image/BmpImageHelper.cs b/itext/itext.io/itext/io/image/BmpImageHelper.cs
index dd6b6886f4..2ae4508afc 100644
--- a/itext/itext.io/itext/io/image/BmpImageHelper.cs
+++ b/itext/itext.io/itext/io/image/BmpImageHelper.cs
@@ -178,7 +178,7 @@ private static void Process(BmpImageHelper.BmpParameters bmp, Stream stream) {
if (!bmp.image.IsNoHeader()) {
// Start File Header
if (!(ReadUnsignedByte(bmp.inputStream) == 'B' && ReadUnsignedByte(bmp.inputStream) == 'M')) {
- throw new iText.IO.IOException(iText.IO.IOException.InvalidMagicValueForBmpFile);
+ throw new iText.IO.IOException(iText.IO.IOException.InvalidMagicValueForBmpFileMustBeBM);
}
// Read file size
bmp.bitmapFileSize = ReadDWord(bmp.inputStream);
diff --git a/itext/itext.io/itext/io/image/ImageData.cs b/itext/itext.io/itext/io/image/ImageData.cs
index e63d2ff419..17ed2f3584 100644
--- a/itext/itext.io/itext/io/image/ImageData.cs
+++ b/itext/itext.io/itext/io/image/ImageData.cs
@@ -222,7 +222,7 @@ public virtual void SetImageMask(iText.IO.Image.ImageData imageMask) {
throw new iText.IO.IOException(iText.IO.IOException.ImageMaskCannotContainAnotherImageMask);
}
if (!imageMask.mask) {
- throw new iText.IO.IOException(iText.IO.IOException.ImageMaskIsNotAMaskDidYouDoMakeMask);
+ throw new iText.IO.IOException(iText.IO.IOException.ImageIsNotMaskYouMustCallImageDataMakeMask);
}
this.imageMask = imageMask;
}
@@ -233,7 +233,7 @@ public virtual bool IsSoftMask() {
public virtual void MakeMask() {
if (!CanBeMask()) {
- throw new iText.IO.IOException(iText.IO.IOException.ImageCanNotBeAnImageMask);
+ throw new iText.IO.IOException(iText.IO.IOException.ThisImageCanNotBeAnImageMask);
}
mask = true;
}
diff --git a/itext/itext.io/itext/io/image/Jpeg2000ImageHelper.cs b/itext/itext.io/itext/io/image/Jpeg2000ImageHelper.cs
index f6e8a07abd..107dd21a6f 100644
--- a/itext/itext.io/itext/io/image/Jpeg2000ImageHelper.cs
+++ b/itext/itext.io/itext/io/image/Jpeg2000ImageHelper.cs
@@ -55,17 +55,17 @@ private class Jpeg2000Box {
}
private class ZeroBoxSizeException : System.IO.IOException {
- public ZeroBoxSizeException(String s)
+ internal ZeroBoxSizeException(String s)
: base(s) {
}
}
+ private const int JPIP_JPIP = 0x6a706970;
+
private const int JP2_JP = 0x6a502020;
private const int JP2_IHDR = 0x69686472;
- private const int JPIP_JPIP = 0x6a706970;
-
private const int JP2_FTYP = 0x66747970;
private const int JP2_JP2H = 0x6a703268;
diff --git a/itext/itext.io/itext/io/image/JpegImageHelper.cs b/itext/itext.io/itext/io/image/JpegImageHelper.cs
index 8fed120843..0abc781a97 100644
--- a/itext/itext.io/itext/io/image/JpegImageHelper.cs
+++ b/itext/itext.io/itext/io/image/JpegImageHelper.cs
@@ -149,7 +149,7 @@ private static void ProcessParameters(Stream jpegStream, String errorID, ImageDa
while (true) {
int v = jpegStream.Read();
if (v < 0) {
- throw new iText.IO.IOException(iText.IO.IOException.PrematureEofWhileReadingJpg);
+ throw new iText.IO.IOException(iText.IO.IOException.PrematureEofWhileReadingJpeg);
}
if (v == 0xFF) {
int marker = jpegStream.Read();
diff --git a/itext/itext.io/itext/io/image/PngImageHelper.cs b/itext/itext.io/itext/io/image/PngImageHelper.cs
index 3969346cbf..b7c3e4e2e3 100644
--- a/itext/itext.io/itext/io/image/PngImageHelper.cs
+++ b/itext/itext.io/itext/io/image/PngImageHelper.cs
@@ -745,7 +745,7 @@ private static void DecodePass(int xOffset, int yOffset, int xStep, int yStep, i
default: {
// Error -- uknown filter type
- throw new iText.IO.IOException(iText.IO.IOException.PngFilterUnknown);
+ throw new iText.IO.IOException(iText.IO.IOException.UnknownPngFilter);
}
}
ProcessPixels(curr, xOffset, xStep, dstY, passWidth, png);
diff --git a/itext/itext.io/itext/io/image/TiffImageHelper.cs b/itext/itext.io/itext/io/image/TiffImageHelper.cs
index 8f1d50f8de..eebd2346ac 100644
--- a/itext/itext.io/itext/io/image/TiffImageHelper.cs
+++ b/itext/itext.io/itext/io/image/TiffImageHelper.cs
@@ -472,7 +472,7 @@ private static void ProcessTiffImageColor(TIFFDirectory dir, RandomAccessFileOrA
// Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
// is often missing
if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))) {
- throw new iText.IO.IOException(iText.IO.IOException.MissingTagSForOjpegCompression);
+ throw new iText.IO.IOException(iText.IO.IOException.MissingTagsForOjpegCompression);
}
int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
int jpegLength = (int)s.Length() - jpegOffset;
diff --git a/itext/itext.io/itext/io/source/ByteUtils.cs b/itext/itext.io/itext/io/source/ByteUtils.cs
index d274f2a9d2..10a702111e 100644
--- a/itext/itext.io/itext/io/source/ByteUtils.cs
+++ b/itext/itext.io/itext/io/source/ByteUtils.cs
@@ -131,7 +131,17 @@ internal static byte[] GetIsoBytes(double d, ByteBuffer buffer) {
internal static byte[] GetIsoBytes(double d, ByteBuffer buffer, bool highPrecision) {
if (highPrecision) {
- byte[] result = DecimalFormatUtil.FormatNumber(d, "0.######").GetBytes();
+ if (Math.Abs(d) < 0.000001) {
+ if (buffer != null) {
+ buffer.Prepend(zero);
+ return null;
+ }
+ else {
+ return zero;
+ }
+ }
+ byte[] result = DecimalFormatUtil.FormatNumber(d, "0.######").GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1
+ );
if (buffer != null) {
buffer.Prepend(result);
return null;
diff --git a/itext/itext.io/itext/io/source/GroupedRandomAccessSource.cs b/itext/itext.io/itext/io/source/GroupedRandomAccessSource.cs
index b43663392b..e5f3a414ab 100644
--- a/itext/itext.io/itext/io/source/GroupedRandomAccessSource.cs
+++ b/itext/itext.io/itext/io/source/GroupedRandomAccessSource.cs
@@ -41,6 +41,10 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
+using System;
+using iText.IO;
+using iText.IO.Log;
+
namespace iText.IO.Source {
///
/// A RandomAccessSource that is based on a set of underlying sources,
@@ -196,12 +200,32 @@ public virtual long Length() {
///
///
- /// Closes all of the underlying sources
+ ///
+ /// Closes all of the underlying sources.
///
///
public virtual void Close() {
+ System.IO.IOException firstThrownIOExc = null;
foreach (GroupedRandomAccessSource.SourceEntry entry in sources) {
- entry.source.Close();
+ try {
+ entry.source.Close();
+ }
+ catch (System.IO.IOException ex) {
+ if (firstThrownIOExc == null) {
+ firstThrownIOExc = ex;
+ }
+ else {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.IO.Source.GroupedRandomAccessSource));
+ logger.Error(LogMessageConstant.ONE_OF_GROUPED_SOURCES_CLOSING_FAILED, ex);
+ }
+ }
+ catch (Exception ex) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.IO.Source.GroupedRandomAccessSource));
+ logger.Error(LogMessageConstant.ONE_OF_GROUPED_SOURCES_CLOSING_FAILED, ex);
+ }
+ }
+ if (firstThrownIOExc != null) {
+ throw firstThrownIOExc;
}
}
diff --git a/itext/itext.io/itext/io/source/PdfTokenizer.cs b/itext/itext.io/itext/io/source/PdfTokenizer.cs
index bd355bee7d..cdbfb6881d 100644
--- a/itext/itext.io/itext/io/source/PdfTokenizer.cs
+++ b/itext/itext.io/itext/io/source/PdfTokenizer.cs
@@ -340,6 +340,7 @@ public virtual void NextValidToken() {
if (level == 1) {
// if the level 1 check returns EOF, then we are still looking at a number - set the type back to Number
type = PdfTokenizer.TokenType.Number;
+ outBuf.Reset().Append(n1);
}
}
diff --git a/itext/itext.io/itext/io/source/RAFRandomAccessSource.cs b/itext/itext.io/itext/io/source/RAFRandomAccessSource.cs
index a1881ac527..c24352910b 100644
--- a/itext/itext.io/itext/io/source/RAFRandomAccessSource.cs
+++ b/itext/itext.io/itext/io/source/RAFRandomAccessSource.cs
@@ -73,7 +73,7 @@ public RAFRandomAccessSource(FileStream raf) {
///
public virtual int Get(long position) {
// TODO: test to make sure we are handling the length properly (i.e. is raf.length() the last byte in the file, or one past the last byte?)
- if (position > raf.Length) {
+ if (position > length) {
return -1;
}
// Not thread safe!
diff --git a/itext/itext.io/itext/io/util/EncodingUtil.cs b/itext/itext.io/itext/io/util/EncodingUtil.cs
index 755131a33f..b7d60fcecf 100644
--- a/itext/itext.io/itext/io/util/EncodingUtil.cs
+++ b/itext/itext.io/itext/io/util/EncodingUtil.cs
@@ -51,6 +51,9 @@ namespace iText.IO.Util {
/// Be aware that it's API and functionality may be changed in future.
///
public static class EncodingUtil {
+
+ public static Encoding ISO_8859_1 = Encoding.GetEncoding("ISO-8859-1");
+
///
public static byte[] ConvertToBytes(char[] chars, String encoding) {
Encoding encw = IanaEncodings.GetEncodingEncoding(encoding);
diff --git a/itext/itext.io/itext/io/util/FileUtil.cs b/itext/itext.io/itext/io/util/FileUtil.cs
index 1760e79d35..3ae44475ca 100644
--- a/itext/itext.io/itext/io/util/FileUtil.cs
+++ b/itext/itext.io/itext/io/util/FileUtil.cs
@@ -43,7 +43,9 @@ source product.
*/
using System;
+using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
using System.Threading;
@@ -88,18 +90,40 @@ public static String[] ListFilesInDirectory(String path, bool recursive) {
return null;
}
+ public static FileInfo[] ListFilesInDirectoryByFilter(String path, IFileFilter filter) {
+ return ListFilesInDirectoryByFilter(path, false, filter);
+ }
+
+ public static FileInfo[] ListFilesInDirectoryByFilter(String path, bool recursive, IFileFilter filter) {
+ if (!String.IsNullOrEmpty(path)) {
+ DirectoryInfo dir = new DirectoryInfo(path);
+ if (dir.Exists) {
+ FileInfo[] files = dir.GetFiles("*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
+ List list = new List();
+ foreach (FileInfo f in files) {
+ if (filter.Accept(f)) {
+ list.Add(f);
+ }
+ }
+ return list.ToArray();
+ }
+ }
+ return null;
+ }
+
+ [Obsolete]
public static String[] ListFilesInDirectoryByFilter(String path, bool recursive, FileFilter filter) {
if (!String.IsNullOrEmpty(path)) {
DirectoryInfo dir = new DirectoryInfo(path);
if (dir.Exists) {
FileInfo[] files = dir.GetFiles("*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
- String[] list = new String[files.Length];
+ var list = new LinkedList();
for (int i = 0; i < files.Length; i++) {
if (filter.Accept(files[i].Name)) {
- list[i] = files[i].FullName;
+ list.AddLast(files[i].FullName);
}
}
- return list;
+ return list.ToArray();
}
}
return null;
@@ -129,10 +153,29 @@ public static FileStream GetRandomAccessFile(FileInfo file) {
return file.Open(FileMode.Open);
}
- public class FileFilter {
+ public static Stream WrapWithBufferedOutputStream(Stream outputStream)
+ {
+ //.NET standard stream already has buffer
+ return outputStream;
+ }
+
+ public static void CreateDirectories(String outPath) {
+ Directory.CreateDirectory(outPath);
+ }
+
+ public interface IFileFilter {
+ bool Accept(FileInfo pathname);
+ }
+
+ [Obsolete]
+ public class FileFilter : IFileFilter {
public virtual bool Accept(String pathname) {
return true;
}
+
+ public bool Accept(FileInfo pathname) {
+ return Accept(pathname.Name);
+ }
}
}
}
diff --git a/itext/itext.io/itext/io/util/IntHashtable.cs b/itext/itext.io/itext/io/util/IntHashtable.cs
index fcce1d4db4..80979ae96c 100644
--- a/itext/itext.io/itext/io/util/IntHashtable.cs
+++ b/itext/itext.io/itext/io/util/IntHashtable.cs
@@ -377,6 +377,10 @@ public virtual int GetValue() {
protected internal virtual Object Clone() {
return new IntHashtable.Entry(key, value, next != null ? (IntHashtable.Entry)next.Clone() : null);
}
+
+ public override String ToString() {
+ return String.Format("{0}={1}", key, value);
+ }
}
public virtual int[] ToOrderedKeys() {
diff --git a/itext/itext.io/itext/io/util/JavaUtil.cs b/itext/itext.io/itext/io/util/JavaUtil.cs
index 89b12aeead..5f8a9e14be 100644
--- a/itext/itext.io/itext/io/util/JavaUtil.cs
+++ b/itext/itext.io/itext/io/util/JavaUtil.cs
@@ -98,22 +98,23 @@ public static String IntegerToOctalString(int i) {
return Convert.ToString(i, 8);
}
- public static bool ArraysEquals(T[] a, T[] a2) where T : IComparable {
+ public static bool ArraysEquals(T[] a, T[] a2) {
if (a == a2)
return true;
if (a == null || a2 == null)
return false;
- if (a.Length != a2.Length) return false;
+ if (a.Length != a2.Length)
+ return false;
for (int i = 0; i < a.Length; i++)
- if (a[i].CompareTo(a2[i]) != 0)
+ if (!(a[i] == null ? a2[i] == null : a[i].Equals(a2[i])))
return false;
return true;
}
- public static int ArraysHashCode(T[] a) {
+ public static int ArraysHashCode(params T[] a) {
if (a == null)
return 0;
int result = 1;
diff --git a/itext/itext.io/itext/io/util/ResourceUtil.cs b/itext/itext.io/itext/io/util/ResourceUtil.cs
index 1d36efc8e7..0bafbff83d 100644
--- a/itext/itext.io/itext/io/util/ResourceUtil.cs
+++ b/itext/itext.io/itext/io/util/ResourceUtil.cs
@@ -42,6 +42,7 @@ source product.
address: sales@itextpdf.com
*/
+using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
@@ -75,11 +76,11 @@ public static void AddToResourceSearch(object obj) {
///
/// if not found.
///
- public static Stream GetResourceStream(string key) {
+ public static Stream GetResourceStream(string key, Type definedClassType) {
Stream istr = null;
// Try to use resource loader to load the properties file.
try {
- Assembly assm = Assembly.GetExecutingAssembly();
+ Assembly assm = definedClassType != null ? Assembly.GetAssembly(definedClassType) : Assembly.GetExecutingAssembly();
istr = assm.GetManifestResourceStream(key);
} catch {
}
@@ -126,6 +127,10 @@ public static Stream GetResourceStream(string key) {
return istr;
}
+
+ public static Stream GetResourceStream(string key) {
+ return GetResourceStream(key, null);
+ }
}
}
diff --git a/itext/itext.io/itext/io/util/StringUtil.cs b/itext/itext.io/itext/io/util/StringUtil.cs
index 224fb778be..e570940fb8 100644
--- a/itext/itext.io/itext/io/util/StringUtil.cs
+++ b/itext/itext.io/itext/io/util/StringUtil.cs
@@ -43,6 +43,7 @@ source product.
*/
using System;
+using System.Text;
using System.Text.RegularExpressions;
namespace iText.IO.Util {
@@ -66,5 +67,9 @@ public static Match Match(Regex r, String s) {
public static String Group(Match match, int index) {
return match.Groups[index].Value;
}
+
+ public static String Normalize(String s, NormalizationForm form) {
+ return s.Normalize(form);
+ }
}
}
diff --git a/itext/itext.io/itext/io/util/SystemUtil.cs b/itext/itext.io/itext/io/util/SystemUtil.cs
index 727410a545..950febd51f 100644
--- a/itext/itext.io/itext/io/util/SystemUtil.cs
+++ b/itext/itext.io/itext/io/util/SystemUtil.cs
@@ -43,6 +43,8 @@ source product.
*/
using System;
+using System.Diagnostics;
+using System.Text;
namespace iText.IO.Util {
///
@@ -57,5 +59,48 @@ public static long GetSystemTimeTicks() {
public static long GetFreeMemory() {
return GC.GetTotalMemory(false);
}
+
+ ///
+ /// Gets environment variable with given name.
+ ///
+ /// the name of environment variable.
+ /// variable value or null if there is no such.
+ public static String GetEnvironmentVariable(String name) {
+ return Environment.GetEnvironmentVariable(name);
+ }
+
+ ///
+ ///
+ public static bool RunProcessAndWait(String execPath, String @params) {
+ StringTokenizer st = new StringTokenizer(@params);
+ String[] cmdArray = new String[st.CountTokens() + 1];
+ cmdArray[0] = execPath;
+ for (int i = 1; st.HasMoreTokens(); ++i) {
+ cmdArray[i] = st.NextToken();
+ }
+ Process p = new Process();
+ p.StartInfo = new ProcessStartInfo(execPath, @params);
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.RedirectStandardError = true;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.CreateNoWindow = true;
+ p.Start();
+
+ PrintProcessOutput(p);
+ p.WaitForExit();
+ return true;
+ }
+
+ ///
+ private static void PrintProcessOutput(Process p) {
+ StringBuilder bri = new StringBuilder();
+ StringBuilder bre = new StringBuilder();
+ while (!p.HasExited) {
+ bri.Append(p.StandardOutput.ReadToEnd());
+ bre.Append(p.StandardError.ReadToEnd());
+ }
+ System.Console.Out.WriteLine(bri.ToString());
+ System.Console.Out.WriteLine(bre.ToString());
+ }
}
}
\ No newline at end of file
diff --git a/itext/itext.io/itext/io/util/UnicodeScriptUtil.cs b/itext/itext.io/itext/io/util/UnicodeScriptUtil.cs
index cc23c04b92..81a4476bd9 100644
--- a/itext/itext.io/itext/io/util/UnicodeScriptUtil.cs
+++ b/itext/itext.io/itext/io/util/UnicodeScriptUtil.cs
@@ -43,10 +43,7 @@ source product.
*/
using System;
-using System.Collections.Generic;
using System.Globalization;
-using System.Linq;
-using System.Text;
namespace iText.IO.Util {
///
@@ -56,7 +53,7 @@ namespace iText.IO.Util {
public static class UnicodeScriptUtil {
public const int MAX_CODE_POINT = 0X10FFFF;
- private static readonly UnicodeScript[] scripts = {
+ private static readonly UnicodeScript[] Scripts = {
UnicodeScript.COMMON,
UnicodeScript.LATIN,
UnicodeScript.COMMON,
@@ -376,7 +373,7 @@ public static class UnicodeScriptUtil {
UnicodeScript.UNKNOWN
};
- public static readonly int[] scriptStarts = {
+ public static readonly int[] ScriptStarts = {
0x0000, // 0000..0040; COMMON
0x0041, // 0041..005A; LATIN
0x005B, // 005B..0060; COMMON
@@ -711,7 +708,7 @@ public static class UnicodeScriptUtil {
*/
public static UnicodeScript Of(int codePoint) {
- if (!isValidCodePoint(codePoint))
+ if (!IsValidCodePoint(codePoint))
throw new Exception();
char ch = Convert.ToChar(codePoint);
UnicodeCategory type = CharUnicodeInfo.GetUnicodeCategory(ch);
@@ -719,14 +716,14 @@ public static UnicodeScript Of(int codePoint) {
if (type == 0) {
return UnicodeScript.UNKNOWN;
}
- int index = Array.BinarySearch(scriptStarts, codePoint);
+ int index = Array.BinarySearch(ScriptStarts, codePoint);
if (index < 0) {
index = -index - 2;
}
- return scripts[index];
+ return Scripts[index];
}
- public static bool isValidCodePoint(int codePoint) {
+ public static bool IsValidCodePoint(int codePoint) {
// Optimized form of:
// codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT
int plane = (int) ((uint) codePoint >> 16);
diff --git a/itext/itext.io/itext/io/util/UrlUtil.cs b/itext/itext.io/itext/io/util/UrlUtil.cs
index 34214f0e7a..e21d89fa88 100644
--- a/itext/itext.io/itext/io/util/UrlUtil.cs
+++ b/itext/itext.io/itext/io/util/UrlUtil.cs
@@ -68,7 +68,7 @@ public static Uri ToURL(String filename) {
public static Stream OpenStream(Uri url) {
Stream isp;
if (url.IsFile) {
- isp = new FileStream(url.AbsolutePath, FileMode.Open, FileAccess.Read);
+ isp = new FileStream(url.LocalPath, FileMode.Open, FileAccess.Read);
} else {
WebRequest req = WebRequest.Create(url);
req.Credentials = CredentialCache.DefaultCredentials;
diff --git a/itext/itext.kernel/Properties/AssemblyInfo.cs b/itext/itext.kernel/Properties/AssemblyInfo.cs
index 7ccdaa0f27..e463959943 100644
--- a/itext/itext.kernel/Properties/AssemblyInfo.cs
+++ b/itext/itext.kernel/Properties/AssemblyInfo.cs
@@ -21,5 +21,5 @@
[assembly: Guid("be4c62cc-6495-47e1-ab00-05b1bfe331f6")]
-[assembly: AssemblyVersion("7.0.0.0")]
-[assembly: AssemblyFileVersion("7.0.0.0")]
+[assembly: AssemblyVersion("7.0.1.0")]
+[assembly: AssemblyFileVersion("7.0.1.0")]
diff --git a/itext/itext.kernel/itext/kernel/KernelExtensions.cs b/itext/itext.kernel/itext/kernel/KernelExtensions.cs
index 4486a7cfaf..423c5503c7 100644
--- a/itext/itext.kernel/itext/kernel/KernelExtensions.cs
+++ b/itext/itext.kernel/itext/kernel/KernelExtensions.cs
@@ -99,6 +99,10 @@ public static byte[] GetBytes(this String str, String encoding) {
return Encoding.GetEncoding(encoding).GetBytes(str);
}
+ public static byte[] GetBytes(this String str, Encoding encoding) {
+ return encoding.GetBytes(str);
+ }
+
public static long Seek(this FileStream fs, long offset) {
return fs.Seek(offset, SeekOrigin.Begin);
}
@@ -151,7 +155,19 @@ public static bool Matches(this String str, String regex) {
}
public static T[] ToArray(this ICollection col, T[] toArray) {
- T[] r = col.ToArray();
+ T[] r;
+ int colSize = col.Count;
+ if (colSize <= toArray.Length) {
+ col.CopyTo(toArray, 0);
+ if (colSize != toArray.Length) {
+ toArray[colSize] = default(T);
+ }
+ r = toArray;
+ } else {
+ r = new T[colSize];
+ col.CopyTo(r, 0);
+ }
+
return r;
}
@@ -233,6 +249,10 @@ public static bool Contains(this IDictionary diction
return dictionary.ContainsKey(key);
}
+ public static Stack Clone(this Stack stack) {
+ return new Stack(new Stack(stack)); // create stack twice to retain the original order
+ }
+
public static void Update(this IDigest dgst, byte[] input) {
dgst.Update(input, 0, input.Length);
}
diff --git a/itext/itext.kernel/itext/kernel/PdfException.cs b/itext/itext.kernel/itext/kernel/PdfException.cs
index 6e5e0f8c3e..88430a04b4 100644
--- a/itext/itext.kernel/itext/kernel/PdfException.cs
+++ b/itext/itext.kernel/itext/kernel/PdfException.cs
@@ -46,409 +46,545 @@ source product.
using iText.IO.Util;
namespace iText.Kernel {
+ /// Exception class for exceptions in kernel module.
public class PdfException : Exception {
- public const String _1IsAnUnknownGraphicsStateDictionary = "{0} is.an.unknown.graphics.state.dictionary";
+ public const String _1IsAnUnknownGraphicsStateDictionary = "{0} is an unknown graphics state dictionary.";
- public const String _1IsNotAValidPlaceableWindowsMetafile = "{0} is.not.a.valid.placeable.windows.metafile";
+ public const String _1IsNotAnAcceptableValueForTheField2 = "{0} is not an acceptable value for the field {1}.";
- public const String AnnotShallHaveReferenceToPage = "annot.shall.have.reference.to.page";
+ public const String _1IsNotAValidPlaceableWindowsMetafile = "{0} is not a valid placeable windows metafile.";
- public const String AppendModeRequiresADocumentWithoutErrorsEvenIfRecoveryWasPossible = "append.mode.requires.a.document.without.errors.even.if.recovery.was.possible";
+ [Obsolete]
+ public const String AnnotShallHaveReferenceToPage = "Annotation shall have reference to page.";
- public const String AuthenticatedAttributeIsMissingTheDigest = "authenticated.attribute.is.missing.the.digest";
+ public const String AnnotationShallHaveReferenceToPage = "Annotation shall have reference to page.";
- public const String AvailableSpaceIsNotEnoughForSignature = "available.space.is.not.enough.for.signature";
+ public const String AppendModeRequiresADocumentWithoutErrorsEvenIfRecoveryWasPossible = "Append mode requires a document without errors, even if recovery is possible.";
- public const String BadCertificateAndKey = "bad.certificate.and.key";
+ public const String AuthenticatedAttributeIsMissingTheDigest = "Authenticated attribute is missing the digest.";
- public const String BadUserPassword = "bad.user.password";
+ public const String AvailableSpaceIsNotEnoughForSignature = "Available space is not enough for signature.";
- public const String CannotAddKidToTheFlushedElement = "cannot.add.kid.to.the.flushed.element";
+ public const String BadCertificateAndKey = "Bad public key certificate and/or private key.";
- public const String CannotCloseDocument = "cannot.close.document";
+ public const String BadUserPassword = "Bad user password. Password is not provided or wrong password provided. Correct password should be passed to PdfReader constructor with properties. See ReaderProperties#setPassword() method.";
- public const String CannotCloseDocumentWithAlreadyFlushedPdfCatalog = "cannot.close.document.with.already.flushed.pdf.catalog";
+ public const String CannotAddKidToTheFlushedElement = "Cannot add kid to the flushed element.";
- public const String CannotConvertPdfArrayToRectanle = "cannot.convert.pdfarray.to.rectangle";
+ public const String CannotAddNonDictionaryExtGStateToResources1 = "Cannot add graphic state to resources. The PdfObject type is {0}, but should be PdfDictionary.";
- public const String CannotCopyFlushedObject = "cannot.copy.flushed.object";
+ public const String CannotAddNonDictionaryPatternToResources1 = "Cannot add pattern to resources. The PdfObject type is {0}, but should be PdfDictionary or PdfStream.";
- public const String CannotCopyFlushedTag = "cannot.copy.flushed.tag";
+ public const String CannotAddNonDictionaryPropertiesToResources1 = "Cannot add properties to resources. The PdfObject type is {0}, but should be PdfDictionary.";
- public const String CannotCopyObjectContent = "cannot.copy.object.content";
+ public const String CannotAddNonDictionaryShadingToResources1 = "Cannot add shading to resources. The PdfObject type is {0}, but should be PdfDictionary or PdfStream.";
- public const String CannotCopyIndirectObjectFromTheDocumentThatIsBeingWritten = "cannot.copy.indirect.object.from.the.document.that.is.being.written";
+ public const String CannotAddNonStreamFormToResources1 = "Cannot add form to resources. The PdfObject type is {0}, but should be PdfStream.";
- public const String CannotCopyToDocumentOpenedInReadingMode = "cannot.copy.to.document.opened.in.reading.mode";
+ public const String CannotAddNonStreamImageToResources1 = "Cannot add image to resources. The PdfObject type is {0}, but should be PdfStream.";
- public const String CannotCreateLayoutImageByWmfImage = "Cannot create layout image by WmfImage instance. First convert the image into FormXObject and then use the corresponding layout image constructor";
+ public const String CannotCloseDocument = "Cannot close document.";
+
+ public const String CannotCloseDocumentWithAlreadyFlushedPdfCatalog = "Cannot close document with already flushed PDF Catalog.";
+
+ public const String CannotConvertPdfArrayToRectanle = "Cannot convert PdfArray to Rectangle.";
+
+ public const String CannotCopyFlushedObject = "Cannot copy flushed object.";
+
+ public const String CannotCopyFlushedTag = "Cannot copy flushed tag.";
+
+ public const String CannotCopyObjectContent = "Cannot copy object content.";
+
+ public const String CannotCopyIndirectObjectFromTheDocumentThatIsBeingWritten = "Cannot copy indirect object from the document that is being written.";
+
+ public const String CannotCopyToDocumentOpenedInReadingMode = "Cannot copy to document opened in reading mode.";
+
+ public const String CannotCreateLayoutImageByWmfImage = "Cannot create layout image by WmfImage instance. First convert the image into FormXObject and then use the corresponding layout image constructor.";
public const String CannotCreatePdfImageXObjectByWmfImage = "Cannot create PdfImageXObject instance by WmfImage. Use PdfFormXObject constructor instead.";
- public const String CannotCreatePdfStreamByInputStreamWithoutPdfDocument = "cannot.create.pdfstream.by.inputstream.without.pdfdocument";
+ public const String CannotCreatePdfStreamByInputStreamWithoutPdfDocument = "Cannot create pdfstream by InputStream without PdfDocument.";
+
+ public const String CannotGetContentBytes = "Cannot get content bytes.";
+
+ public const String CannotGetPdfStreamBytes = "Cannot get PdfStream bytes.";
+
+ public const String CannotRetrieveMediaBoxAttribute = "Invalid PDF. There is no media box attribute for page or its parents.";
+
+ public const String CannotFindImageDataOrEI = "Cannot find image data or EI.";
+
+ public const String CannotFlushDocumentRootTagBeforeDocumentIsClosed = "Cannot flush document root tag before document is closed.";
+
+ public const String CannotFlushObject = "Cannot flush object.";
+
+ public const String CannotMoveToFlushedKid = "Cannot move to flushed kid.";
+
+ public const String CannotMoveToMarkedContentReference = "Cannot move to marked content reference.";
+
+ public const String CannotMoveToParentCurrentElementIsRoot = "Cannot move to parent current element is root.";
+
+ public const String CannotOpenDocument = "Cannot open document.";
+
+ public const String CannotParseContentStream = "Cannot parse content stream.";
+
+ public const String CannotReadAStreamInOrderToAppendNewBytes = "Cannot read a stream in order to append new bytes.";
+
+ public const String CannotReadPdfObject = "Cannot read PdfObject.";
+
+ public const String CannotRemoveDocumentRootTag = "Cannot remove document root tag.";
+
+ public const String CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed = "Cannot remove marked content reference, because its page has been already flushed.";
+
+ public const String CannotRemoveTagBecauseItsParentIsFlushed = "Cannot remove tag, because its parent is flushed.";
+
+ [Obsolete]
+ public const String CannotSetDataToPdfstreamWhichWasCreatedByInputstream = "Cannot set data to PdfStream which was created by InputStream.";
+
+ public const String CannotSetDataToPdfstreamWhichWasCreatedByInputStream = "Cannot set data to PdfStream which was created by InputStream.";
+
+ public const String CannotSplitDocumentThatIsBeingWritten = "Cannot split document that is being written.";
+
+ [Obsolete]
+ public const String CannotWritePdfStream = "Cannot write pdf stream.";
+
+ public const String CannotWriteToPdfStream = "Cannot write to PdfStream.";
+
+ public const String CannotWriteObjectAfterItWasReleased = "Cannot write object after it was released. In normal situation the object must be read once again before being written.";
+
+ [Obsolete]
+ public const String CantDecodePkcs7SigneddataObject = "Cannot decode PKCS#7 SignedData object.";
+
+ public const String CannotDecodePkcs7SigneddataObject = "Cannot decode PKCS#7 SignedData object.";
+
+ [Obsolete]
+ public const String CantFindSigningCertificateWithSerial1 = "Cannot find signing certificate with serial {0}.";
+
+ public const String CannotFindSigningCertificateWithSerial1 = "Cannot find signing certificate with serial {0}.";
+
+ public const String CertificateIsNotProvidedDocumentIsEncryptedWithPublicKeyCertificate = "Certificate is not provided. Document is encrypted with public key certificate, it should be passed to PdfReader constructor with properties. See ReaderProperties#setPublicKeySecurityParams() method.";
+
+ public const String CfNotFoundEncryption = "/CF not found (encryption)";
+
+ [Obsolete]
+ public const String CodabarCharacterOneIsIllegal = "the character {0} is illegal in codabar.";
+
+ [Obsolete]
+ public const String CodabarMustHaveAtLeastAStartAndStopCharacter = "Codabar must have at least start and stop character.";
+
+ public const String CodabarMustHaveAtLeastStartAndStopCharacter = "Codabar must have at least start and stop character.";
+
+ public const String CodabarMustHaveOneAbcdAsStartStopCharacter = "Codabar must have one of 'ABCD' as start/stop character.";
+
+ [Obsolete]
+ public const String CodabarStartStopCharacterAreOnlyExtremes = "In codabar, start/stop characters are only allowed at the extremes.";
- public const String CannotGetContentBytes = "cannot.get.content.bytes";
+ public const String ColorNotFound = "Color not found.";
- public const String CannotGetPdfStreamBytes = "cannot.get.pdfstream.bytes";
+ public const String ColorSpaceNotFound = "ColorSpace not found.";
- public const String CannotFindImageDataOrEI = "cannot.find.image.data.or.EI";
+ public const String ContentStreamMustNotInvokeOperatorsThatSpecifyColorsOrOtherColorRelatedParameters = "Content stream must not invoke operators that specify colors or other color related parameters in the graphics state.";
- public const String CannotFlushDocumentRootTagBeforeDocumentIsClosed = "cannot.flush.document.root.tag.before.document.is.closed";
+ public const String DecodeParameterType1IsNotSupported = "Decode parameter type {0} is not supported.";
- public const String CannotFlushObject = "cannot.flush.object";
+ public const String DefaultcryptfilterNotFoundEncryption = "/DefaultCryptFilter not found (encryption).";
- public const String CannotMoveToFlushedKid = "cannot.move.to.flushed.kid";
+ public const String DictionaryKey1IsNotAName = "Dictionary key {0} is not a name.";
- public const String CannotMoveToMarkedContentReference = "cannot.move.to.marked.content.reference";
+ [Obsolete]
+ public const String DictionaryNotContainFontData = "Dictionary doesn't have font data.";
- public const String CannotMoveToParentCurrentElementIsRoot = "cannot.move.to.parent.current.element.is.root";
+ public const String DictionaryDoesntHave1FontData = "Dictionary doesn't have {0} font data.";
- public const String CannotOpenDocument = "cannot.open.document";
+ public const String DictionaryDoesntHaveSupportedFontData = "Dictionary doesn't have supported font data.";
- public const String CannotParseContentStream = "could.not.parse.content.stream";
+ public const String DocumentAlreadyPreClosed = "Document has been already pre closed.";
- public const String CannotReadAStreamInOrderToAppendNewBytes = "cannot.read.a.stream.in.order.to.append.new.bytes.reason {0}";
+ [Obsolete]
+ public const String DocumentClosedImpossibleExecuteAction = "Document was closed. It is impossible to execute action.";
- public const String CannotReadPdfObject = "cannot.read.pdf.object";
+ public const String DocumentClosedItIsImpossibleToExecuteAction = "Document was closed. It is impossible to execute action.";
- public const String CannotRemoveDocumentRootTag = "cannot.remove.document.root.tag";
+ public const String DocumentDoesntContainStructTreeRoot = "Document doesn't contain StructTreeRoot.";
- public const String CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed = "cannot.remove.marked.content.reference.because.its.page.was.already.flushed";
+ public const String DocumentHasNoPages = "Document has no pages.";
- public const String CannotRemoveTagBecauseItsParentIsFlushed = "cannot.remove.tag.because.its.parent.is.flushed";
+ [Obsolete]
+ public const String DocumentHasNoCatalogObject = "Document has no PDF Catalog object.";
- public const String CannotSetDataToPdfstreamWhichWasCreatedByInputstream = "cannot.set.data.to.pdfstream.which.was.created.by.inputstream";
+ public const String DocumentHasNoPdfCatalogObject = "Document has no PDF Catalog object.";
- public const String CannotSplitDocumentThatIsBeingWritten = "cannot.split.document.that.is.being.written";
+ [Obsolete]
+ public const String DocumentMustBePreclosed = "Document must be preClosed.";
- public const String CannotWritePdfStream = "cannot.write.pdf.stream";
+ public const String DocumentMustBePreClosed = "Document must be preClosed.";
- public const String CannotWriteObjectAfterItWasReleased = "Cannot write object after it was released. In normal situation the object must be read once again before being written";
+ [Obsolete]
+ public const String DocumentToCopyToCannotBeNull = "Document for copyTo cannot be null.";
- public const String CantDecodePkcs7SigneddataObject = "can.t.decode.pkcs7signeddata.object";
+ public const String DocumentForCopyToCannotBeNull = "Document for copyTo cannot be null.";
- public const String CantFindSigningCertificateWithSerial1 = "can.t.find.signing.certificate.with.serial {0}";
+ public const String ElementCannotFitAnyArea = "Element cannot fit any area.";
- public const String CfNotFoundEncryption = "cf.not.found.encryption";
+ public const String EncryptionCanOnlyBeAddedBeforeOpeningDocument = "Encryption can only be added before opening the document.";
- public const String CodabarCharacterOneIsIllegal = "the.character {0} is.illegal.in.codabar";
+ public const String EndOfContentStreamReachedBeforeEndOfImageData = "End of content stream reached before end of image data.";
- public const String CodabarMustHaveAtLeastAStartAndStopCharacter = "codabar.must.have.at.least.a.start.and.stop.character";
+ [Obsolete]
+ public const String ErrorReadingObjectStream = "Error while reading Object Stream.";
- public const String CodabarMustHaveOneAbcdAsStartStopCharacter = "codabar.must.have.one.of.abcd.as.start.stop.character";
+ public const String ErrorWhileReadingObjectStream = "Error while reading Object Stream.";
- public const String CodabarStartStopCharacterAreOnlyExtremes = "in.codabar.start.stop.characters.are.only.allowed.at.the.extremes";
+ public const String FailedToGetTsaResponseFrom1 = "Failed to get TSA response from {0}.";
- public const String ColorNotFound = "color.not.found";
+ public const String FieldFlatteningIsNotSupportedInAppendMode = "Field flattening is not supported in append mode.";
- public const String ContentStreamMustNotInvokeOperatorsThatSpecifyColorsOrOtherColorRelatedParameters = "content.stream.must.not.invoke.operators.that.specify.colors.or.other.color.related.parameters.in.the.graphics.state";
+ [Obsolete]
+ public const String FieldIsAlreadySigned = "Field has been already signed.";
- public const String DecodeParameterType1IsNotSupported = "decode.parameter.type {0} is.not.supported";
+ public const String FieldAlreadySigned = "Field has been already signed.";
- public const String DefaultcryptfilterNotFoundEncryption = "defaultcryptfilter.not.found.encryption";
+ public const String FieldNamesCannotContainADot = "Field names cannot contain a dot.";
- public const String DictionaryKey1IsNotAName = "dictionary.key {0} is.not.a.name";
+ public const String FieldTypeIsNotASignatureFieldType = "Field type is not a signature field type.";
- public const String DictionaryNotContainFontData = "dict.not.contain.font.data";
+ public const String Filter1IsNotSupported = "Filter {0} is not supported.";
- public const String DocumentAlreadyPreClosed = "document.already.pre.closed";
+ [Obsolete]
+ public const String FilePosition0CrossReferenceEntryInThisXrefSubsection = "file position {0} cross reference entry in this xref subsection.";
- public const String DocumentClosedImpossibleExecuteAction = "document.was.closed.it.is.impossible.execute.action";
+ public const String FilePosition1CrossReferenceEntryInThisXrefSubsection = "file position {0} cross reference entry in this xref subsection.";
- public const String DocumentDoesntContainStructTreeRoot = "document.doesn't.contain.structtreeroot";
+ public const String FilterCcittfaxdecodeIsOnlySupportedForImages = "Filter CCITTFaxDecode is only supported for images";
- public const String DocumentHasNoPages = "document.has.no.pages";
+ public const String FilterIsNotANameOrArray = "filter is not a name or array.";
- public const String DocumentHasNoCatalogObject = "document.has.no.catalog.object";
+ public const String FlushedPageCannotBeAddedOrInserted = "Flushed page cannot be added or inserted.";
- public const String DocumentMustBePreclosed = "document.must.be.preclosed";
+ public const String FontAndSizeMustBeSetBeforeWritingAnyText = "Font and size must be set before writing any text.";
- public const String DocumentToCopyToCannotBeNull = "document.to.copy.to.cannot.be.null";
+ public const String FontEmbeddingIssue = "Font embedding issue.";
- public const String ElementCannotFitAnyArea = "element.cannot.fit.any.area";
+ [Obsolete]
+ public const String FontSizeTooSmall = "Font size is too small.";
- public const String EncryptionCanOnlyBeAddedBeforeOpeningDocument = "encryption.can.only.be.added.before.opening.the.document";
+ public const String FontSizeIsTooSmall = "Font size is too small.";
- public const String EndOfContentStreamReachedBeforeEndOfImageData = "end.of.content.stream.reached.before.end.of.image.data";
+ public const String FormXObjectMustHaveBbox = "Form XObject must have BBox.";
- public const String ErrorReadingObjectStream = "error.reading.objstm";
+ public const String FunctionIsNotCompatibleWitColorSpace = "Function is not compatible with ColorSpace.";
- public const String FailedToGetTsaResponseFrom1 = "failed.to.get.tsa.response.from {0}";
+ public const String GivenAccessibleElementIsNotConnectedToAnyTag = "Given accessible element is not connected to any tag.";
- public const String FieldFlatteningIsNotSupportedInAppendMode = "field.flattening.is.not.supported.in.append.mode";
+ public const String IllegalCharacterInAsciihexdecode = "illegal character in ASCIIHexDecode.";
- public const String FieldIsAlreadySigned = "field.flattening.is.not.supported.in.append.mode";
+ public const String IllegalCharacterInAscii85decode = "Illegal character in ASCII85Decode.";
- public const String FieldNamesCannotContainADot = "field.names.cannot.contain.a.dot";
+ public const String IllegalCharacterInCodabarBarcode = "Illegal character in Codabar Barcode.";
- public const String FieldTypeIsNotASignatureFieldType = "the.field.type.is.not.a.signature.field.type";
+ public const String IllegalLengthValue = "Illegal length value.";
- public const String Filter1IsNotSupported = "filter {0} is.not.supported";
+ public const String IllegalPValue = "Illegal P value.";
- public const String FilePosition0CrossReferenceEntryInThisXrefSubsection = "file.position {0} cross.reference.entry.in.this.xref.subsection";
+ public const String IllegalRValue = "Illegal R value.";
- public const String FilterCcittfaxdecodeIsOnlySupportedForImages = "filter.ccittfaxdecode.is.only.supported.for.images";
+ public const String IllegalVValue = "Illegal V value.";
- public const String FilterIsNotANameOrArray = "filter.is.not.a.name.or.array";
+ public const String InAPageLabelThePageNumbersMustBeGreaterOrEqualTo1 = "In a page label the page numbers must be greater or equal to 1.";
- public const String FlushedPageCannotBeAddedOrInserted = "flushed.page.cannot.be.added.or.inserted";
+ public const String InCodabarStartStopCharactersAreOnlyAllowedAtTheExtremes = "In Codabar, start/stop characters are only allowed at the extremes.";
- public const String FontAndSizeMustBeSetBeforeWritingAnyText = "font.and.size.must.be.set.before.writing.any.text";
+ public const String InvalidHttpResponse1 = "Invalid http response {0}.";
- public const String FontEmbeddingIssue = "font.embedding.issue";
+ public const String InvalidTsa1ResponseCode2 = "Invalid TSA {0} response code {1}.";
- public const String FontSizeTooSmall = "font.size.too.small";
+ public const String IncorrectNumberOfComponents = "Incorrect number of components.";
- public const String FormXObjectMustHaveBbox = "form.xobject.must.have.bbox";
+ public const String InlineLevelOrIllustrationElementCannotContainKids = "Inline level or illustration element cannot contain kids.";
- public const String FunctionIsNotCompatibleWitColorSpace = "function.is.not.compatible.with.color.space";
+ public const String InvalidCodewordSize = "Invalid codeword size.";
- public const String GivenAccessibleElementIsNotConnectedToAnyTag = "given.accessible.element.is.not.connected.to.any.tag";
+ public const String InvalidCrossReferenceEntryInThisXrefSubsection = "Invalid cross reference entry in this xref subsection.";
- public const String IllegalCharacterInAsciihexdecode = "illegal.character.in.asciihexdecode";
+ public const String InvalidIndirectReference1 = "Invalid indirect reference {0}.";
- public const String IllegalCharacterInAscii85decode = "illegal.character.in.ascii85decode";
+ public const String InvalidMediaBoxValue = "Tne media box object has incorrect values.";
- public const String IllegalLengthValue = "illegal.length.value";
+ public const String InvalidPageStructure1 = "Invalid page structure {0}.";
- public const String IllegalPValue = "illegal.p.value";
+ public const String InvalidPageStructurePagesPagesMustBePdfDictionary = "Invalid page structure. /Pages must be PdfDictionary.";
- public const String IllegalRValue = "illegal.r.value";
+ public const String InvalidRangeArray = "Invalid range array.";
- public const String IllegalVValue = "illegal.v.value";
+ public const String InvalidOffsetForObject1 = "Invalid offset for object {0}.";
- public const String InAPageLabelThePageNumbersMustBeGreaterOrEqualTo1 = "in.a.page.label.the.page.numbers.must.be.greater.or.equal.to.1";
+ public const String InvalidXrefStream = "Invalid xref stream.";
- public const String InvalidHttpResponse1 = "invalid.http.response {0}";
+ public const String InvalidXrefTable = "Invalid xref table.";
- public const String InvalidTsa1ResponseCode2 = "invalid.tsa {0} response.code {1}";
+ public const String IoException = "I/O exception.";
- public const String IncorrectNumberOfComponents = "incorrect.number.of.components";
+ [Obsolete]
+ public const String IsNotAnAcceptableValueForTheField = "{0} is not an acceptable value for the field {1}.";
- public const String InlineLevelOrIllustrationElementCannotContainKids = "inline.level.or.illustration.element.cannot.contain.kids";
+ [Obsolete]
+ public const String IsNotWmfImage = "Not a WMF image.";
- public const String InvalidCodewordSize = "invalid.codeword.size";
+ public const String LzwDecoderException = "LZW decoder exception.";
- public const String InvalidCrossReferenceEntryInThisXrefSubsection = "invalid.cross.reference.entry.in.this.xref.subsection";
+ public const String LzwFlavourNotSupported = "LZW flavour not supported.";
- public const String InvalidIndirectReference1 = "invalid.indirect.reference {0}";
+ public const String MacroSegmentIdMustBeGtOrEqZero = "macroSegmentId must be >= 0";
- public const String InvalidPageStructure1 = "invalid.page.structure {0}";
+ public const String MacroSegmentIdMustBeGtZero = "macroSegmentId must be > 0";
- public const String InvalidPageStructurePagesPagesMustBePdfDictionary = "invalid.page.structure.pages.must.be.pdfdictionary";
+ public const String MacroSegmentIdMustBeLtMacroSegmentCount = "macroSegmentId must be < macroSemgentCount";
- public const String InvalidRangeArray = "invalid.range.array";
+ public const String MustBeATaggedDocument = "Must be a tagged document.";
- public const String InvalidOffsetForObject1 = "invalid.offset.for.object {0}";
+ public const String NumberOfEntriesInThisXrefSubsectionNotFound = "Number of entries in this xref subsection not found.";
- public const String InvalidXrefStream = "invalid.xref.stream";
+ public const String NameAlreadyExistsInTheNameTree = "Name already exists in the name tree.";
- public const String InvalidXrefTable = "invalid.xref.table";
+ public const String NoCompatibleEncryptionFound = "No compatible encryption found.";
- public const String IoException = "io.exception";
+ public const String NoCryptoDictionaryDefined = "No crypto dictionary defined.";
- public const String IsNotAnAcceptableValueForTheField = "{0}.is.not.an.acceptable.value.for.the.field.{1}";
+ public const String NoKidWithSuchRole = "No kid with such role.";
- public const String IsNotWmfImage = "is.not.wmf.image";
+ public const String NotAPlaceableWindowsMetafile = "Not a placeable windows metafile.";
- public const String LzwDecoderException = "lzw.decoder.exception";
+ public const String NotAValidPkcs7ObjectNotASequence = "Not a valid PKCS#7 object - not a sequence";
- public const String LzwFlavourNotSupported = "lzw.flavour.not.supported";
+ public const String NotAValidPkcs7ObjectNotSignedData = "Not a valid PKCS#7 object - not signed data.";
- public const String MacroSegmentIdMustBeGtOrEqZero = "macrosegmentid.must.be.gt.eq.0";
+ public const String NotAWmfImage = "Not a WMF image.";
- public const String MacroSegmentIdMustBeGtZero = "macrosegmentid.must.be.gt.0";
+ public const String NoValidEncryptionMode = "No valid encryption mode.";
- public const String MacroSegmentIdMustBeLtMacroSegmentCount = "macrosegmentid.must.be.lt.macrosegmentcount";
+ public const String NumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields = "The number of booleans in the array doesn't correspond with the number of fields.";
- public const String MustBeATaggedDocument = "must.be.a.tagged.document";
+ public const String ObjectMustBeIndirectToWorkWithThisWrapper = "Object must be indirect to work with this wrapper.";
- public const String NumberOfEntriesInThisXrefSubsectionNotFound = "number.of.entries.in.this.xref.subsection.not.found";
+ public const String ObjectNumberOfTheFirstObjectInThisXrefSubsectionNotFound = "Object number of the first object in this xref subsection not found.";
- public const String NameAlreadyExistsInTheNameTree = "name.already.exist.in.the.name.tree";
+ public const String OcspStatusIsRevoked = "OCSP status is revoked.";
- public const String NoCompatibleEncryptionFound = "no.compatible.encryption.found";
+ public const String OcspStatusIsUnknown = "OCSP status is unknown.";
- public const String NoCryptoDictionaryDefined = "no.crypto.dictionary.defined";
+ public const String OnlyBmpCanBeWrappedInWmf = "Only BMP can be wrapped in WMF.";
- public const String NoKidWithSuchRole = "no.kid.with.such.role";
+ public const String OperatorEINotFoundAfterEndOfImageData = "Operator EI not found after the end of image data.";
- public const String NotAPlaceableWindowsMetafile = "not.a.placeable.windows.metafile";
+ public const String Page1CannotBeAddedToDocument2BecauseItBelongsToDocument3 = "Page {0} cannot be added to document {1}, because it belongs to document {2}.";
- public const String NotAValidPkcs7ObjectNotASequence = "not.a.valid.pkcs.7.object.not.a.sequence";
+ public const String PageIsNotSetForThePdfTagStructure = "Page is not set for the pdf tag structure.";
- public const String NotAValidPkcs7ObjectNotSignedData = "not.a.valid.pkcs.7.object.not.signed.data";
+ [Obsolete]
+ public const String PageWasAlreadyFlushed = "The page has been already flushed.";
- public const String NoValidEncryptionMode = "no.valid.encryption.mode";
+ public const String PageAlreadyFlushed = "The page has been already flushed.";
- public const String ObjectMustBeIndirectToWorkWithThisWrapper = "object.must.be.indirect.to.work.with.this.wrapper";
+ [Obsolete]
+ public const String PageWasAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing = "The page has been already flushed. Use PdfAcroForm#addFieldAppearanceToPage() method before page flushing.";
- public const String ObjectNumberOfTheFirstObjectInThisXrefSubsectionNotFound = "object.number.of.the.first.object.in.this.xref.subsection.not.found";
+ public const String PageAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing = "The page has been already flushed. Use PdfAcroForm#addFieldAppearanceToPage() method before page flushing.";
- public const String OcspStatusIsRevoked = "ocsp.status.is.revoked";
+ public const String PdfEncodings = "PdfEncodings exception.";
- public const String OcspStatusIsUnknown = "ocsp.status.is.unknown";
+ public const String PdfEncryption = "PdfEncryption exception.";
- public const String OnlyBmpCanBeWrappedInWmf = "only.bmp.can.be.wrapped.in.wmf";
+ public const String PdfDecryption = "Exception occurred with PDF document decryption. One of the possible reasons is wrong password or wrong public key certificate and private key.";
- public const String OperatorEINotFoundAfterEndOfImageData = "operator.EI.not.found.after.end.of.image.data";
+ public const String PdfDocumentMustBeOpenedInStampingMode = "PdfDocument must be opened in stamping mode.";
- public const String Page1CannotBeAddedToDocument2BecauseItBelongsToDocument3 = "page {0} cannot.be.added.to.document {1} because.it.belongs.to.document {2}";
+ public const String PdfFormXobjectHasInvalidBbox = "PdfFormXObject has invalid BBox.";
- public const String PageIsNotSetForThePdfTagStructure = "page.is.not.set.for.the.pdf.tag.structure";
+ public const String PdfObjectStreamReachMaxSize = "PdfObjectStream reach max size.";
- public const String PageWasAlreadyFlushed = "the.page.was.already.flushed";
+ public const String PdfPageShallHaveContent = "PdfPage shall have content.";
- public const String PageWasAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing = "the.page.was.already.flushed.use.add.field.appearance.to.page.method.before.page.flushing";
+ public const String PdfPagesTreeCouldBeGeneratedOnlyOnce = "PdfPages tree could be generated only once.";
- public const String PdfEncodings = "pdf.encodings";
+ public const String PdfStartxrefIsNotFollowedByANumber = "PDF startxref is not followed by a number.";
- public const String PdfEncryption = "pdf.encryption";
+ public const String PdfStartxrefNotFound = "PDF startxref not found.";
- public const String PdfDecryption = "pdf.decryption";
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1.0.
There is a typo in the name of the constant. Use PdfIndirectObjectBelongsToOtherPdfDocument instead."
+ )]
+ public const String PdfInderectObjectBelongToOtherPdfDocument = "pdf inderect object belong to other pdf document Copy object to current pdf document.";
- public const String PdfDocumentMustBeOpenedInStampingMode = "pdf.document.must.be.opened.in.stamping.mode";
+ public const String PdfIndirectObjectBelongsToOtherPdfDocument = "Pdf indirect object belongs to other PDF document. Copy object to current pdf document.";
- public const String PdfFormXobjectHasInvalidBbox = "pdf.form.xobject.has.invalid.bbox";
+ public const String PdfVersionNotValid = "PDF version is not valid.";
- public const String PdfObjectStreamReachMaxSize = "pdf.object.stream.reach.max.size";
+ public const String PngFilterUnknown = "PNG filter unknown.";
- public const String PdfPageShallHaveContent = "pdf.page.shall.have.content";
+ public const String ResourcesCannotBeNull = "Resources cannot be null.";
- public const String PdfPagesTreeCouldBeGeneratedOnlyOnce = "pdf.pages.tree.could.be.generated.only.once";
+ public const String ResourcesDoNotContainExtgstateEntryUnableToProcessOperator1 = "Resources do not contain ExtGState entry. Unable to process operator {0}.";
- public const String PdfStartxrefIsNotFollowedByANumber = "pdf.startxref.is.not.followed.by.a.number";
+ public const String RoleIsNotMappedWithAnyStandardRole = "Role is not mapped with any standard role.";
- public const String PdfStartxrefNotFound = "pdf.startxref.not.found";
+ public const String ShadingTypeNotFound = "Shading type not found.";
- public const String PdfInderectObjectBelongToOtherPdfDocument = "pdf.inderect.object.belong.to.other.pdf.document.Copy.object.to.current.pdf.document";
+ public const String SignatureWithName1IsNotTheLastItDoesntCoverWholeDocument = "Signature with name {0} is not the last. It doesn't cover the whole document.";
- public const String PdfVersionNotValid = "pdf.version.not.valid";
+ public const String StdcfNotFoundEncryption = "/StdCF not found (encryption)";
- public const String PngFilterUnknown = "png.filter.unknown";
+ public const String StructParentIndexNotFoundInTaggedObject = "StructParent index not found in tagged object.";
- public const String ResourcesCannotBeNull = "resources.cannot.be.null";
+ public const String StructureElementShallContainParentObject = "StructureElement shall contain parent object.";
- public const String ResourcesDoNotContainExtgstateEntryUnableToProcessOperator1 = "resources.do.not.contain.extgstate.entry.unable.to.process.operator {0}";
+ public const String TagCannotBeMovedToTheAnotherDocumentsTagStructure = "Tag cannot be moved to the another document's tag structure.";
- public const String RoleIsNotMappedWithAnyStandardRole = "role.is.not.mapped.with.any.standard.role";
+ public const String TagFromTheExistingTagStructureIsFlushedCannotAddCopiedPageTags = "Tag from the existing tag structure is flushed. Cannot add copied page tags.";
- public const String SignatureWithName1IsNotTheLastItDoesntCoverWholeDocument = "signature.with.name.1.is.not.the.last.it.doesnt.cover.whole.document";
+ public const String TagStructureCopyingFailedItMightBeCorruptedInOneOfTheDocuments = "Tag structure copying failed: it might be corrupted in one of the documents.";
- public const String StdcfNotFoundEncryption = "stdcf.not.found.encryption";
+ public const String TagStructureFlushingFailedItMightBeCorrupted = "Tag structure flushing failed: it might be corrupted.";
- public const String StructParentIndexNotFoundInTaggedObject = "struct.parent.index.not.found.in.tagged.object";
+ public const String TagTreePointerIsInInvalidStateItPointsAtFlushedElementUseMoveToRoot = "TagTreePointer is in invalid state: it points at flushed element. Use TagTreePointer#moveToRoot.";
- public const String StructureElementShallContainParentObject = "structure.element.shall.contain.parent.object";
+ public const String TagTreePointerIsInInvalidStateItPointsAtRemovedElementUseMoveToRoot = "TagTreePointer is in invalid state: it points at removed element use TagTreePointer#moveToRoot.";
- public const String TagCannotBeMovedToTheAnotherDocumentsTagStructure = "tag.cannot.be.moved.to.the.another.documents.tag.structure";
+ public const String TextCannotBeNull = "Text cannot be null.";
- public const String TagFromTheExistingTagStructureIsFlushedCannotAddCopiedPageTags = "tag.from.the.existing.tag.structure.is.flushed.cannot.add.copied.page.tags";
+ public const String TextIsTooBig = "Text is too big.";
- public const String TagTreePointerIsInInvalidStateItPointsAtFlushedElementUseMoveToRoot = "tagtreepointer.is.in.invalid.state.it.points.at.flushed.element.use.movetoroot";
+ public const String TextMustBeEven = "The text length must be even.";
- public const String TagTreePointerIsInInvalidStateItPointsAtRemovedElementUseMoveToRoot = "tagtreepointer.is.in.invalid.state.it.points.at.removed.element.use.movetoroot";
+ public const String TwoBarcodeMustBeExternally = "The two barcodes must be composed externally.";
- public const String TextCannotBeNull = "text.cannot.be.null";
+ [Obsolete]
+ public const String TheNumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields = "The number of booleans in the array doesn't correspond with the number of fields.";
- public const String TextIsTooBig = "text.is.too.big";
+ public const String ThereAreIllegalCharactersForBarcode128In1 = "There are illegal characters for barcode 128 in {0}.";
- public const String TextMustBeEven = "the.text.length.must.be.even";
+ public const String ThereIsNoAssociatePdfWriterForMakingIndirects = "There is no associate PdfWriter for making indirects.";
- public const String TwoBarcodeMustBeExternally = "the.two.barcodes.must.be.composed.externally";
+ public const String ThereIsNoFieldInTheDocumentWithSuchName1 = "There is no field in the document with such name: {0}.";
- public const String TheNumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields = "the.number.of.booleans.in.the.array.doesn.t.correspond.with.the.number.of.fields";
+ public const String ThisPkcs7ObjectHasMultipleSignerinfosOnlyOneIsSupportedAtThisTime = "This PKCS#7 object has multiple SignerInfos. Only one is supported at this time.";
- public const String ThereAreIllegalCharactersForBarcode128In1 = "there.are.illegal.characters.for.barcode.128.in {0}";
+ [Obsolete]
+ public const String ThisInstanceOfPdfSignerIsAlreadyClosed = "This instance of PdfSigner has been already closed.";
- public const String ThereIsNoAssociatePdfWriterForMakingIndirects = "there.is.no.associate.pdf.writer.for.making.indirects";
+ public const String ThisInstanceOfPdfSignerAlreadyClosed = "This instance of PdfSigner has been already closed.";
- public const String ThereIsNoFieldInTheDocumentWithSuchName1 = "there.is.no.field.in.the.document.with.such.name {0}";
+ public const String Tsa1FailedToReturnTimeStampToken2 = "TSA {0} failed to return time stamp token: {1}.";
- public const String ThisPkcs7ObjectHasMultipleSignerinfosOnlyOneIsSupportedAtThisTime = "this.pkcs.7.object.has.multiple.signerinfos.only.one.is.supported.at.this.time";
+ public const String TrailerNotFound = "Trailer not found.";
- public const String ThisInstanceOfPdfSignerIsAlreadyClosed = "this.instance.of.PdfSigner.is.already.closed";
+ public const String TrailerPrevEntryPointsToItsOwnCrossReferenceSection = "Trailer prev entry points to its own cross reference section.";
- public const String Tsa1FailedToReturnTimeStampToken2 = "tsa {0} failed.to.return.time.stamp.token {1}";
+ public const String UnbalancedBeginEndMarkedContentOperators = "Unbalanced begin/end marked content operators.";
- public const String TrailerNotFound = "trailer.not.found";
+ public const String UnbalancedLayerOperators = "Unbalanced layer operators.";
- public const String TrailerPrevEntryPointsToItsOwnCrossReferenceSection = "trailer.prev.entry.points.to.its.own.cross.reference.section";
+ public const String UnbalancedSaveRestoreStateOperators = "Unbalanced save restore state operators.";
- public const String UnbalancedBeginEndMarkedContentOperators = "unbalanced.begin.end.marked.content.operators";
+ public const String UnexpectedCharacter1FoundAfterIDInInlineImage = "Unexpected character {0} found after ID in inline image.";
- public const String UnbalancedLayerOperators = "unbalanced.layer.operators";
+ public const String UnexpectedCloseBracket = "Unexpected close bracket.";
- public const String UnbalancedSaveRestoreStateOperators = "unbalanced.save.restore.state.operators";
+ public const String UnexpectedColorSpace1 = "Unexpected ColorSpace: {0}.";
- public const String UnexpectedCharacter1FoundAfterIDInInlineImage = "unexpected.character.1.found.after.ID.in.inline.image";
+ public const String UnexpectedEndOfFile = "Unexpected end of file.";
- public const String UnexpectedCloseBracket = "unexpected.close.bracket";
+ public const String UnexpectedGtGt = "unexpected >>.";
- public const String UnexpectedColorSpace1 = "unexpected.color.space {0}";
+ public const String UnexpectedShadingType = "Unexpected shading type.";
- public const String UnexpectedEndOfFile = "unexpected.end.of.file";
+ public const String UnknownEncryptionTypeREq1 = "Unknown encryption type R == {0}.";
- public const String UnexpectedGtGt = "unexpected.gt.gt";
+ public const String UnknownEncryptionTypeVEq1 = "Unknown encryption type V == {0}.";
- public const String UnexpectedShadingType = "unexpected.shading.type";
+ public const String UnknownPdfException = "Unknown PdfException.";
- public const String UnknownEncryptionTypeREq1 = "unknown.encryption.type.r.eq {0}";
+ public const String UnknownHashAlgorithm1 = "Unknown hash algorithm: {0}.";
- public const String UnknownEncryptionTypeVEq1 = "unknown.encryption.type.v.eq {0}";
+ public const String UnknownKeyAlgorithm1 = "Unknown key algorithm: {0}.";
- public const String UnknownPdfException = "unknown.pdf.exception";
+ public const String UnknownColorFormatMustBeRGBorRRGGBB = "Unknown color format: must be rgb or rrggbb.";
- public const String UnknownHashAlgorithm1 = "unknown.hash.algorithm {0}";
+ public const String UnsupportedDefaultColorSpaceName1 = "Unsupported default color space name. Was {0}, but should be DefaultCMYK, DefaultGray or DefaultRGB";
- public const String UnknownKeyAlgorithm1 = "unknown.key.algorithm {0}";
+ public const String UnsupportedXObjectType = "Unsupported XObject type.";
- public const String UnknownColorFormatMustBeRGBorRRGGBB = "unknown.color.format.must.be.rgb.or.rrggbb";
+ public const String VerificationAlreadyOutput = "Verification already output.";
- public const String VerificationAlreadyOutput = "verification.already.output";
+ public const String WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject = "When adding object reference to the tag tree, it must be connected to not flushed object.";
- public const String WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject = "when.adding.object.reference.to.the.tag.tree.it.must.be.connected.to.not.flushed.object";
+ public const String WhitePointIsIncorrectlySpecified = "White point is incorrectly specified.";
- public const String WhitePointIsIncorrectlySpecified = "white.point.is.incorrectly.specified";
+ public const String WmfImageException = "WMF image exception.";
- public const String WmfImageException = "wmf.image.exception";
+ public const String WrongFormFieldAddAnnotationToTheField = "Wrong form field. Add annotation to the field.";
- public const String WrongFormFieldAddAnnotationToTheField = "wrong.form.field.add.annotation.to.the.field";
+ public const String WrongMediaBoxSize1 = "Wrong media box size: {0}.";
- public const String XrefSubsectionNotFound = "xref.subsection.not.found";
+ public const String XrefSubsectionNotFound = "xref subsection not found.";
- public const String YouCannotFlushPdfCatalogManually = "you.cannot.flush.pdf.catalog.manually";
+ [Obsolete]
+ public const String YouCannotFlushPdfCatalogManually = "You cannot flush PdfCatalog manually.";
- public const String YouHaveToDefineABooleanArrayForThisCollectionSortDictionary = "you.have.to.define.a.boolean.array.for.this.collection.sort.dictionary";
+ public const String YouHaveToDefineABooleanArrayForThisCollectionSortDictionary = "You have to define a boolean array for this collection sort dictionary.";
- public const String YouMustSetAValueBeforeAddingAPrefix = "you.must.set.a.value.before.adding.a.prefix";
+ public const String YouMustSetAValueBeforeAddingAPrefix = "You must set a value before adding a prefix.";
- public const String YouNeedASingleBooleanForThisCollectionSortDictionary = "you.need.a.single.boolean.for.this.collection.sort.dictionary";
+ public const String YouNeedASingleBooleanForThisCollectionSortDictionary = "You need a single boolean for this collection sort dictionary.";
+ /// Object for more details
protected internal Object @object;
private IList messageParams;
+ /// Creates a new instance of PdfException.
+ /// the detail message.
public PdfException(String message)
: base(message) {
}
+ /// Creates a new instance of PdfException.
+ ///
+ /// the cause (which is saved for later retrieval by
+ ///
+ /// method).
+ ///
public PdfException(Exception cause)
: this(UnknownPdfException, cause) {
}
- public PdfException(String message, Object @object)
+ /// Creates a new instance of PdfException.
+ /// the detail message.
+ /// an object for more details.
+ public PdfException(String message, Object obj)
: this(message) {
- this.@object = @object;
+ this.@object = obj;
}
+ /// Creates a new instance of PdfException.
+ /// the detail message.
+ ///
+ /// the cause (which is saved for later retrieval by
+ ///
+ /// method).
+ ///
public PdfException(String message, Exception cause)
: base(message, cause) {
}
- public PdfException(String message, Exception cause, Object @object)
+ /// Creates a new instance of PdfException.
+ /// the detail message.
+ ///
+ /// the cause (which is saved for later retrieval by
+ ///
+ /// method).
+ ///
+ /// an object for more details.
+ public PdfException(String message, Exception cause, Object obj)
: this(message, cause) {
- this.@object = @object;
+ this.@object = obj;
}
public override String Message {
@@ -462,12 +598,16 @@ public override String Message {
}
}
+ /// Sets additional params for Exception message.
+ /// additional params.
+ /// object itself.
public virtual iText.Kernel.PdfException SetMessageParams(params Object[] messageParams) {
this.messageParams = new List();
this.messageParams.AddAll(messageParams);
return this;
}
+ /// Gets additional params for Exception message.
protected internal virtual Object[] GetMessageParams() {
Object[] parameters = new Object[messageParams.Count];
for (int i = 0; i < messageParams.Count; i++) {
diff --git a/itext/itext.kernel/itext/kernel/Version.cs b/itext/itext.kernel/itext/kernel/Version.cs
index 11a7c11625..4d2cdc1a70 100644
--- a/itext/itext.kernel/itext/kernel/Version.cs
+++ b/itext/itext.kernel/itext/kernel/Version.cs
@@ -72,7 +72,7 @@ public sealed class Version {
/// This String contains the version number of this iText release.
/// For debugging purposes, we request you NOT to change this constant.
///
- private static String release = "7.0.0";
+ private static String release = "7.0.1";
/// This String contains the iText version as shown in the producer line.
///
@@ -86,7 +86,7 @@ public sealed class Version {
/// The license key.
private String key = null;
- private static bool expired;
+ private bool expired;
/// Gets an instance of the iText version that is currently used.
///
@@ -102,69 +102,58 @@ public static Version GetInstance() {
String licenseKeyClassFullName = "iText.License.LicenseKey, itext.licensekey";
String licenseeInfoMethodName = "GetLicenseeInfo";
Type klass = System.Type.GetType(licenseKeyClassFullName);
- MethodInfo m = klass.GetMethod(licenseeInfoMethodName);
- String[] info = (String[])m.Invoke(System.Activator.CreateInstance(klass), null);
- if (info[3] != null && info[3].Trim().Length > 0) {
- version.key = info[3];
- }
- else {
- version.key = "Trial version";
- if (info[5] == null) {
- version.key += "unauthorised";
+ if (klass != null) {
+ MethodInfo m = klass.GetMethod(licenseeInfoMethodName);
+ String[] info = (String[])m.Invoke(System.Activator.CreateInstance(klass), null);
+ if (info[3] != null && info[3].Trim().Length > 0) {
+ version.key = info[3];
}
else {
- version.key += info[5];
- }
- }
- if (info.Length > 6) {
- if (info[6] != null && info[6].Trim().Length > 0) {
- String versionToCheck = release.JSubstring(0, release.LastIndexOf("."));
- if (!info[6].EqualsIgnoreCase(versionToCheck)) {
- throw new ArgumentException("Your license key version doesn't match the iText version.");
- }
- }
- }
- if (info[4] != null && info[4].Trim().Length > 0) {
- version.iTextVersion = info[4];
- }
- else {
- if (info[2] != null && info[2].Trim().Length > 0) {
- version.iTextVersion += " (" + info[2];
- if (!version.key.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("trial")) {
- version.iTextVersion += "; licensed version)";
+ version.key = "Trial version ";
+ if (info[5] == null) {
+ version.key += "unauthorised";
}
else {
- version.iTextVersion += "; " + version.key + ")";
+ version.key += info[5];
}
}
+ if (info.Length > 6) {
+ if (info[6] != null && info[6].Trim().Length > 0) {
+ String versionToCheck = release.JSubstring(0, release.LastIndexOf("."));
+ if (!info[6].EqualsIgnoreCase(versionToCheck)) {
+ throw new ArgumentException("Your license key version doesn't match the iText version.");
+ }
+ }
+ }
+ if (info[4] != null && info[4].Trim().Length > 0) {
+ version.iTextVersion = info[4];
+ }
else {
- if (info[0] != null && info[0].Trim().Length > 0) {
- // fall back to contact name, if company name is unavailable
- version.iTextVersion += " (" + info[0];
- if (!version.key.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("trial")) {
+ if (info[2] != null && info[2].Trim().Length > 0) {
+ version.AddLicensedPostfix(info[2]);
+ }
+ else {
+ if (info[0] != null && info[0].Trim().Length > 0) {
+ // fall back to contact name, if company name is unavailable.
// we shouldn't have a licensed version without company name,
// but let's account for it anyway
- version.iTextVersion += "; licensed version)";
+ version.AddLicensedPostfix(info[0]);
}
else {
- version.iTextVersion += "; " + version.key + ")";
+ version.AddAGPLPostfix(null);
}
}
- else {
- throw new Exception();
- }
}
}
+ else {
+ version.AddAGPLPostfix(null);
+ }
}
catch (ArgumentException exc) {
throw;
}
catch (Exception e) {
- version.iTextVersion += AGPL;
- if (e.InnerException != null && e.InnerException.Message != null && e.InnerException.Message.Contains("expired"
- )) {
- expired = true;
- }
+ version.AddAGPLPostfix(e.InnerException);
}
}
}
@@ -180,7 +169,7 @@ public static bool IsAGPLVersion() {
/// Is the license expired?
/// true if expired
public static bool IsExpired() {
- return expired;
+ return GetInstance().expired;
}
/// Gets the product name.
@@ -222,5 +211,22 @@ public String GetVersion() {
public String GetKey() {
return key;
}
+
+ private void AddLicensedPostfix(String ownerName) {
+ iTextVersion += " (" + ownerName;
+ if (!key.ToLower(System.Globalization.CultureInfo.InvariantCulture).StartsWith("trial")) {
+ iTextVersion += "; licensed version)";
+ }
+ else {
+ iTextVersion += "; " + key + ")";
+ }
+ }
+
+ private void AddAGPLPostfix(Exception cause) {
+ iTextVersion += AGPL;
+ if (cause != null && cause.Message != null && cause.Message.Contains("expired")) {
+ expired = true;
+ }
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/colors/Color.cs b/itext/itext.kernel/itext/kernel/colors/Color.cs
index b046b6295b..47a09788d3 100644
--- a/itext/itext.kernel/itext/kernel/colors/Color.cs
+++ b/itext/itext.kernel/itext/kernel/colors/Color.cs
@@ -46,37 +46,60 @@ source product.
using iText.Kernel.Pdf.Colorspace;
namespace iText.Kernel.Colors {
+ /// Represents a color
public class Color {
+ /// Predefined black DeviceRgb color
public static readonly iText.Kernel.Colors.Color BLACK = new DeviceRgb(0, 0, 0);
+ /// Predefined blue DeviceRgb color
public static readonly iText.Kernel.Colors.Color BLUE = new DeviceRgb(0, 0, 255);
+ /// Predefined cyan DeviceRgb color
public static readonly iText.Kernel.Colors.Color CYAN = new DeviceRgb(0, 255, 255);
+ /// Predefined dark gray DeviceRgb color
public static readonly iText.Kernel.Colors.Color DARK_GRAY = new DeviceRgb(64, 64, 64);
+ /// Predefined gray DeviceRgb color
public static readonly iText.Kernel.Colors.Color GRAY = new DeviceRgb(128, 128, 128);
+ /// Predefined green DeviceRgb color
public static readonly iText.Kernel.Colors.Color GREEN = new DeviceRgb(0, 255, 0);
+ /// Predefined light gray DeviceRgb color
public static readonly iText.Kernel.Colors.Color LIGHT_GRAY = new DeviceRgb(192, 192, 192);
+ /// Predefined magenta DeviceRgb color
public static readonly iText.Kernel.Colors.Color MAGENTA = new DeviceRgb(255, 0, 255);
+ /// Predefined orange DeviceRgb color
public static readonly iText.Kernel.Colors.Color ORANGE = new DeviceRgb(255, 200, 0);
+ /// Predefined pink DeviceRgb color
public static readonly iText.Kernel.Colors.Color PINK = new DeviceRgb(255, 175, 175);
+ /// Predefined red DeviceRgb color
public static readonly iText.Kernel.Colors.Color RED = new DeviceRgb(255, 0, 0);
+ /// Predefined white DeviceRgb color
public static readonly iText.Kernel.Colors.Color WHITE = new DeviceRgb(255, 255, 255);
+ /// Predefined yellow DeviceRgb color
public static readonly iText.Kernel.Colors.Color YELLOW = new DeviceRgb(255, 255, 0);
+ /// The color space of the color
protected internal PdfColorSpace colorSpace;
+ /// The color value of the color
protected internal float[] colorValue;
+ /// Creates a Color of certain color space and color value.
+ ///
+ /// Creates a Color of certain color space and color value.
+ /// If color value is set in null, all value components will be initialised with zeroes.
+ ///
+ /// the color space to which the created Color object relates
+ /// the color value of the created Color object
protected internal Color(PdfColorSpace colorSpace, float[] colorValue) {
this.colorSpace = colorSpace;
if (colorValue == null) {
@@ -87,10 +110,23 @@ protected internal Color(PdfColorSpace colorSpace, float[] colorValue) {
}
}
+ /// Makes a Color of certain color space.
+ ///
+ /// Makes a Color of certain color space.
+ /// All color value components will be initialised with zeroes.
+ ///
+ /// the color space to which the returned Color object relates
public static iText.Kernel.Colors.Color MakeColor(PdfColorSpace colorSpace) {
return MakeColor(colorSpace, null);
}
+ /// Makes a Color of certain color space and color value.
+ ///
+ /// Makes a Color of certain color space and color value.
+ /// If color value is set in null, all value components will be initialised with zeroes.
+ ///
+ /// the color space to which the returned Color object relates
+ /// the color value of the returned Color object
public static iText.Kernel.Colors.Color MakeColor(PdfColorSpace colorSpace, float[] colorValue) {
iText.Kernel.Colors.Color c = null;
bool unknownColorSpace = false;
@@ -180,6 +216,15 @@ public static iText.Kernel.Colors.Color MakeColor(PdfColorSpace colorSpace, floa
return c;
}
+ ///
+ /// Converts
+ /// DeviceCmyk
+ /// color to
+ /// DeviceRgb
+ /// color
+ ///
+ /// the DeviceCmyk color which will be converted to DeviceRgb color
+ /// converted color
public static DeviceRgb ConvertCmykToRgb(DeviceCmyk cmykColor) {
float cyanComp = 1 - cmykColor.GetColorValue()[0];
float magentaComp = 1 - cmykColor.GetColorValue()[1];
@@ -191,6 +236,15 @@ public static DeviceRgb ConvertCmykToRgb(DeviceCmyk cmykColor) {
return new DeviceRgb(r, g, b);
}
+ ///
+ /// Converts
+ /// DeviceRgb
+ /// color to
+ /// DeviceCmyk
+ /// color
+ ///
+ /// the DeviceRgb color which will be converted to DeviceCmyk color
+ /// converted color
public static DeviceCmyk ConvertRgbToCmyk(DeviceRgb rgbColor) {
float redComp = rgbColor.GetColorValue()[0];
float greenComp = rgbColor.GetColorValue()[1];
@@ -202,18 +256,30 @@ public static DeviceCmyk ConvertRgbToCmyk(DeviceRgb rgbColor) {
return new DeviceCmyk(c, m, y, k);
}
+ /// Returns the number of color value components
+ /// the number of color value components
public virtual int GetNumberOfComponents() {
return colorValue.Length;
}
+ ///
+ /// Returns the
+ /// color space
+ /// to which the color is related.
+ ///
+ /// the color space of the color
public virtual PdfColorSpace GetColorSpace() {
return colorSpace;
}
+ /// Returns the color value of the color
+ /// the color value
public virtual float[] GetColorValue() {
return colorValue;
}
+ /// Sets the color value of the color
+ /// new color value
public virtual void SetColorValue(float[] value) {
colorValue = value;
if (colorValue.Length != value.Length) {
@@ -221,6 +287,15 @@ public virtual void SetColorValue(float[] value) {
}
}
+ /// Indicates whether the color is equal to the given color.
+ ///
+ /// Indicates whether the color is equal to the given color.
+ /// The
+ /// color space
+ /// and
+ /// color value
+ /// are considered during the comparison.
+ ///
public override bool Equals(Object o) {
if (this == o) {
return true;
@@ -233,6 +308,7 @@ public override bool Equals(Object o) {
== null) && iText.IO.Util.JavaUtil.ArraysEquals(colorValue, color.colorValue);
}
+ ///
public override int GetHashCode() {
int result = colorSpace != null ? colorSpace.GetHashCode() : 0;
result = 31 * result + (colorValue != null ? iText.IO.Util.JavaUtil.ArraysHashCode(colorValue) : 0);
diff --git a/itext/itext.kernel/itext/kernel/colors/DeviceCmyk.cs b/itext/itext.kernel/itext/kernel/colors/DeviceCmyk.cs
index 0695e46cd7..6ea47067c8 100644
--- a/itext/itext.kernel/itext/kernel/colors/DeviceCmyk.cs
+++ b/itext/itext.kernel/itext/kernel/colors/DeviceCmyk.cs
@@ -41,40 +41,89 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
+using iText.IO;
+using iText.IO.Log;
using iText.Kernel.Pdf.Colorspace;
namespace iText.Kernel.Colors {
+ /// Color space to specify colors according to CMYK color model.
public class DeviceCmyk : Color {
+ /// Predefined cyan DeviceCmyk color
public static readonly iText.Kernel.Colors.DeviceCmyk CYAN = new iText.Kernel.Colors.DeviceCmyk(100, 0, 0,
0);
+ /// Predefined magenta DeviceCmyk color
public static readonly iText.Kernel.Colors.DeviceCmyk MAGENTA = new iText.Kernel.Colors.DeviceCmyk(0, 100,
0, 0);
+ /// Predefined yellow DeviceCmyk color
public static readonly iText.Kernel.Colors.DeviceCmyk YELLOW = new iText.Kernel.Colors.DeviceCmyk(0, 0, 100
, 0);
+ /// Predefined black DeviceCmyk color
public static readonly iText.Kernel.Colors.DeviceCmyk BLACK = new iText.Kernel.Colors.DeviceCmyk(0, 0, 0,
100);
+ /// Creates DeviceCmyk color with all colorants intensities initialised as zeroes.
public DeviceCmyk()
: this(0f, 0f, 0f, 1f) {
}
+ /// Creates DeviceCmyk color by intensities of cyan, magenta, yellow and black colorants.
+ ///
+ /// Creates DeviceCmyk color by intensities of cyan, magenta, yellow and black colorants.
+ /// The intensities are considered to be in [0, 100] gap, if not,
+ /// the intensity will be considered as 100 (when colorant's value is bigger than 100)
+ /// or 0 (when colorant's value is less than 0).
+ ///
+ /// the intensity of cyan colorant
+ /// the intensity of magenta colorant
+ /// the intensity of yellow colorant
+ /// the intensity of black colorant
public DeviceCmyk(int c, int m, int y, int k)
: this(c / 100f, m / 100f, y / 100f, k / 100f) {
}
+ /// Creates DeviceCmyk color by intensities of cyan, magenta, yellow and black colorants.
+ ///
+ /// Creates DeviceCmyk color by intensities of cyan, magenta, yellow and black colorants.
+ /// The intensities are considered to be in [0, 1] interval, if not,
+ /// the intensity will be considered as 1 (when colorant's value is bigger than 1)
+ /// or 0 (when colorant's value is less than 0).
+ ///
+ /// the intensity of cyan colorant
+ /// the intensity of magenta colorant
+ /// the intensity of yellow colorant
+ /// the intensity of black colorant
public DeviceCmyk(float c, float m, float y, float k)
- : base(new PdfDeviceCs.Cmyk(), new float[] { c, m, y, k }) {
+ : base(new PdfDeviceCs.Cmyk(), new float[] { c > 1 ? 1 : (c > 0 ? c : 0), m > 1 ? 1 : (m > 0 ? m : 0), y >
+ 1 ? 1 : (y > 0 ? y : 0), k > 1 ? 1 : (k > 0 ? k : 0) }) {
+ if (c > 1 || c < 0 || m > 1 || m < 0 || y > 1 || y < 0 || k > 1 || k < 0) {
+ ILogger LOGGER = LoggerFactory.GetLogger(typeof(iText.Kernel.Colors.DeviceCmyk));
+ LOGGER.Warn(LogMessageConstant.COLORANT_INTENSITIES_INVALID);
+ }
}
+ ///
+ /// Returns
+ /// DeviceCmyk
+ /// color which is lighter than given one
+ ///
+ /// the DeviceCmyk color to be made lighter
+ /// lighter color
public static iText.Kernel.Colors.DeviceCmyk MakeLighter(iText.Kernel.Colors.DeviceCmyk cmykColor) {
DeviceRgb rgbEquivalent = ConvertCmykToRgb(cmykColor);
DeviceRgb lighterRgb = DeviceRgb.MakeLighter((rgbEquivalent));
return ConvertRgbToCmyk(lighterRgb);
}
+ ///
+ /// Returns
+ /// DeviceCmyk
+ /// color which is darker than given one
+ ///
+ /// the DeviceCmyk color to be made darker
+ /// darker color
public static iText.Kernel.Colors.DeviceCmyk MakeDarker(iText.Kernel.Colors.DeviceCmyk cmykColor) {
DeviceRgb rgbEquivalent = ConvertCmykToRgb(cmykColor);
DeviceRgb darkerRgb = DeviceRgb.MakeDarker(rgbEquivalent);
diff --git a/itext/itext.kernel/itext/kernel/colors/DeviceGray.cs b/itext/itext.kernel/itext/kernel/colors/DeviceGray.cs
index bfc3c157ff..512f297027 100644
--- a/itext/itext.kernel/itext/kernel/colors/DeviceGray.cs
+++ b/itext/itext.kernel/itext/kernel/colors/DeviceGray.cs
@@ -42,24 +42,50 @@ source product.
address: sales@itextpdf.com
*/
using System;
+using iText.IO;
+using iText.IO.Log;
using iText.Kernel.Pdf.Colorspace;
namespace iText.Kernel.Colors {
+ /// Color space to specify shades of gray color.
public class DeviceGray : Color {
+ /// Predefined white DeviceGray color.
public static readonly iText.Kernel.Colors.DeviceGray WHITE = new iText.Kernel.Colors.DeviceGray(1f);
+ /// Predefined gray DeviceGray color.
public static readonly iText.Kernel.Colors.DeviceGray GRAY = new iText.Kernel.Colors.DeviceGray(.5f);
+ /// Predefined black DeviceGray color.
public static readonly iText.Kernel.Colors.DeviceGray BLACK = new iText.Kernel.Colors.DeviceGray();
+ /// Creates DeviceGray color by given grayscale.
+ ///
+ /// Creates DeviceGray color by given grayscale.
+ /// The grayscale is considered to be in [0, 1] interval, if not,
+ /// the grayscale will be considered as 1 (when grayscale's value is bigger than 1)
+ /// or 0 (when grayscale's value is less than 0).
+ ///
+ /// the grayscale value
public DeviceGray(float value)
- : base(new PdfDeviceCs.Gray(), new float[] { value }) {
+ : base(new PdfDeviceCs.Gray(), new float[] { value > 1 ? 1 : (value > 0 ? value : 0) }) {
+ if (value > 1 || value < 0) {
+ ILogger LOGGER = LoggerFactory.GetLogger(typeof(iText.Kernel.Colors.DeviceGray));
+ LOGGER.Warn(LogMessageConstant.COLORANT_INTENSITIES_INVALID);
+ }
}
+ /// Creates DeviceGray color with grayscale value initialised as zero.
public DeviceGray()
: this(0f) {
}
+ ///
+ /// Returns
+ /// DeviceGray
+ /// color which is lighter than given one
+ ///
+ /// the DeviceGray color to be made lighter
+ /// lighter color
public static iText.Kernel.Colors.DeviceGray MakeLighter(iText.Kernel.Colors.DeviceGray grayColor) {
float v = grayColor.GetColorValue()[0];
if (v == 0f) {
@@ -69,6 +95,13 @@ public static iText.Kernel.Colors.DeviceGray MakeLighter(iText.Kernel.Colors.Dev
return new iText.Kernel.Colors.DeviceGray(v * multiplier);
}
+ ///
+ /// Returns
+ /// DeviceGray
+ /// color which is darker than given one
+ ///
+ /// the DeviceGray color to be made darker
+ /// darker color
public static iText.Kernel.Colors.DeviceGray MakeDarker(iText.Kernel.Colors.DeviceGray grayColor) {
float v = grayColor.GetColorValue()[0];
float multiplier = Math.Max(0f, (v - 0.33f) / v);
diff --git a/itext/itext.kernel/itext/kernel/colors/DeviceRgb.cs b/itext/itext.kernel/itext/kernel/colors/DeviceRgb.cs
index c0ef69f05c..6441e8ab4a 100644
--- a/itext/itext.kernel/itext/kernel/colors/DeviceRgb.cs
+++ b/itext/itext.kernel/itext/kernel/colors/DeviceRgb.cs
@@ -42,22 +42,58 @@ source product.
address: sales@itextpdf.com
*/
using System;
+using iText.IO;
+using iText.IO.Log;
using iText.Kernel.Pdf.Colorspace;
namespace iText.Kernel.Colors {
+ /// Color space to specify colors according to RGB color model.
public class DeviceRgb : Color {
+ /// Creates DeviceRgb color by intensities of red, green and blue colorants.
+ ///
+ /// Creates DeviceRgb color by intensities of red, green and blue colorants.
+ /// The intensities are considered to be in [0, 255] gap, if not,
+ /// the intensity will be considered as 255 (when colorant's value is bigger than 255)
+ /// or 0 (when colorant's value is less than 0).
+ ///
+ /// the intensity of red colorant
+ /// the intensity of green colorant
+ /// the intensity of blue colorant
public DeviceRgb(int r, int g, int b)
: this(r / 255f, g / 255f, b / 255f) {
}
+ /// Creates DeviceRgb color by intensities of red, green and blue colorants.
+ ///
+ /// Creates DeviceRgb color by intensities of red, green and blue colorants.
+ /// The intensities are considered to be in [0, 1] interval, if not,
+ /// the intensity will be considered as 1 (when colorant's value is bigger than 1)
+ /// or 0 (when colorant's value is less than 0).
+ ///
+ /// the intensity of red colorant
+ /// the intensity of green colorant
+ /// the intensity of blue colorant
public DeviceRgb(float r, float g, float b)
- : base(new PdfDeviceCs.Rgb(), new float[] { r, g, b }) {
+ : base(new PdfDeviceCs.Rgb(), new float[] { r > 1 ? 1 : (r > 0 ? r : 0), g > 1 ? 1 : (g > 0 ? g : 0), b >
+ 1 ? 1 : (b > 0 ? b : 0) }) {
+ if (r > 1 || r < 0 || g > 1 || g < 0 || b > 1 || b < 0) {
+ ILogger LOGGER = LoggerFactory.GetLogger(typeof(iText.Kernel.Colors.DeviceRgb));
+ LOGGER.Warn(LogMessageConstant.COLORANT_INTENSITIES_INVALID);
+ }
}
+ /// Creates DeviceRgb color with all colorants intensities initialised as zeroes.
public DeviceRgb()
: this(0f, 0f, 0f) {
}
+ ///
+ /// Returns
+ /// DeviceRgb
+ /// color which is lighter than given one
+ ///
+ /// the DeviceRgb color to be made lighter
+ /// lighter color
public static iText.Kernel.Colors.DeviceRgb MakeLighter(iText.Kernel.Colors.DeviceRgb rgbColor) {
float r = rgbColor.GetColorValue()[0];
float g = rgbColor.GetColorValue()[1];
@@ -73,6 +109,13 @@ public static iText.Kernel.Colors.DeviceRgb MakeLighter(iText.Kernel.Colors.Devi
return new iText.Kernel.Colors.DeviceRgb(r, g, b);
}
+ ///
+ /// Returns
+ /// DeviceRgb
+ /// color which is darker than given one
+ ///
+ /// the DeviceRgb color to be made darker
+ /// darker color
public static iText.Kernel.Colors.DeviceRgb MakeDarker(iText.Kernel.Colors.DeviceRgb rgbColor) {
float r = rgbColor.GetColorValue()[0];
float g = rgbColor.GetColorValue()[1];
diff --git a/itext/itext.kernel/itext/kernel/colors/IccBased.cs b/itext/itext.kernel/itext/kernel/colors/IccBased.cs
index 1b05656349..9b6dd3821a 100644
--- a/itext/itext.kernel/itext/kernel/colors/IccBased.cs
+++ b/itext/itext.kernel/itext/kernel/colors/IccBased.cs
@@ -57,7 +57,6 @@ public IccBased(PdfCieBasedCs.IccBased cs, float[] value)
/// Creates IccBased color.
/// ICC profile stream. User is responsible for closing the stream.
- ///
public IccBased(Stream iccStream)
: this(new PdfCieBasedCs.IccBased(iccStream), null) {
// TODO if zero if outside of the Range, default value should be the nearest to the zero valid value
@@ -70,7 +69,6 @@ public IccBased(Stream iccStream)
/// Creates IccBased color.
/// ICC profile stream. User is responsible for closing the stream.
/// color value.
- ///
public IccBased(Stream iccStream, float[] value)
: this(new PdfCieBasedCs.IccBased(iccStream), value) {
}
diff --git a/itext/itext.kernel/itext/kernel/crypto/BadPasswordException.cs b/itext/itext.kernel/itext/kernel/crypto/BadPasswordException.cs
index 765416bfc0..8a47afe83b 100644
--- a/itext/itext.kernel/itext/kernel/crypto/BadPasswordException.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/BadPasswordException.cs
@@ -45,13 +45,23 @@ source product.
using iText.Kernel;
namespace iText.Kernel.Crypto {
+ /// Bad password exception.
public class BadPasswordException : PdfException {
public const String PdfReaderNotOpenedWithOwnerPassword = "PdfReader is not opened with owner password";
+ /// Creates a new BadPasswordException.
+ /// the detail message.
+ ///
+ /// the cause (which is saved for later retrieval by
+ ///
+ /// method).
+ ///
public BadPasswordException(String message, Exception cause)
: base(message, cause) {
}
+ /// Creates a new BadPasswordException.
+ /// the detail message.
public BadPasswordException(String message)
: base(message) {
}
diff --git a/itext/itext.kernel/itext/kernel/crypto/CryptoUtil.cs b/itext/itext.kernel/itext/kernel/crypto/CryptoUtil.cs
new file mode 100644
index 0000000000..33c766faca
--- /dev/null
+++ b/itext/itext.kernel/itext/kernel/crypto/CryptoUtil.cs
@@ -0,0 +1,68 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2016 iText Group NV
+ Authors: Bruno Lowagie, Paulo Soares, et al.
+
+ 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
+ ITEXT GROUP. ITEXT 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://itextpdf.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 iText.
+
+ 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 iText 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 iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+
+using System;
+using System.IO;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.X509;
+
+namespace iText.Kernel.Crypto {
+ ///
+ /// This file is a helper class for internal usage only.
+ /// Be aware that it's API and functionality may be changed in future.
+ ///
+ public static class CryptoUtil {
+
+ public static X509Certificate ReadPublicCertificate(Stream s) {
+ return new X509CertificateParser().ReadCertificate(s);
+ }
+
+ ///
+ ///
+ public static ICipherParameters ReadPrivateKeyFromPkcs12KeyStore(Stream keyStore, String pkAlias, char[] pkPassword) {
+ return new Pkcs12Store(keyStore, pkPassword).GetKey(pkAlias).Key;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/itext/itext.kernel/itext/kernel/crypto/IVGenerator.cs b/itext/itext.kernel/itext/kernel/crypto/IVGenerator.cs
index 0489cd0315..95f39d0594 100644
--- a/itext/itext.kernel/itext/kernel/crypto/IVGenerator.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/IVGenerator.cs
@@ -57,7 +57,7 @@ static IVGenerator() {
long time = SystemUtil.GetSystemTimeTicks();
long mem = SystemUtil.GetFreeMemory();
String s = time + "+" + mem;
- arcfour.PrepareARCFOURKey(s.GetBytes());
+ arcfour.PrepareARCFOURKey(s.GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1));
}
/// Creates a new instance of IVGenerator
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/EncryptionUtils.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/EncryptionUtils.cs
index 3b782da485..07eb505a10 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/EncryptionUtils.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/EncryptionUtils.cs
@@ -63,14 +63,18 @@ internal static byte[] FetchEnvelopedData(ICipherParameters certificateKey, X509
bool foundRecipient = false;
byte[] envelopedData = null;
for (int i = 0; i < recipients.Size(); i++) {
- PdfString recipient = recipients.GetAsString(i);
- CmsEnvelopedData data = new CmsEnvelopedData(recipient.GetValueBytes());
-
- foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients()) {
- if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient) {
- envelopedData = recipientInfo.GetContent(certificateKey);
- foundRecipient = true;
+ try {
+ PdfString recipient = recipients.GetAsString(i);
+ CmsEnvelopedData data = new CmsEnvelopedData(recipient.GetValueBytes());
+
+ foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients()) {
+ if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient) {
+ envelopedData = recipientInfo.GetContent(certificateKey);
+ foundRecipient = true;
+ }
}
+ } catch (Exception f) {
+ throw new PdfException(PdfException.PdfDecryption, f);
}
}
if (!foundRecipient || envelopedData == null) {
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes128.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes128.cs
index 4c5fd69bfa..adf7e73daa 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes128.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes128.cs
@@ -50,6 +50,8 @@ source product.
namespace iText.Kernel.Crypto.Securityhandler {
public class PubSecHandlerUsingAes128 : PubKeySecurityHandler {
+ private static readonly byte[] salt = new byte[] { (byte)0x73, (byte)0x41, (byte)0x6c, (byte)0x54 };
+
public PubSecHandlerUsingAes128(PdfDictionary encryptionDictionary, X509Certificate[] certs, int[] permissions
, bool encryptMetadata, bool embeddedFilesOnly) {
InitKeyAndFillDictionary(encryptionDictionary, certs, permissions, encryptMetadata, embeddedFilesOnly);
@@ -68,6 +70,24 @@ public override IDecryptor GetDecryptor() {
return new AesDecryptor(nextObjectKey, 0, nextObjectKeySize);
}
+ public override void SetHashKeyForNextObject(int objNumber, int objGeneration) {
+ md5.Reset();
+ // added by ujihara
+ extra[0] = (byte)objNumber;
+ extra[1] = (byte)(objNumber >> 8);
+ extra[2] = (byte)(objNumber >> 16);
+ extra[3] = (byte)objGeneration;
+ extra[4] = (byte)(objGeneration >> 8);
+ md5.Update(mkey);
+ md5.Update(extra);
+ md5.Update(salt);
+ nextObjectKey = md5.Digest();
+ nextObjectKeySize = mkey.Length + 5;
+ if (nextObjectKeySize > 16) {
+ nextObjectKeySize = 16;
+ }
+ }
+
protected internal override String GetDigestAlgorithm() {
return "SHA-1";
}
@@ -90,6 +110,7 @@ protected internal override void SetPubSecSpecificHandlerDicEntries(PdfDictionar
stdcf.Put(PdfName.EncryptMetadata, PdfBoolean.FALSE);
}
stdcf.Put(PdfName.CFM, PdfName.AESV2);
+ stdcf.Put(PdfName.Length, new PdfNumber(128));
PdfDictionary cf = new PdfDictionary();
cf.Put(PdfName.DefaultCryptFilter, stdcf);
encryptionDictionary.Put(PdfName.CF, cf);
diff --git a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes256.cs b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes256.cs
index d7a8277a63..6b8295ae9a 100644
--- a/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes256.cs
+++ b/itext/itext.kernel/itext/kernel/crypto/securityhandler/PubSecHandlerUsingAes256.cs
@@ -58,6 +58,10 @@ public PubSecHandlerUsingAes256(PdfDictionary encryptionDictionary, ICipherParam
: base(encryptionDictionary, certificateKey, certificate, encryptMetadata) {
}
+ public override void SetHashKeyForNextObject(int objNumber, int objGeneration) {
+ }
+
+ // in AES256 we don't recalculate nextObjectKey
protected internal override String GetDigestAlgorithm() {
return "SHA-256";
}
@@ -80,6 +84,7 @@ protected internal override void SetPubSecSpecificHandlerDicEntries(PdfDictionar
stdcf.Put(PdfName.EncryptMetadata, PdfBoolean.FALSE);
}
stdcf.Put(PdfName.CFM, PdfName.AESV3);
+ stdcf.Put(PdfName.Length, new PdfNumber(256));
PdfDictionary cf = new PdfDictionary();
cf.Put(PdfName.DefaultCryptFilter, stdcf);
encryptionDictionary.Put(PdfName.CF, cf);
diff --git a/itext/itext.kernel/itext/kernel/font/DocFontEncoding.cs b/itext/itext.kernel/itext/kernel/font/DocFontEncoding.cs
index 2319f8e387..c7f72abedf 100644
--- a/itext/itext.kernel/itext/kernel/font/DocFontEncoding.cs
+++ b/itext/itext.kernel/itext/kernel/font/DocFontEncoding.cs
@@ -53,7 +53,7 @@ internal class DocFontEncoding : FontEncoding {
protected internal DocFontEncoding() {
}
- public static FontEncoding CreateDocFontEncoding(PdfObject encoding, CMapToUnicode toUnicode, bool fillBaseEncoding
+ public static FontEncoding CreateDocFontEncoding(PdfObject encoding, CMapToUnicode toUnicode, bool fillStandardEncoding
) {
if (encoding != null) {
if (encoding.IsName()) {
@@ -63,9 +63,8 @@ public static FontEncoding CreateDocFontEncoding(PdfObject encoding, CMapToUnico
if (encoding.IsDictionary()) {
iText.Kernel.Font.DocFontEncoding fontEncoding = new iText.Kernel.Font.DocFontEncoding();
fontEncoding.differences = new String[256];
- if (fillBaseEncoding) {
- FillBaseEncoding(fontEncoding, ((PdfDictionary)encoding).GetAsName(PdfName.BaseEncoding));
- }
+ FillBaseEncoding(fontEncoding, ((PdfDictionary)encoding).GetAsName(PdfName.BaseEncoding), fillStandardEncoding
+ );
FillDifferences(fontEncoding, ((PdfDictionary)encoding).GetAsArray(PdfName.Differences), toUnicode);
return fontEncoding;
}
@@ -82,12 +81,8 @@ public static FontEncoding CreateDocFontEncoding(PdfObject encoding, CMapToUnico
}
}
- public static FontEncoding CreateDocFontEncoding(PdfObject encoding, CMapToUnicode toUnicode) {
- return CreateDocFontEncoding(encoding, toUnicode, true);
- }
-
private static void FillBaseEncoding(iText.Kernel.Font.DocFontEncoding fontEncoding, PdfName baseEncodingName
- ) {
+ , bool fillStandardEncoding) {
if (baseEncodingName != null) {
fontEncoding.baseEncoding = baseEncodingName.GetValue();
}
@@ -111,7 +106,9 @@ private static void FillBaseEncoding(iText.Kernel.Font.DocFontEncoding fontEncod
fontEncoding.FillNamedEncoding();
}
else {
- fontEncoding.FillStandardEncoding();
+ if (fillStandardEncoding) {
+ fontEncoding.FillStandardEncoding();
+ }
}
}
@@ -127,7 +124,7 @@ private static void FillDifferences(iText.Kernel.Font.DocFontEncoding fontEncodi
}
else {
String glyphName = ((PdfName)obj).GetValue();
- int unicode = (int)AdobeGlyphList.NameToUnicode(glyphName);
+ int unicode = AdobeGlyphList.NameToUnicode(glyphName);
if (unicode != -1) {
fontEncoding.codeToUnicode[currentNumber] = (int)unicode;
fontEncoding.unicodeToCode.Put((int)unicode, currentNumber);
diff --git a/itext/itext.kernel/itext/kernel/font/DocTrueTypeFont.cs b/itext/itext.kernel/itext/kernel/font/DocTrueTypeFont.cs
index fcf813c43e..90d954967e 100644
--- a/itext/itext.kernel/itext/kernel/font/DocTrueTypeFont.cs
+++ b/itext/itext.kernel/itext/kernel/font/DocTrueTypeFont.cs
@@ -56,6 +56,8 @@ internal class DocTrueTypeFont : TrueTypeFont, IDocFontProgram {
private PdfName subtype;
+ private int missingWidth = 0;
+
private DocTrueTypeFont(PdfDictionary fontDictionary)
: base() {
PdfName baseFontName = fontDictionary.GetAsName(PdfName.BaseFont);
@@ -73,13 +75,15 @@ internal static TrueTypeFont CreateFontProgram(PdfDictionary fontDictionary, Fon
FillFontDescriptor(fontProgram, fontDictionary.GetAsDictionary(PdfName.FontDescriptor));
PdfNumber firstCharNumber = fontDictionary.GetAsNumber(PdfName.FirstChar);
int firstChar = firstCharNumber != null ? Math.Max(firstCharNumber.IntValue(), 0) : 0;
- int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar);
+ int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar, fontProgram
+ .GetMissingWidth());
fontProgram.avgWidth = 0;
int glyphsWithWidths = 0;
for (int i = 0; i < 256; i++) {
Glyph glyph = new Glyph(i, widths[i], fontEncoding.GetUnicode(i));
fontProgram.codeToGlyph[i] = glyph;
- if (glyph.HasValidUnicode()) {
+ //FontEncoding.codeToUnicode table has higher priority
+ if (glyph.HasValidUnicode() && fontEncoding.ConvertToByte(glyph.GetUnicode()) == i) {
fontProgram.unicodeToGlyph[glyph.GetUnicode()] = glyph;
}
if (widths[i] > 0) {
@@ -133,6 +137,10 @@ public virtual PdfName GetSubtype() {
return subtype;
}
+ public virtual int GetMissingWidth() {
+ return missingWidth;
+ }
+
internal static void FillFontDescriptor(iText.Kernel.Font.DocTrueTypeFont font, PdfDictionary fontDesc) {
if (fontDesc == null) {
return;
@@ -169,6 +177,10 @@ internal static void FillFontDescriptor(iText.Kernel.Font.DocTrueTypeFont font,
if (v != null) {
font.SetFontWeight(v.IntValue());
}
+ v = fontDesc.GetAsNumber(PdfName.MissingWidth);
+ if (v != null) {
+ font.missingWidth = v.IntValue();
+ }
PdfName fontStretch = fontDesc.GetAsName(PdfName.FontStretch);
if (fontStretch != null) {
font.SetFontWidth(fontStretch.GetValue());
diff --git a/itext/itext.kernel/itext/kernel/font/DocType1Font.cs b/itext/itext.kernel/itext/kernel/font/DocType1Font.cs
index 1ab0fbf4bc..babe609c22 100644
--- a/itext/itext.kernel/itext/kernel/font/DocType1Font.cs
+++ b/itext/itext.kernel/itext/kernel/font/DocType1Font.cs
@@ -55,6 +55,8 @@ internal class DocType1Font : Type1Font, IDocFontProgram {
private PdfName subtype;
+ private int missingWidth = 0;
+
private DocType1Font(String fontName)
: base(fontName) {
}
@@ -89,15 +91,16 @@ internal static Type1Font CreateFontProgram(PdfDictionary fontDictionary, FontEn
FillFontDescriptor(fontProgram, fontDesc);
PdfNumber firstCharNumber = fontDictionary.GetAsNumber(PdfName.FirstChar);
int firstChar = firstCharNumber != null ? Math.Max(firstCharNumber.IntValue(), 0) : 0;
- int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar);
+ int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar, fontProgram
+ .GetMissingWidth());
fontProgram.avgWidth = 0;
int glyphsWithWidths = 0;
for (int i = 0; i < 256; i++) {
Glyph glyph = new Glyph(i, widths[i], fontEncoding.GetUnicode(i));
fontProgram.codeToGlyph[i] = glyph;
if (glyph.HasValidUnicode()) {
- // Workaround for fonts for embedded Document fonts with differences without base encoding
- if (!fontProgram.unicodeToGlyph.ContainsKey(glyph.GetUnicode()) || glyph.GetWidth() != 0) {
+ //FontEncoding.codeToUnicode table has higher priority
+ if (fontEncoding.ConvertToByte(glyph.GetUnicode()) == i) {
fontProgram.unicodeToGlyph[glyph.GetUnicode()] = glyph;
}
}
@@ -129,6 +132,10 @@ public virtual PdfName GetSubtype() {
return subtype;
}
+ public virtual int GetMissingWidth() {
+ return missingWidth;
+ }
+
internal static void FillFontDescriptor(iText.Kernel.Font.DocType1Font font, PdfDictionary fontDesc) {
if (fontDesc == null) {
return;
@@ -165,6 +172,10 @@ internal static void FillFontDescriptor(iText.Kernel.Font.DocType1Font font, Pdf
if (v != null) {
font.SetFontWeight(v.IntValue());
}
+ v = fontDesc.GetAsNumber(PdfName.MissingWidth);
+ if (v != null) {
+ font.missingWidth = v.IntValue();
+ }
PdfName fontStretch = fontDesc.GetAsName(PdfName.FontStretch);
if (fontStretch != null) {
font.SetFontWidth(fontStretch.GetValue());
diff --git a/itext/itext.kernel/itext/kernel/font/FontUtil.cs b/itext/itext.kernel/itext/kernel/font/FontUtil.cs
index 50f9cd3d6a..43b1535524 100644
--- a/itext/itext.kernel/itext/kernel/font/FontUtil.cs
+++ b/itext/itext.kernel/itext/kernel/font/FontUtil.cs
@@ -111,14 +111,17 @@ internal static String CreateRandomFontName() {
return s.ToString();
}
- internal static int[] ConvertSimpleWidthsArray(PdfArray widthsArray, int first) {
+ internal static int[] ConvertSimpleWidthsArray(PdfArray widthsArray, int first, int missingWidth) {
int[] res = new int[256];
+ for (int i = 0; i < res.Length; i++) {
+ res[i] = missingWidth;
+ }
if (widthsArray == null) {
return res;
}
- for (int i = 0; i < widthsArray.Size() && first + i < 256; i++) {
- PdfNumber number = widthsArray.GetAsNumber(i);
- res[first + i] = number != null ? number.IntValue() : 0;
+ for (int i_1 = 0; i_1 < widthsArray.Size() && first + i_1 < 256; i_1++) {
+ PdfNumber number = widthsArray.GetAsNumber(i_1);
+ res[first + i_1] = number != null ? number.IntValue() : missingWidth;
}
return res;
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfFont.cs b/itext/itext.kernel/itext/kernel/font/PdfFont.cs
index 948ad54619..d0f7a1d5a1 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfFont.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfFont.cs
@@ -77,13 +77,38 @@ protected internal PdfFont(PdfDictionary fontDictionary)
protected internal PdfFont()
: base(new PdfDictionary()) {
- MarkObjectAsIndirect(GetPdfObject());
GetPdfObject().Put(PdfName.Type, PdfName.Font);
}
+ /// Get glyph by unicode
+ /// a unicode code point
+ ///
+ ///
+ /// Glyph
+ /// if it exists or .NOTDEF if supported, otherwise
+ ///
+ /// .
+ ///
public abstract Glyph GetGlyph(int unicode);
+ /// Check whether font contains glyph with specified unicode.
+ /// a unicode code point
+ ///
+ /// true if font contains glyph, represented with the unicode code point,
+ /// otherwise false.
+ ///
+ [System.ObsoleteAttribute(@"Use ContainsGlyph(int) instead.")]
public virtual bool ContainsGlyph(char unicode) {
+ return ContainsGlyph((int)unicode);
+ }
+
+ /// Check whether font contains glyph with specified unicode.
+ /// a unicode code point
+ ///
+ /// true if font contains glyph, represented with the unicode code point,
+ /// otherwise false.
+ ///
+ public virtual bool ContainsGlyph(int unicode) {
Glyph glyph = GetGlyph(unicode);
if (glyph != null) {
if (GetFontProgram() != null && GetFontProgram().IsFontSpecific()) {
@@ -352,7 +377,12 @@ public virtual void AddSubsetRange(int[] range) {
subsetRanges.Add(range);
}
+ [System.ObsoleteAttribute(@"Will be removed in 7.1. Use SplitString(System.String, float, float) instead")]
public virtual IList SplitString(String text, int fontSize, float maxWidth) {
+ return SplitString(text, (float)fontSize, maxWidth);
+ }
+
+ public virtual IList SplitString(String text, float fontSize, float maxWidth) {
IList resultString = new List();
int lastWhiteSpace = 0;
int startPos = 0;
@@ -382,6 +412,21 @@ public virtual IList SplitString(String text, int fontSize, float maxWid
return resultString;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal abstract PdfDictionary GetFontDescriptor(String fontName);
protected internal override bool IsWrappedObjectMustBeIndirect() {
@@ -400,7 +445,7 @@ protected internal virtual bool CheckTrueTypeFontDictionary(PdfDictionary fontDi
if (fontDic == null || fontDic.Get(PdfName.Subtype) == null || !(fontDic.Get(PdfName.Subtype).Equals(PdfName
.TrueType) || fontDic.Get(PdfName.Subtype).Equals(PdfName.Type1))) {
if (isException) {
- throw new PdfException(PdfException.DictionaryNotContainFontData).SetMessageParams(PdfName.TrueType.GetValue
+ throw new PdfException(PdfException.DictionaryDoesntHave1FontData).SetMessageParams(PdfName.TrueType.GetValue
());
}
return false;
@@ -437,8 +482,7 @@ protected internal static String CreateSubsetPrefix() {
///
/// , if there is an error reading the font.
///
- ///
- /// PdfException
+ ///
/// Method will throw exception if
///
/// is
@@ -450,6 +494,7 @@ protected internal virtual PdfStream GetPdfFontStream(byte[] fontStreamBytes, in
throw new PdfException(PdfException.FontEmbeddingIssue);
}
PdfStream fontStream = new PdfStream(fontStreamBytes);
+ MakeObjectIndirect(fontStream);
for (int k = 0; k < fontStreamLengths.Length; ++k) {
fontStream.Put(new PdfName("Length" + (k + 1)), new PdfNumber(fontStreamLengths[k]));
}
@@ -484,5 +529,31 @@ protected internal static int[] CompactRanges(IList ranges) {
}
return s;
}
+
+ /// Helper method for making an object indirect, if the object already is indirect.
+ ///
+ /// Helper method for making an object indirect, if the object already is indirect.
+ /// Useful for FontDescriptor and FontFile to make possible immediate flushing.
+ /// If there is no PdfDocument, mark the object as
+ /// MUST_BE_INDIRECT
+ /// .
+ ///
+ /// an object to make indirect.
+ ///
+ /// if current object isn't indirect, returns
+ ///
+ /// , otherwise
+ /// tree
+ ///
+ internal virtual bool MakeObjectIndirect(PdfObject obj) {
+ if (GetPdfObject().GetIndirectReference() != null) {
+ obj.MakeIndirect(GetPdfObject().GetIndirectReference().GetDocument());
+ return true;
+ }
+ else {
+ MarkObjectAsIndirect(obj);
+ return false;
+ }
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfFontFactory.cs b/itext/itext.kernel/itext/kernel/font/PdfFontFactory.cs
index 2bdacc0148..510e05829d 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfFontFactory.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfFontFactory.cs
@@ -48,6 +48,10 @@ source product.
using iText.Kernel.Pdf;
namespace iText.Kernel.Font {
+ ///
+ /// This class provides helpful methods for creating fonts ready to be used in a
+ ///
+ ///
public sealed class PdfFontFactory {
/// This is the default encoding to use.
private static String DEFAULT_ENCODING = "";
@@ -55,14 +59,34 @@ public sealed class PdfFontFactory {
/// This is the default value of the embedded variable.
private static bool DEFAULT_EMBEDDING = false;
- /// This is the default value of the embedded variable.
- private static bool DEFAULT_CACHED = false;
-
- ///
+ /// This is the default value of the cached variable.
+ private static bool DEFAULT_CACHED = true;
+
+ ///
+ /// Creates a default font, namely
+ ///
+ /// standard font with
+ ///
+ /// encoding.
+ ///
+ /// created font
+ /// if error occurred while creating the font, e.g. metrics loading failure
+ ///
public static PdfFont CreateFont() {
return CreateFont(FontConstants.HELVETICA, PdfEncodings.WINANSI);
}
+ ///
+ /// Creates a
+ ///
+ /// by existing font dictionary.
+ ///
+ /// the font dictionary to create the font from
+ ///
+ /// created
+ ///
+ /// instance
+ ///
public static PdfFont CreateFont(PdfDictionary fontDictionary) {
if (CheckFontDictionary(fontDictionary, PdfName.Type1, false)) {
return new PdfType1Font(fontDictionary);
@@ -80,53 +104,191 @@ public static PdfFont CreateFont(PdfDictionary fontDictionary) {
return new PdfType3Font(fontDictionary);
}
else {
- throw new PdfException(PdfException.DictionaryNotContainFontData);
+ throw new PdfException(PdfException.DictionaryDoesntHaveSupportedFontData);
}
}
}
}
}
- ///
- public static PdfFont CreateFont(String path) {
- return CreateFont(path, DEFAULT_ENCODING);
+ ///
+ /// Creates a
+ ///
+ /// instance by the path of the font program file
+ ///
+ /// the path of the font program file
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// exception is thrown in case an I/O error occurs when reading the file
+ ///
+ public static PdfFont CreateFont(String fontProgram) {
+ return CreateFont(fontProgram, DEFAULT_ENCODING);
}
- ///
- public static PdfFont CreateFont(String path, String encoding) {
- return CreateFont(path, encoding, DEFAULT_EMBEDDING);
+ ///
+ /// Creates a
+ ///
+ /// instance by the path of the font program file and given encoding.
+ ///
+ /// the path of the font program file
+ ///
+ /// the font encoding. See
+ ///
+ ///
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// exception is thrown in case an I/O error occurs when reading the file
+ ///
+ public static PdfFont CreateFont(String fontProgram, String encoding) {
+ return CreateFont(fontProgram, encoding, DEFAULT_EMBEDDING);
}
- ///
+ ///
+ /// Creates a
+ ///
+ /// instance from the TrueTypeCollection represented by its byte contents.
+ ///
+ /// the byte contents of the TrueTypeCollection
+ /// the index of the font in the collection, zero-based
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ /// indicates whether the font will be cached
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// in case the contents of the TrueTypeCollection is mal-formed or an error occurred during reading the font
+ ///
public static PdfFont CreateTtcFont(byte[] ttc, int ttcIndex, String encoding, bool embedded, bool cached) {
FontProgram fontProgram = FontProgramFactory.CreateFont(ttc, ttcIndex, cached);
return CreateFont(fontProgram, encoding, embedded);
}
- ///
- public static PdfFont CreateTtcFont(String ttcPath, int ttcIndex, String encoding, bool embedded, bool cached
- ) {
- FontProgram fontProgram = FontProgramFactory.CreateFont(ttcPath, ttcIndex, cached);
- return CreateFont(fontProgram, encoding, embedded);
- }
-
- ///
- public static PdfFont CreateFont(String path, bool embedded) {
- return CreateFont(path, DEFAULT_ENCODING, embedded);
- }
-
- ///
- public static PdfFont CreateFont(String path, String encoding, bool embedded) {
- return CreateFont(path, encoding, embedded, DEFAULT_CACHED);
- }
-
- ///
- public static PdfFont CreateFont(String path, String encoding, bool embedded, bool cached) {
- FontProgram fontProgram = FontProgramFactory.CreateFont(path, cached);
+ ///
+ /// Creates a
+ ///
+ /// instance from the TrueTypeCollection given by the path to the .ttc file.
+ ///
+ /// the path of the .ttc file
+ /// the index of the font in the collection, zero-based
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ /// indicates whether the font will be cached
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ ///
+ /// in case the file is not found, contents of the TrueTypeCollection is mal-formed
+ /// or an error occurred during reading the font
+ ///
+ public static PdfFont CreateTtcFont(String ttc, int ttcIndex, String encoding, bool embedded, bool cached) {
+ FontProgram fontProgram = FontProgramFactory.CreateFont(ttc, ttcIndex, cached);
return CreateFont(fontProgram, encoding, embedded);
}
- ///
+ ///
+ /// Created a
+ ///
+ /// instance given the path to the font file.
+ ///
+ /// the font program file
+ /// indicates whether the font is to be embedded into the target document
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// in case the file is not found or the contents of the font file is mal-formed
+ ///
+ public static PdfFont CreateFont(String fontProgram, bool embedded) {
+ return CreateFont(fontProgram, DEFAULT_ENCODING, embedded);
+ }
+
+ ///
+ /// Created a
+ ///
+ /// instance given the path to the font file.
+ ///
+ /// the font program file
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// in case the file is not found or the contents of the font file is mal-formed
+ ///
+ public static PdfFont CreateFont(String fontProgram, String encoding, bool embedded) {
+ return CreateFont(fontProgram, encoding, embedded, DEFAULT_CACHED);
+ }
+
+ ///
+ /// Created a
+ ///
+ /// instance given the path to the font file.
+ ///
+ /// the font program file
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ /// indicates whether the font will be cached
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// in case the file is not found or the contents of the font file is mal-formed
+ ///
+ public static PdfFont CreateFont(String fontProgram, String encoding, bool embedded, bool cached) {
+ FontProgram fp = FontProgramFactory.CreateFont(fontProgram, cached);
+ return CreateFont(fp, encoding, embedded);
+ }
+
+ ///
+ /// Created a
+ ///
+ /// instance given the given underlying
+ ///
+ /// instance.
+ ///
+ ///
+ /// the font program of the
+ ///
+ /// instance to be created
+ ///
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown and will be removed in 7.1.
+ ///
public static PdfFont CreateFont(FontProgram fontProgram, String encoding, bool embedded) {
if (fontProgram == null) {
return null;
@@ -161,69 +323,257 @@ public static PdfFont CreateFont(FontProgram fontProgram, String encoding, bool
}
}
- ///
+ ///
+ /// Created a
+ ///
+ /// instance given the given underlying
+ ///
+ /// instance.
+ ///
+ ///
+ /// the font program of the
+ ///
+ /// instance to be created
+ ///
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown and will be removed in 7.1.
+ ///
public static PdfFont CreateFont(FontProgram fontProgram, String encoding) {
return CreateFont(fontProgram, encoding, DEFAULT_EMBEDDING);
}
- ///
+ ///
+ /// Created a
+ ///
+ /// instance given the given underlying
+ ///
+ /// instance.
+ ///
+ ///
+ /// the font program of the
+ ///
+ /// instance to be created
+ ///
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown and will be removed in 7.1.
+ ///
public static PdfFont CreateFont(FontProgram fontProgram) {
return CreateFont(fontProgram, DEFAULT_ENCODING);
}
- ///
- public static PdfFont CreateFont(byte[] font, String encoding) {
- return CreateFont(font, encoding, DEFAULT_EMBEDDING);
- }
-
- ///
- public static PdfFont CreateFont(byte[] font, bool embedded) {
- return CreateFont(font, null, embedded);
- }
-
- ///
- public static PdfFont CreateFont(byte[] font, String encoding, bool embedded) {
- return CreateFont(font, encoding, embedded, DEFAULT_CACHED);
- }
-
- ///
- public static PdfFont CreateFont(byte[] font, String encoding, bool embedded, bool cached) {
- FontProgram fontProgram = FontProgramFactory.CreateFont(null, font, cached);
- return CreateFont(fontProgram, encoding, embedded);
+ ///
+ /// Created a
+ ///
+ /// instance by the bytes of the underlying font program.
+ ///
+ /// the bytes of the underlying font program
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown. Will be removed in 7.1.
+ public static PdfFont CreateFont(byte[] fontProgram, String encoding) {
+ return CreateFont(fontProgram, encoding, DEFAULT_EMBEDDING);
}
- ///
+ ///
+ /// Created a
+ ///
+ /// instance by the bytes of the underlying font program.
+ ///
+ /// the bytes of the underlying font program
+ /// indicates whether the font is to be embedded into the target document
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown. Will be removed in 7.1.
+ public static PdfFont CreateFont(byte[] fontProgram, bool embedded) {
+ return CreateFont(fontProgram, null, embedded);
+ }
+
+ ///
+ /// Created a
+ ///
+ /// instance by the bytes of the underlying font program.
+ ///
+ /// the bytes of the underlying font program
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown. Will be removed in 7.1.
+ public static PdfFont CreateFont(byte[] fontProgram, String encoding, bool embedded) {
+ return CreateFont(fontProgram, encoding, embedded, DEFAULT_CACHED);
+ }
+
+ ///
+ /// Created a
+ ///
+ /// instance by the bytes of the underlying font program.
+ ///
+ /// the bytes of the underlying font program
+ ///
+ /// the encoding of the font to be created. See
+ ///
+ ///
+ /// indicates whether the font is to be embedded into the target document
+ /// indicates whether the font will be cached
+ ///
+ /// created
+ ///
+ /// instance
+ ///
+ /// this exception is actually never thrown. Will be removed in 7.1.
+ public static PdfFont CreateFont(byte[] fontProgram, String encoding, bool embedded, bool cached) {
+ FontProgram fp = FontProgramFactory.CreateFont(null, fontProgram, cached);
+ return CreateFont(fp, encoding, embedded);
+ }
+
+ ///
+ /// Creates a new instance of
+ ///
+ ///
+ /// the target document of the new font
+ /// indicates whether the font will be colorized
+ /// created font
+ /// actually this exception is never thrown. This will be removed in 7.1.
+ ///
public static PdfType3Font CreateType3Font(PdfDocument document, bool colorized) {
return new PdfType3Font(document, colorized);
}
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static PdfFont CreateRegisteredFont(String font, String encoding, bool embedded, int style, bool cached
- ) {
- FontProgram fontProgram = FontProgramFactory.CreateRegisteredFont(font, style, cached);
- return CreateFont(fontProgram, encoding, embedded);
- }
-
+ public static PdfFont CreateRegisteredFont(String fontName, String encoding, bool embedded, int style, bool
+ cached) {
+ FontProgram fp = FontProgramFactory.CreateRegisteredFont(fontName, style, cached);
+ return CreateFont(fp, encoding, embedded);
+ }
+
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static PdfFont CreateRegisteredFont(String font, String encoding, bool embedded, bool cached) {
- return CreateRegisteredFont(font, encoding, embedded, FontConstants.UNDEFINED, cached);
- }
-
+ public static PdfFont CreateRegisteredFont(String fontName, String encoding, bool embedded, bool cached) {
+ return CreateRegisteredFont(fontName, encoding, embedded, FontConstants.UNDEFINED, cached);
+ }
+
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static PdfFont CreateRegisteredFont(String font, String encoding, bool embedded) {
- return CreateRegisteredFont(font, encoding, embedded, FontConstants.UNDEFINED);
- }
-
+ public static PdfFont CreateRegisteredFont(String fontName, String encoding, bool embedded) {
+ return CreateRegisteredFont(fontName, encoding, embedded, FontConstants.UNDEFINED);
+ }
+
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static PdfFont CreateRegisteredFont(String font, String encoding, bool embedded, int style) {
- return CreateRegisteredFont(font, encoding, embedded, style, DEFAULT_CACHED);
- }
-
+ public static PdfFont CreateRegisteredFont(String fontName, String encoding, bool embedded, int style) {
+ return CreateRegisteredFont(fontName, encoding, embedded, style, DEFAULT_CACHED);
+ }
+
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
- public static PdfFont CreateRegisteredFont(String font, String encoding) {
- return CreateRegisteredFont(font, encoding, false, FontConstants.UNDEFINED);
- }
-
+ public static PdfFont CreateRegisteredFont(String fontName, String encoding) {
+ return CreateRegisteredFont(fontName, encoding, false, FontConstants.UNDEFINED);
+ }
+
+ ///
+ /// Creates
+ ///
+ /// based on registered
+ ///
+ /// 's.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
///
public static PdfFont CreateRegisteredFont(String fontName) {
return CreateRegisteredFont(fontName, null, false, FontConstants.UNDEFINED);
@@ -237,8 +587,13 @@ public static void RegisterFamily(String familyName, String fullName, String pat
FontProgramFactory.RegisterFontFamily(familyName, fullName, path);
}
- /// Register a ttf- or a ttc-file.
- /// the path to a ttf- or ttc-file
+ /// Registers a .ttf, .otf, .afm, .pfm, or a .ttc font file.
+ ///
+ /// Registers a .ttf, .otf, .afm, .pfm, or a .ttc font file.
+ /// In case if TrueTypeCollection (.ttc), an additional parameter may be specified defining the index of the font
+ /// to be registered, e.g. "path/to/font/collection.ttc,0". The index is zero-based.
+ ///
+ /// the path to a font file
public static void Register(String path) {
Register(path, null);
}
@@ -250,11 +605,11 @@ public static void Register(String path, String alias) {
FontProgramFactory.RegisterFont(path, alias);
}
- /// Register all the fonts in a directory.
- /// the directory
+ /// Registers all the fonts in a directory.
+ /// the directory path to be registered as a font directory path
/// the number of fonts registered
- public static int RegisterDirectory(String dir) {
- return FontProgramFactory.RegisterFontDirectory(dir);
+ public static int RegisterDirectory(String dirPath) {
+ return FontProgramFactory.RegisterFontDirectory(dirPath);
}
/// Register fonts in some probable directories.
@@ -273,25 +628,28 @@ public static ICollection GetRegisteredFonts() {
return FontProgramFactory.GetRegisteredFonts();
}
- /// Gets a set of registered font names.
+ /// Gets a set of registered font families.
/// a set of registered font families
public static ICollection GetRegisteredFamilies() {
return FontProgramFactory.GetRegisteredFontFamilies();
}
/// Checks if a certain font is registered.
- /// the name of the font that has to be checked.
- /// true if the font is found
- public static bool IsRegistered(String fontname) {
- return FontProgramFactory.IsRegisteredFont(fontname);
+ /// the name of the font that has to be checked.
+ /// true if the font is found, false otherwise
+ public static bool IsRegistered(String fontName) {
+ return FontProgramFactory.IsRegisteredFont(fontName);
}
+ /// Checks if the provided dictionary is a valid font dictionary of the provided font type.
+ /// true if the passed dictionary is a valid dictionary, false otherwise
+ [System.ObsoleteAttribute(@"this method will become private in 7.1. Do not use this method")]
protected internal static bool CheckFontDictionary(PdfDictionary fontDic, PdfName fontType, bool isException
) {
if (fontDic == null || fontDic.Get(PdfName.Subtype) == null || !fontDic.Get(PdfName.Subtype).Equals(fontType
)) {
if (isException) {
- throw new PdfException(PdfException.DictionaryNotContainFontData).SetMessageParams(fontType.GetValue());
+ throw new PdfException(PdfException.DictionaryDoesntHave1FontData).SetMessageParams(fontType.GetValue());
}
return false;
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfSimpleFont.cs b/itext/itext.kernel/itext/kernel/font/PdfSimpleFont.cs
index 9cfe87d88e..ba2807e3b6 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfSimpleFont.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfSimpleFont.cs
@@ -181,9 +181,11 @@ public override String Decode(PdfString content) {
builder.Append((char)(int)uni);
}
else {
- Glyph glyph = fontProgram.GetGlyphByCode(b & 0xff);
- if (glyph != null && glyph.GetChars() != null) {
- builder.Append(glyph.GetChars());
+ if (fontEncoding.GetBaseEncoding() == null) {
+ Glyph glyph = fontProgram.GetGlyphByCode(b & 0xff);
+ if (glyph != null && glyph.GetChars() != null) {
+ builder.Append(glyph.GetChars());
+ }
}
}
}
@@ -194,7 +196,16 @@ public override float GetContentWidth(PdfString content) {
float width = 0;
byte[] contentBytes = content.GetValueBytes();
foreach (byte b in contentBytes) {
- Glyph glyph = fontProgram.GetGlyphByCode(b & 0xff);
+ Glyph glyph = null;
+ int uni = fontEncoding.GetUnicode(b & 0xff);
+ if (uni > -1) {
+ glyph = GetGlyph(uni);
+ }
+ else {
+ if (fontEncoding.GetBaseEncoding() == null) {
+ glyph = fontProgram.GetGlyphByCode(b & 0xff);
+ }
+ }
width += glyph != null ? glyph.GetWidth() : 0;
}
return width;
@@ -319,7 +330,9 @@ protected internal virtual void FlushFontData(String fontName, PdfName subtype)
PdfDictionary fontDescriptor = !IsBuiltInFont() ? GetFontDescriptor(fontName) : null;
if (fontDescriptor != null) {
GetPdfObject().Put(PdfName.FontDescriptor, fontDescriptor);
- fontDescriptor.Flush();
+ if (fontDescriptor.GetIndirectReference() != null) {
+ fontDescriptor.Flush();
+ }
}
}
@@ -341,7 +354,7 @@ protected internal override PdfDictionary GetFontDescriptor(String fontName) {
FontMetrics fontMetrics = fontProgram.GetFontMetrics();
FontNames fontNames = fontProgram.GetFontNames();
PdfDictionary fontDescriptor = new PdfDictionary();
- MarkObjectAsIndirect(fontDescriptor);
+ MakeObjectIndirect(fontDescriptor);
fontDescriptor.Put(PdfName.Type, PdfName.FontDescriptor);
fontDescriptor.Put(PdfName.FontName, new PdfName(fontName));
fontDescriptor.Put(PdfName.Ascent, new PdfNumber(fontMetrics.GetTypoAscender()));
@@ -363,11 +376,15 @@ protected internal override PdfDictionary GetFontDescriptor(String fontName) {
[0].Length >= 4) {
fontDescriptor.Put(PdfName.FontFamily, new PdfString(fontNames.GetFamilyName()[0][3]));
}
+ //add font stream and flush it immediately
AddFontStream(fontDescriptor);
int flags = fontProgram.GetPdfFontFlags();
- if (!fontEncoding.IsFontSpecific()) {
- flags &= ~64;
+ if (fontProgram.IsFontSpecific() != fontEncoding.IsFontSpecific()) {
+ flags &= ~(4 | 32);
+ // reset both flags
+ flags |= fontEncoding.IsFontSpecific() ? 4 : 32;
}
+ // set based on font encoding
fontDescriptor.Put(PdfName.Flags, new PdfNumber(flags));
return fontDescriptor;
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfTrueTypeFont.cs b/itext/itext.kernel/itext/kernel/font/PdfTrueTypeFont.cs
index a5192a3016..46134606bf 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfTrueTypeFont.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfTrueTypeFont.cs
@@ -81,7 +81,7 @@ internal PdfTrueTypeFont(PdfDictionary fontDictionary)
newFont = false;
CheckFontDictionary(fontDictionary, PdfName.TrueType);
CMapToUnicode toUni = FontUtil.ProcessToUnicode(fontDictionary.Get(PdfName.ToUnicode));
- fontEncoding = DocFontEncoding.CreateDocFontEncoding(fontDictionary.Get(PdfName.Encoding), toUni);
+ fontEncoding = DocFontEncoding.CreateDocFontEncoding(fontDictionary.Get(PdfName.Encoding), toUni, false);
fontProgram = DocTrueTypeFont.CreateFontProgram(fontDictionary, fontEncoding);
embedded = ((IDocFontProgram)fontProgram).GetFontFile() != null;
subset = false;
@@ -103,8 +103,8 @@ public override Glyph GetGlyph(int unicode) {
return null;
}
- //TODO make subtype class member and simplify this method
public override void Flush() {
+ //TODO make subtype class member and simplify this method
if (newFont) {
PdfName subtype;
String fontName;
@@ -204,6 +204,9 @@ protected internal override void AddFontStream(PdfDictionary fontDescriptor) {
}
if (fontStream != null) {
fontDescriptor.Put(fontFileName, fontStream);
+ if (fontStream.GetIndirectReference() != null) {
+ fontStream.Flush();
+ }
}
}
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfType0Font.cs b/itext/itext.kernel/itext/kernel/font/PdfType0Font.cs
index 17ced64b27..222496cb9f 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfType0Font.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfType0Font.cs
@@ -388,7 +388,7 @@ public override float GetContentWidth(PdfString content) {
protected internal override PdfDictionary GetFontDescriptor(String fontName) {
PdfDictionary fontDescriptor = new PdfDictionary();
- MarkObjectAsIndirect(fontDescriptor);
+ MakeObjectIndirect(fontDescriptor);
fontDescriptor.Put(PdfName.Type, PdfName.FontDescriptor);
fontDescriptor.Put(PdfName.FontName, new PdfName(fontName));
fontDescriptor.Put(PdfName.FontBBox, new PdfArray(GetFontProgram().GetFontMetrics().GetBbox()));
@@ -436,8 +436,11 @@ private void FlushFontData() {
PdfDictionary cidFont = GetCidFontType2(null, fontDescriptor, fontProgram.GetFontNames().GetFontName(), metrics
);
GetPdfObject().Put(PdfName.DescendantFonts, new PdfArray(cidFont));
- fontDescriptor.Flush();
- cidFont.Flush();
+ if (GetPdfObject().GetIndirectReference() != null) {
+ //this means, that fontDescriptor and cidFont already are indirects
+ fontDescriptor.Flush();
+ cidFont.Flush();
+ }
}
else {
if (cidFontType == CID_FONT_TYPE_2) {
@@ -495,10 +498,16 @@ private void FlushFontData() {
PdfStream toUnicode = GetToUnicode(metrics);
if (toUnicode != null) {
GetPdfObject().Put(PdfName.ToUnicode, toUnicode);
- toUnicode.Flush();
+ if (toUnicode.GetIndirectReference() != null) {
+ toUnicode.Flush();
+ }
+ }
+ if (GetPdfObject().GetIndirectReference() != null) {
+ //this means, that fontDescriptor, cidFont and fontStream already are indirects
+ fontDescriptor.Flush();
+ cidFont.Flush();
+ fontStream.Flush();
}
- fontDescriptor.Flush();
- cidFont.Flush();
}
else {
throw new InvalidOperationException("Unsupported CID Font");
@@ -514,7 +523,7 @@ private void FlushFontData() {
protected internal virtual PdfDictionary GetCidFontType2(TrueTypeFont ttf, PdfDictionary fontDescriptor, String
fontName, int[][] metrics) {
PdfDictionary cidFont = new PdfDictionary();
- MarkObjectAsIndirect(cidFont);
+ MakeObjectIndirect(cidFont);
cidFont.Put(PdfName.Type, PdfName.Font);
// sivan; cff
cidFont.Put(PdfName.FontDescriptor, fontDescriptor);
@@ -606,7 +615,9 @@ public virtual PdfStream GetToUnicode(Object[] metrics) {
}
}
buf.Append("endbfrange\n" + "endcmap\n" + "CMapName currentdict /CMap defineresource pop\n" + "end end\n");
- return new PdfStream(PdfEncodings.ConvertToBytes(buf.ToString(), null));
+ PdfStream toUnicode = new PdfStream(PdfEncodings.ConvertToBytes(buf.ToString(), null));
+ MakeObjectIndirect(toUnicode);
+ return toUnicode;
}
//TODO optimize memory ussage
diff --git a/itext/itext.kernel/itext/kernel/font/PdfType1Font.cs b/itext/itext.kernel/itext/kernel/font/PdfType1Font.cs
index e3b7ddccbf..b697f18a42 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfType1Font.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfType1Font.cs
@@ -74,7 +74,10 @@ internal PdfType1Font(PdfDictionary fontDictionary)
newFont = false;
CheckFontDictionary(fontDictionary, PdfName.Type1);
CMapToUnicode toUni = FontUtil.ProcessToUnicode(fontDictionary.Get(PdfName.ToUnicode));
- fontEncoding = DocFontEncoding.CreateDocFontEncoding(fontDictionary.Get(PdfName.Encoding), toUni);
+ //if there is no FontDescriptor, it is most likely one of the Standard Font with StandardEncoding as base encoding.
+ bool fillStandardEncoding = !fontDictionary.ContainsKey(PdfName.FontDescriptor);
+ fontEncoding = DocFontEncoding.CreateDocFontEncoding(fontDictionary.Get(PdfName.Encoding), toUni, fillStandardEncoding
+ );
fontProgram = DocType1Font.CreateFontProgram(fontDictionary, fontEncoding, toUni);
if (fontProgram is IDocFontProgram) {
embedded = ((IDocFontProgram)fontProgram).GetFontFile() != null;
@@ -134,6 +137,7 @@ protected internal override void AddFontStream(PdfDictionary fontDescriptor) {
if (fontProgram is IDocFontProgram) {
IDocFontProgram docType1Font = (IDocFontProgram)fontProgram;
fontDescriptor.Put(docType1Font.GetFontFileName(), docType1Font.GetFontFile());
+ docType1Font.GetFontFile().Flush();
if (docType1Font.GetSubtype() != null) {
fontDescriptor.Put(PdfName.Subtype, docType1Font.GetSubtype());
}
@@ -147,6 +151,9 @@ protected internal override void AddFontStream(PdfDictionary fontDescriptor) {
fontStream.Put(new PdfName("Length" + (k + 1)), new PdfNumber(fontStreamLengths[k]));
}
fontDescriptor.Put(PdfName.FontFile, fontStream);
+ if (MakeObjectIndirect(fontStream)) {
+ fontStream.Flush();
+ }
}
}
}
diff --git a/itext/itext.kernel/itext/kernel/font/PdfType3Font.cs b/itext/itext.kernel/itext/kernel/font/PdfType3Font.cs
index 4e5299112d..0816ca1b74 100644
--- a/itext/itext.kernel/itext/kernel/font/PdfType3Font.cs
+++ b/itext/itext.kernel/itext/kernel/font/PdfType3Font.cs
@@ -99,14 +99,14 @@ internal PdfType3Font(PdfDictionary fontDictionary)
}
PdfNumber firstCharNumber = fontDictionary.GetAsNumber(PdfName.FirstChar);
int firstChar = firstCharNumber != null ? Math.Max(firstCharNumber.IntValue(), 0) : 0;
- int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar);
+ int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar, 0);
double[] fontMatrix = new double[6];
for (int i = 0; i < fontMatrixArray.Size(); i++) {
fontMatrix[i] = ((PdfNumber)fontMatrixArray.Get(i)).GetValue();
}
SetFontMatrix(fontMatrix);
foreach (PdfName glyphName in charProcsDic.KeySet()) {
- int unicode = (int)AdobeGlyphList.NameToUnicode(glyphName.GetValue());
+ int unicode = AdobeGlyphList.NameToUnicode(glyphName.GetValue());
if (unicode != -1 && fontEncoding.CanEncode(unicode)) {
int code = fontEncoding.ConvertToByte(unicode);
((Type3FontProgram)GetFontProgram()).AddGlyph(code, unicode, widths[code], null, new Type3Glyph(charProcsDic
@@ -216,6 +216,7 @@ public override void Flush() {
if (fontEncoding.CanDecode(i)) {
Type3Glyph glyph = GetType3Glyph(fontEncoding.GetUnicode(i));
charProcs.Put(new PdfName(fontEncoding.GetDifference(i)), glyph.GetContentStream());
+ glyph.GetContentStream().Flush();
}
}
GetPdfObject().Put(PdfName.CharProcs, charProcs);
diff --git a/itext/itext.kernel/itext/kernel/geom/AffineTransform.cs b/itext/itext.kernel/itext/kernel/geom/AffineTransform.cs
index f44d86e58c..66f6e0b005 100644
--- a/itext/itext.kernel/itext/kernel/geom/AffineTransform.cs
+++ b/itext/itext.kernel/itext/kernel/geom/AffineTransform.cs
@@ -45,27 +45,87 @@ source product.
namespace iText.Kernel.Geom {
public class AffineTransform {
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_IDENTITY = 0;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_TRANSLATION = 1;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_UNIFORM_SCALE = 2;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_GENERAL_SCALE = 4;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_QUADRANT_ROTATION = 8;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_GENERAL_ROTATION = 16;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_GENERAL_TRANSFORM = 32;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_FLIP = 64;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_MASK_SCALE = TYPE_UNIFORM_SCALE | TYPE_GENERAL_SCALE;
+ /// The type of affine transformation.
+ ///
+ /// The type of affine transformation. See
+ ///
+ /// .
+ ///
public const int TYPE_MASK_ROTATION = TYPE_QUADRANT_ROTATION | TYPE_GENERAL_ROTATION;
- /// The TYPE_UNKNOWN is an initial type value
+ /// The TYPE_UNKNOWN is an initial type value.
internal const int TYPE_UNKNOWN = -1;
/// The min value equivalent to zero.
@@ -139,25 +199,42 @@ public AffineTransform(double[] matrix) {
}
}
- /*
- * Method returns type of affine transformation.
- *
- * Transform matrix is
- * m00 m01 m02
- * m10 m11 m12
- *
- * According analytic geometry new basis vectors are (m00, m01) and (m10, m11),
- * translation vector is (m02, m12). Original basis vectors are (1, 0) and (0, 1).
- * Type transformations classification:
- * TYPE_IDENTITY - new basis equals original one and zero translation
- * TYPE_TRANSLATION - translation vector isn't zero
- * TYPE_UNIFORM_SCALE - vectors length of new basis equals
- * TYPE_GENERAL_SCALE - vectors length of new basis doesn't equal
- * TYPE_FLIP - new basis vector orientation differ from original one
- * TYPE_QUADRANT_ROTATION - new basis is rotated by 90, 180, 270, or 360 degrees
- * TYPE_GENERAL_ROTATION - new basis is rotated by arbitrary angle
- * TYPE_GENERAL_TRANSFORM - transformation can't be inversed
- */
+ /// Method returns type of affine transformation.
+ ///
+ /// Method returns type of affine transformation.
+ /// Transform matrix is
+ /// m00 m01 m02
+ /// m10 m11 m12
+ /// According analytic geometry new basis vectors are (m00, m01) and (m10, m11),
+ /// translation vector is (m02, m12). Original basis vectors are (1, 0) and (0, 1).
+ /// Type transformations classification:
+ ///
+ ///
+ ///
+ /// - new basis equals original one and zero translation
+ ///
+ ///
+ /// - translation vector isn't zero
+ ///
+ ///
+ /// - vectors length of new basis equals
+ ///
+ ///
+ /// - vectors length of new basis doesn't equal
+ ///
+ ///
+ /// - new basis vector orientation differ from original one
+ ///
+ ///
+ /// - new basis is rotated by 90, 180, 270, or 360 degrees
+ ///
+ ///
+ /// - new basis is rotated by arbitrary angle
+ ///
+ ///
+ /// - transformation can't be inversed
+ ///
+ ///
public virtual int GetTransformType() {
if (this.type != TYPE_UNKNOWN) {
return this.type;
diff --git a/itext/itext.kernel/itext/kernel/geom/LineSegment.cs b/itext/itext.kernel/itext/kernel/geom/LineSegment.cs
index 1d319af607..f0ce2df7e1 100644
--- a/itext/itext.kernel/itext/kernel/geom/LineSegment.cs
+++ b/itext/itext.kernel/itext/kernel/geom/LineSegment.cs
@@ -84,7 +84,20 @@ public virtual float GetLength() {
/// origin of the lower left hand end point of the segment, with width = 4 and height = 3.
///
/// the bounding rectangle
+ [System.ObsoleteAttribute(@"Use getBoundingRectangle(). Will be removed in 7.1")]
public virtual Rectangle GetBoundingRectange() {
+ return GetBoundingRectangle();
+ }
+
+ /// Computes the bounding rectangle for this line segment.
+ ///
+ /// Computes the bounding rectangle for this line segment. The rectangle has a rotation 0 degrees
+ /// with respect to the coordinate system that the line system is in. For example, if a line segment
+ /// is 5 unit long and sits at a 37 degree angle from horizontal, the bounding rectangle will have
+ /// origin of the lower left hand end point of the segment, with width = 4 and height = 3.
+ ///
+ /// the bounding rectangle
+ public virtual Rectangle GetBoundingRectangle() {
float x1 = GetStartPoint().Get(Vector.I1);
float y1 = GetStartPoint().Get(Vector.I2);
float x2 = GetEndPoint().Get(Vector.I1);
diff --git a/itext/itext.kernel/itext/kernel/geom/NoninvertibleTransformException.cs b/itext/itext.kernel/itext/kernel/geom/NoninvertibleTransformException.cs
index 84d2d4f5b4..9a00567bee 100644
--- a/itext/itext.kernel/itext/kernel/geom/NoninvertibleTransformException.cs
+++ b/itext/itext.kernel/itext/kernel/geom/NoninvertibleTransformException.cs
@@ -21,9 +21,13 @@
using System;
namespace iText.Kernel.Geom {
+ /// NoninvertibleTransformException
+ /// Denis M. Kishenko
public class NoninvertibleTransformException : Exception {
- public NoninvertibleTransformException(String s)
- : base(s) {
+ /// Creates a new NoninvertibleTransformException.
+ /// the detail message.
+ public NoninvertibleTransformException(String message)
+ : base(message) {
}
}
}
diff --git a/itext/itext.kernel/itext/kernel/geom/PageSize.cs b/itext/itext.kernel/itext/kernel/geom/PageSize.cs
index cd1400a80b..7700d37094 100644
--- a/itext/itext.kernel/itext/kernel/geom/PageSize.cs
+++ b/itext/itext.kernel/itext/kernel/geom/PageSize.cs
@@ -61,6 +61,42 @@ public class PageSize : Rectangle {
public static iText.Kernel.Geom.PageSize A8 = new iText.Kernel.Geom.PageSize(148, 210);
+ public static iText.Kernel.Geom.PageSize A9 = new iText.Kernel.Geom.PageSize(105, 547);
+
+ public static iText.Kernel.Geom.PageSize A10 = new iText.Kernel.Geom.PageSize(74, 105);
+
+ public static iText.Kernel.Geom.PageSize B0 = new iText.Kernel.Geom.PageSize(2834, 4008);
+
+ public static iText.Kernel.Geom.PageSize B1 = new iText.Kernel.Geom.PageSize(2004, 2834);
+
+ public static iText.Kernel.Geom.PageSize B2 = new iText.Kernel.Geom.PageSize(1417, 2004);
+
+ public static iText.Kernel.Geom.PageSize B3 = new iText.Kernel.Geom.PageSize(1000, 1417);
+
+ public static iText.Kernel.Geom.PageSize B4 = new iText.Kernel.Geom.PageSize(708, 1000);
+
+ public static iText.Kernel.Geom.PageSize B5 = new iText.Kernel.Geom.PageSize(498, 708);
+
+ public static iText.Kernel.Geom.PageSize B6 = new iText.Kernel.Geom.PageSize(354, 498);
+
+ public static iText.Kernel.Geom.PageSize B7 = new iText.Kernel.Geom.PageSize(249, 354);
+
+ public static iText.Kernel.Geom.PageSize B8 = new iText.Kernel.Geom.PageSize(175, 249);
+
+ public static iText.Kernel.Geom.PageSize B9 = new iText.Kernel.Geom.PageSize(124, 175);
+
+ public static iText.Kernel.Geom.PageSize B10 = new iText.Kernel.Geom.PageSize(88, 124);
+
+ public static iText.Kernel.Geom.PageSize LETTER = new iText.Kernel.Geom.PageSize(612, 792);
+
+ public static iText.Kernel.Geom.PageSize LEGAL = new iText.Kernel.Geom.PageSize(612, 1008);
+
+ public static iText.Kernel.Geom.PageSize TABLOID = new iText.Kernel.Geom.PageSize(792, 1224);
+
+ public static iText.Kernel.Geom.PageSize LEDGER = new iText.Kernel.Geom.PageSize(1224, 792);
+
+ public static iText.Kernel.Geom.PageSize EXECUTIVE = new iText.Kernel.Geom.PageSize(522, 756);
+
public static iText.Kernel.Geom.PageSize Default = A4;
public PageSize(float width, float height)
diff --git a/itext/itext.kernel/itext/kernel/geom/Rectangle.cs b/itext/itext.kernel/itext/kernel/geom/Rectangle.cs
index 839498302b..10a74a8d2e 100644
--- a/itext/itext.kernel/itext/kernel/geom/Rectangle.cs
+++ b/itext/itext.kernel/itext/kernel/geom/Rectangle.cs
@@ -100,6 +100,23 @@ public static iText.Kernel.Geom.Rectangle GetCommonRectangle(params iText.Kernel
return new iText.Kernel.Geom.Rectangle(llx, lly, urx - llx, ury - lly);
}
+ /// Sets the rectangle by the coordinates, specifying its lower left and upper right points.
+ ///
+ /// Sets the rectangle by the coordinates, specifying its lower left and upper right points. May be used in chain.
+ ///
+ ///
+ /// Note: this method will normalize coordinates, so the rectangle will have non negative width and height,
+ /// and its x and y coordinates specified lower left point.
+ ///
+ /// the X coordinate of lower left point
+ /// the Y coordinate of lower left point
+ /// the X coordinate of upper right point
+ /// the Y coordinate of upper right point
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle SetBbox(float llx, float lly, float urx, float ury) {
// If llx is greater than urx, swap them (normalize)
if (llx > urx) {
@@ -120,84 +137,148 @@ public virtual iText.Kernel.Geom.Rectangle SetBbox(float llx, float lly, float u
return this;
}
+ /// Gets the X coordinate of lower left point.
+ /// the X coordinate of lower left point.
public virtual float GetX() {
return x;
}
+ /// Sets the X coordinate of lower left point.
+ /// Sets the X coordinate of lower left point. May be used in chain.
+ /// the X coordinate of lower left point to be set.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle SetX(float x) {
this.x = x;
return this;
}
+ /// Gets the Y coordinate of lower left point.
+ /// the Y coordinate of lower left point.
public virtual float GetY() {
return y;
}
+ /// Sets the Y coordinate of lower left point.
+ /// Sets the Y coordinate of lower left point. May be used in chain.
+ /// the Y coordinate of lower left point to be set.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle SetY(float y) {
this.y = y;
return this;
}
+ /// Gets the width of rectangle.
+ /// the width of rectangle.
public virtual float GetWidth() {
return width;
}
+ /// Sets the width of rectangle.
+ /// Sets the width of rectangle. May be used in chain.
+ /// the the width of rectangle to be set.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle SetWidth(float width) {
this.width = width;
return this;
}
+ /// Gets the height of rectangle.
+ /// the height of rectangle.
public virtual float GetHeight() {
return height;
}
+ /// Sets the height of rectangle.
+ /// Sets the height of rectangle. May be used in chain.
+ /// the the width of rectangle to be set.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle SetHeight(float height) {
this.height = height;
return this;
}
+ /// Increases the height of rectangle by the given value.
+ /// Increases the height of rectangle by the given value. May be used in chain.
+ /// the value of the extra height to be added.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle IncreaseHeight(float extra) {
this.height += extra;
return this;
}
+ /// Decreases the height of rectangle by the given value.
+ /// Decreases the height of rectangle by the given value. May be used in chain.
+ /// the value of the extra height to be subtracted.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Geom.Rectangle DecreaseHeight(float extra) {
this.height -= extra;
return this;
}
- ///
- /// Gets llx, the same:
+ /// Gets the X coordinate of the left edge of the rectangle.
+ ///
+ /// Gets the X coordinate of the left edge of the rectangle. Same as:
/// getX()
/// .
- ///
+ ///
+ /// the X coordinate of the left edge of the rectangle.
public virtual float GetLeft() {
return x;
}
- ///
- /// Gets urx, the same to
+ /// Gets the X coordinate of the right edge of the rectangle.
+ ///
+ /// Gets the X coordinate of the right edge of the rectangle. Same as:
/// getX() + getWidth()
/// .
- ///
+ ///
+ /// the X coordinate of the right edge of the rectangle.
public virtual float GetRight() {
return x + width;
}
- ///
- /// Gets ury, the same to
+ /// Gets the Y coordinate of the upper edge of the rectangle.
+ ///
+ /// Gets the Y coordinate of the upper edge of the rectangle. Same as:
/// getY() + getHeight()
/// .
- ///
+ ///
+ /// the Y coordinate of the upper edge of the rectangle.
public virtual float GetTop() {
return y + height;
}
- ///
- /// Gets lly, the same to
+ /// Gets the Y coordinate of the lower edge of the rectangle.
+ ///
+ /// Gets the Y coordinate of the lower edge of the rectangle. Same as:
/// getY()
/// .
- ///
+ ///
+ /// the Y coordinate of the lower edge of the rectangle.
public virtual float GetBottom() {
return y;
}
@@ -246,6 +327,8 @@ public override String ToString() {
return "Rectangle: " + GetWidth() + 'x' + GetHeight();
}
+ /// Gets the copy of this rectangle.
+ /// the copied rectangle.
public virtual iText.Kernel.Geom.Rectangle Clone() {
return new iText.Kernel.Geom.Rectangle(x, y, width, height);
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/ByteBufferOutputStream.cs b/itext/itext.kernel/itext/kernel/pdf/ByteBufferOutputStream.cs
index 19f44fed2b..e3319509e1 100644
--- a/itext/itext.kernel/itext/kernel/pdf/ByteBufferOutputStream.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/ByteBufferOutputStream.cs
@@ -269,7 +269,7 @@ public virtual iText.Kernel.Pdf.ByteBufferOutputStream Append(String str)
{
if (str != null)
{
- return Append(str.GetBytes());
+ return Append(str.GetBytes(EncodingUtil.ISO_8859_1));
}
return this;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/CompressionConstants.cs b/itext/itext.kernel/itext/kernel/pdf/CompressionConstants.cs
index 3125cb2092..a6386a1854 100644
--- a/itext/itext.kernel/itext/kernel/pdf/CompressionConstants.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/CompressionConstants.cs
@@ -42,23 +42,24 @@ source product.
address: sales@itextpdf.com
*/
-namespace iText.Kernel.Pdf
-{
- public class CompressionConstants
- {
- /// A possible compression level.
- public const int UNDEFINED_COMPRESSION = int.MinValue;
+namespace iText.Kernel.Pdf {
+ ///
+ /// Compression constants for .
+ ///
+ public class CompressionConstants {
+ /// A possible compression level.
+ public const int UNDEFINED_COMPRESSION = int.MinValue;
- /// A possible compression level.
- public const int DEFAULT_COMPRESSION = -1;
+ /// A possible compression level.
+ public const int DEFAULT_COMPRESSION = -1;
- /// A possible compression level.
- public const int NO_COMPRESSION = 0;
+ /// A possible compression level.
+ public const int NO_COMPRESSION = 0;
- /// A possible compression level.
- public const int BEST_SPEED = 1;
+ /// A possible compression level.
+ public const int BEST_SPEED = 1;
- /// A possible compression level.
- public const int BEST_COMPRESSION = 9;
- }
+ /// A possible compression level.
+ public const int BEST_COMPRESSION = 9;
+ }
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/EncryptionConstants.cs b/itext/itext.kernel/itext/kernel/pdf/EncryptionConstants.cs
index 0ed9019eea..826b245cf2 100644
--- a/itext/itext.kernel/itext/kernel/pdf/EncryptionConstants.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/EncryptionConstants.cs
@@ -42,6 +42,11 @@ source product.
address: sales@itextpdf.com
*/
namespace iText.Kernel.Pdf {
+ ///
+ /// Encryption constants for
+ ///
+ /// .
+ ///
public class EncryptionConstants {
/// Type of encryption.
public const int STANDARD_ENCRYPTION_40 = 0;
diff --git a/itext/itext.kernel/itext/kernel/pdf/IsoKey.cs b/itext/itext.kernel/itext/kernel/pdf/IsoKey.cs
index 6277eacb80..61bc43e6fa 100644
--- a/itext/itext.kernel/itext/kernel/pdf/IsoKey.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/IsoKey.cs
@@ -42,6 +42,7 @@ source product.
address: sales@itextpdf.com
*/
namespace iText.Kernel.Pdf {
+ /// Type of object to conform.
public enum IsoKey {
CANVAS_STACK,
DRAWMODE_FILL,
@@ -51,6 +52,7 @@ public enum IsoKey {
INLINE_IMAGE,
PAGE,
PDF_OBJECT,
- RENDERING_INTENT
+ RENDERING_INTENT,
+ TAG_STRUCTURE_ELEMENT
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfArray.cs b/itext/itext.kernel/itext/kernel/pdf/PdfArray.cs
index f10942a315..964658b0e1 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfArray.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfArray.cs
@@ -209,16 +209,35 @@ public virtual bool IsEmpty()
public virtual bool Contains(PdfObject o)
{
- return list.Contains(o);
- }
+ if (list.Contains(o))
+ return true;
+ if (o == null)
+ return false;
+ foreach (PdfObject pdfObject in this)
+ if (PdfObject.EqualContent(o, pdfObject))
+ return true;
+ return false;
+ }
+ ///
+ /// Returns an iterator over an array of PdfObject elements.
+ ///
+ /// NOTE: since 7.0.1 it returns collection of direct objects.
+ /// If you want to get {@link PdfIndirectReference} instances for the indirect objects value,
+ /// you shall use {@link #get(int, boolean)} method.
+ ///
+ /// an enumerator.
public IEnumerator GetEnumerator()
{
- return list.GetEnumerator();
+ return new PdfArrayDirectIterator(list.GetEnumerator());
}
+ ///
+ /// Returns an iterator over an array of PdfObject elements.
+ ///
+ [Obsolete("Use {@link #iterator()} instead")]
public IEnumerator GetDirectEnumerator() {
- return new PdfArrayDirectEnumerator(list.GetEnumerator());
+ return new PdfArrayDirectIterator(list.GetEnumerator());
}
public virtual void Add(PdfObject pdfObject)
@@ -228,8 +247,20 @@ public virtual void Add(PdfObject pdfObject)
public virtual void Remove(PdfObject o)
{
- list.Remove(o);
- }
+ if (list.Remove(o))
+ return;
+ if (o == null)
+ return;
+ PdfObject toDelete = null;
+ foreach (PdfObject pdfObject in list)
+ if (PdfObject.EqualContent(o, pdfObject))
+ {
+ toDelete = pdfObject;
+ break;
+ }
+ if (toDelete != null)
+ list.Remove(toDelete);
+ }
/// Adds the Collection of PdfObjects.
/// the Collection of PdfObjects to be added
@@ -283,8 +314,8 @@ public virtual PdfObject Set(int index, PdfObject element)
return list[index] = element;
}
- /// Adds the specified PdfObject qt the specified index.
- /// Adds the specified PdfObject qt the specified index. All objects after this index will be shifted by 1.
+ /// Adds the specified PdfObject at the specified index.
+ /// Adds the specified PdfObject at the specified index. All objects after this index will be shifted by 1.
///
/// position to insert the PdfObject
/// PdfObject to be added
@@ -309,8 +340,17 @@ public virtual void Remove(int index)
///
public virtual int IndexOf(PdfObject o)
{
- return list.IndexOf(o);
- }
+ if (o == null)
+ return list.IndexOf(null);
+ int index = 0;
+ foreach (PdfObject pdfObject in this)
+ {
+ if (PdfObject.EqualContent(o, pdfObject))
+ return index;
+ index++;
+ }
+ return -1;
+ }
/// Returns a sublist of this PdfArray, starting at fromIndex (inclusive) and ending at toIndex (exclusive).
///
@@ -394,7 +434,6 @@ IEnumerator IEnumerable.GetEnumerator() {
}
/// true is to extract direct object always.
- ///
public virtual PdfObject Get(int index, bool asDirect)
{
if (!asDirect)
@@ -565,47 +604,5 @@ protected internal virtual void ReleaseContent()
{
list = null;
}
-
- private class PdfArrayDirectEnumerator : IEnumerator
- {
- private IEnumerator parentEnumerator;
-
- public PdfArrayDirectEnumerator(IEnumerator parentEnumerator)
- {
- this.parentEnumerator = parentEnumerator;
- }
-
- public void Dispose()
- {
- parentEnumerator.Dispose();
- }
-
- public bool MoveNext()
- {
- if (parentEnumerator.MoveNext())
- {
- PdfObject obj = parentEnumerator.Current;
- if (obj.IsIndirectReference())
- {
- obj = ((PdfIndirectReference)obj).GetRefersTo(true);
- }
- Current = obj;
- return true;
- }
- return false;
- }
-
- public void Reset()
- {
- parentEnumerator.Reset();
- }
-
- public PdfObject Current { get; private set; }
-
- object IEnumerator.Current
- {
- get { return Current; }
- }
- }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfArrayDirectIterator.cs b/itext/itext.kernel/itext/kernel/pdf/PdfArrayDirectIterator.cs
new file mode 100644
index 0000000000..1cf12161c5
--- /dev/null
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfArrayDirectIterator.cs
@@ -0,0 +1,89 @@
+/*
+
+This file is part of the iText (R) project.
+Copyright (c) 1998-2016 iText Group NV
+Authors: Bruno Lowagie, Paulo Soares, et al.
+
+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
+ITEXT GROUP. ITEXT 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://itextpdf.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 iText.
+
+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 iText 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 iText with a closed
+source product.
+
+For more information, please contact iText Software Corp. at this
+address: sales@itextpdf.com
+*/
+using System.Collections;
+using System.Collections.Generic;
+
+namespace iText.Kernel.Pdf {
+ internal class PdfArrayDirectIterator : IEnumerator
+ {
+ private IEnumerator parentEnumerator;
+
+ internal PdfArrayDirectIterator(IEnumerator parentEnumerator)
+ {
+ this.parentEnumerator = parentEnumerator;
+ }
+
+ public void Dispose()
+ {
+ parentEnumerator.Dispose();
+ }
+
+ public bool MoveNext()
+ {
+ if (parentEnumerator.MoveNext())
+ {
+ PdfObject obj = parentEnumerator.Current;
+ if (obj.IsIndirectReference())
+ {
+ obj = ((PdfIndirectReference)obj).GetRefersTo(true);
+ }
+ Current = obj;
+ return true;
+ }
+ return false;
+ }
+
+ public void Reset()
+ {
+ parentEnumerator.Reset();
+ }
+
+ public PdfObject Current { get; private set; }
+
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+ }
+}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfBoolean.cs b/itext/itext.kernel/itext/kernel/pdf/PdfBoolean.cs
index 2bb6c349cd..e02886c6a0 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfBoolean.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfBoolean.cs
@@ -135,5 +135,14 @@ protected internal override void CopyContent(PdfObject from, PdfDocument documen
iText.Kernel.Pdf.PdfBoolean @bool = (iText.Kernel.Pdf.PdfBoolean)from;
value = @bool.value;
}
+
+ public override bool Equals(Object obj) {
+ return this == obj || obj != null && GetType() == obj.GetType() && value == ((iText.Kernel.Pdf.PdfBoolean)
+ obj).value;
+ }
+
+ public override int GetHashCode() {
+ return (value ? 1 : 0);
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs b/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs
index 051328f372..6a18fd811f 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfCatalog.cs
@@ -43,6 +43,7 @@ source product.
*/
using System;
using System.Collections.Generic;
+using iText.IO.Log;
using iText.Kernel;
using iText.Kernel.Pdf.Action;
using iText.Kernel.Pdf.Collection;
@@ -73,7 +74,7 @@ protected internal PdfCatalog(PdfDictionary pdfObject)
//This HashMap contents all pages of the document and outlines associated to them
//This flag determines if Outline tree of the document has been built via calling getOutlines method. If this flag is false all outline operations will be ignored
if (pdfObject == null) {
- throw new PdfException(PdfException.DocumentHasNoCatalogObject);
+ throw new PdfException(PdfException.DocumentHasNoPdfCatalogObject);
}
EnsureObjectIsAddedToDocument(pdfObject);
GetPdfObject().Put(PdfName.Type, PdfName.Catalog);
@@ -134,7 +135,8 @@ public virtual PdfDocument GetDocument() {
/// PdfCatalog will be flushed in PdfDocument.close().
/// PdfCatalog will be flushed in PdfDocument.close(). User mustn't flush PdfCatalog!
public override void Flush() {
- throw new PdfException(PdfException.YouCannotFlushPdfCatalogManually);
+ ILogger logger = LoggerFactory.GetLogger(typeof(PdfDocument));
+ logger.Warn("PdfCatalog cannot be flushed manually");
}
public virtual iText.Kernel.Pdf.PdfCatalog SetOpenAction(PdfDestination destination) {
@@ -330,9 +332,8 @@ internal virtual IDictionary> GetPagesWithOutlines(
/// Name of the destination.
///
/// An object destination refers to. Must be an array or a dictionary with key /D and array.
- /// See PdfSpec 12.3.2.3 for more info.
+ /// See ISO 32000-1 12.3.2.3 for more info.
///
- ///
internal virtual void AddNamedDestination(String key, PdfObject value) {
AddNameToNameTree(key, value, PdfName.Dests);
}
@@ -349,11 +350,14 @@ internal virtual void AddNameToNameTree(String key, PdfObject value, PdfName tre
/// This method returns a complete outline tree of the whole document.
///
- /// - if this flag is true, the method read the whole document and creates outline tree.
+ /// if the flag is true, the method read the whole document and creates outline tree.
/// If false the method gets cached outline tree (if it was cached via calling getOutlines method before).
///
- ///
- ///
+ ///
+ /// fully initialized
+ ///
+ /// object.
+ ///
internal virtual PdfOutline GetOutlines(bool updateOutlines) {
if (outlines != null && !updateOutlines) {
return outlines;
@@ -401,7 +405,6 @@ internal virtual bool IsOutlineMode() {
/// This method removes all outlines associated with a given page
///
- ///
internal virtual void RemoveOutlines(PdfPage page) {
if (GetDocument().GetWriter() == null) {
return;
@@ -409,8 +412,10 @@ internal virtual void RemoveOutlines(PdfPage page) {
if (HasOutlines()) {
GetOutlines(false);
if (pagesWithOutlines.Count > 0) {
- foreach (PdfOutline outline in pagesWithOutlines.Get(page.GetPdfObject())) {
- outline.RemoveOutline();
+ if (pagesWithOutlines.Get(page.GetPdfObject()) != null) {
+ foreach (PdfOutline outline in pagesWithOutlines.Get(page.GetPdfObject())) {
+ outline.RemoveOutline();
+ }
}
}
}
@@ -418,7 +423,6 @@ internal virtual void RemoveOutlines(PdfPage page) {
/// This method sets the root outline element in the catalog.
///
- ///
internal virtual void AddRootOutline(PdfOutline outline) {
if (!outlineMode) {
return;
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfDictionary.cs b/itext/itext.kernel/itext/kernel/pdf/PdfDictionary.cs
index d1f0533a8c..2eb131ab72 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfDictionary.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfDictionary.cs
@@ -314,11 +314,48 @@ public virtual ICollection KeySet() {
}
/// Returns all the values of this map in a Collection.
+ ///
+ /// if false, collection will contain
+ ///
+ /// instances
+ /// for the indirect objects in dictionary, otherwise it will contain collection of direct objects.
+ ///
+ /// a Collection holding all the values
+ public virtual ICollection Values(bool asDirects) {
+ if (asDirects) {
+ return Values();
+ }
+ else {
+ return map.Values;
+ }
+ }
+
+ /// Returns all the values of this map in a Collection.
+ ///
+ /// Returns all the values of this map in a Collection.
+ ///
+ /// NOTE: since 7.0.1 it returns collection of direct objects.
+ /// If you want to get
+ ///
+ /// instances for the indirect objects value,
+ /// you shall use
+ ///
+ /// method.
+ ///
/// a Collection holding all the values
public virtual ICollection Values() {
- return map.Values;
+ return new PdfDictionaryValues(map.Values);
}
+ /// Returns all the values of this map in a Collection.
+ ///
+ /// Returns all the values of this map in a Collection. In opposite to
+ ///
+ /// method,
+ /// this method will resolve all indirect references in the dictionary and return actual objects in collection.
+ ///
+ /// a Collection holding all the values
+ [System.ObsoleteAttribute(@"Use Values() instead.")]
public virtual ICollection DirectValues() {
ICollection directValues = new List();
foreach (PdfObject value in map.Values) {
@@ -333,13 +370,33 @@ public virtual ICollection DirectValues() {
}
/// Returns a Set holding the key-value pairs as Map#Entry objects.
+ ///
+ /// Returns a Set holding the key-value pairs as Map#Entry objects.
+ ///
+ /// NOTE: since 7.0.1 it returns collection of direct objects.
+ /// If you want to get
+ ///
+ /// instances for the indirect objects value,
+ /// you shall use
+ ///
+ /// method.
+ ///
/// a Set of Map.Entry objects
public virtual ICollection> EntrySet() {
- return map;
+ return new PdfDictionaryEntrySet(map);
}
+ /// Returns a Set holding the key-value pairs as Map#Entry objects.
+ ///
+ /// Returns a Set holding the key-value pairs as Map#Entry objects. In opposite to
+ ///
+ /// method, this method will resolve all indirect references in the dictionary and return actual objects as values of
+ /// entries in the collection.
+ ///
+ /// a Set of Map.Entry objects
+ [System.ObsoleteAttribute(@"Use EntrySet() instead.")]
public virtual ICollection> DirectEntrySet() {
- IDictionary directMap = new Dictionary();
+ IDictionary directMap = new SortedDictionary();
foreach (KeyValuePair entry in map) {
PdfObject value = entry.Value;
if (value.IsIndirectReference()) {
@@ -359,7 +416,7 @@ public override byte GetObjectType() {
public override String ToString() {
if (!IsFlushed()) {
String @string = "<<";
- foreach (KeyValuePair entry in EntrySet()) {
+ foreach (KeyValuePair entry in map) {
PdfIndirectReference indirectReference = entry.Value.GetIndirectReference();
@string = @string + entry.Key.ToString() + " " + (indirectReference == null ? entry.Value.ToString() : indirectReference
.ToString()) + " ";
@@ -379,7 +436,6 @@ public override String ToString() {
///
/// list of objects to exclude when cloning dictionary.
/// cloned dictionary.
- ///
public virtual iText.Kernel.Pdf.PdfDictionary Clone(IList excludeKeys) {
IDictionary excluded = new SortedDictionary();
foreach (PdfName key in excludeKeys) {
@@ -446,7 +502,6 @@ public override PdfObject CopyTo(PdfDocument document, bool allowDuplicating) {
///
///
/// copied dictionary.
- ///
public virtual iText.Kernel.Pdf.PdfDictionary CopyTo(PdfDocument document, IList excludeKeys, bool
allowDuplicating) {
IDictionary excluded = new SortedDictionary();
@@ -463,7 +518,6 @@ public virtual iText.Kernel.Pdf.PdfDictionary CopyTo(PdfDocument document, IList
}
/// true is to extract direct object always.
- ///
public virtual PdfObject Get(PdfName key, bool asDirect) {
if (!asDirect) {
return map.Get(key);
@@ -496,7 +550,7 @@ protected internal override PdfObject NewInstance() {
protected internal override void CopyContent(PdfObject from, PdfDocument document) {
base.CopyContent(from, document);
iText.Kernel.Pdf.PdfDictionary dictionary = (iText.Kernel.Pdf.PdfDictionary)from;
- foreach (KeyValuePair entry in dictionary.EntrySet()) {
+ foreach (KeyValuePair entry in dictionary.map) {
map[entry.Key] = entry.Value.ProcessCopying(document, false);
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryEntrySet.cs b/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryEntrySet.cs
new file mode 100644
index 0000000000..8149cf8637
--- /dev/null
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryEntrySet.cs
@@ -0,0 +1,178 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2016 iText Group NV
+ Authors: Bruno Lowagie, Paulo Soares, et al.
+
+ 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
+ ITEXT GROUP. ITEXT 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://itextpdf.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 iText.
+
+ 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 iText 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 iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace iText.Kernel.Pdf {
+ internal class PdfDictionaryEntrySet : ICollection>
+ {
+ private readonly ICollection> collection;
+
+ internal PdfDictionaryEntrySet(ICollection> collection) {
+ this.collection = collection;
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return new DirectEnumerator(collection.GetEnumerator());
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public void Add(KeyValuePair item)
+ {
+ collection.Add(item);
+ }
+
+ public void Clear()
+ {
+ collection.Clear();
+ }
+
+ public bool Contains(KeyValuePair item)
+ {
+ if (collection.Contains(item))
+ return true;
+ if (item.Value == null)
+ return false;
+ foreach (KeyValuePair entry in this)
+ if (item.Key.Equals(entry.Key) && item.Value.Equals(entry.Value))
+ return true;
+ return false;
+ }
+
+ public void CopyTo(KeyValuePair[] array, int arrayIndex)
+ {
+ int count = collection.Count;
+ if (count == 0)
+ return;
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, "arrayIndex mut not be negtive");
+ if (arrayIndex >= array.Length || count > array.Length - arrayIndex)
+ throw new ArgumentException("arrayIndex", "array too small");
+
+ int index = arrayIndex;
+ foreach (KeyValuePair item in this)
+ {
+ if (--count < 0)
+ break;
+ array[index++] = item;
+ }
+ }
+
+ public bool Remove(KeyValuePair item)
+ {
+ if (collection.Remove(item))
+ return true;
+ if (item.Value == null)
+ return false;
+ KeyValuePair toDelete = new KeyValuePair(null, null);
+ foreach (KeyValuePair entry in collection)
+ if (item.Key.Equals(entry.Key) && PdfObject.EqualContent(item.Value, entry.Value))
+ {
+ toDelete = entry;
+ break;
+ }
+
+ return toDelete.Key != null && collection.Remove(toDelete);
+ }
+
+ public int Count
+ {
+ get { return collection.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return collection.IsReadOnly; }
+ }
+
+ private class DirectEnumerator : IEnumerator>
+ {
+ private IEnumerator> parentEnumerator;
+
+ public DirectEnumerator(IEnumerator> parentEnumerator)
+ {
+ this.parentEnumerator = parentEnumerator;
+ }
+
+ public void Dispose()
+ {
+ parentEnumerator.Dispose();
+ }
+
+ public bool MoveNext()
+ {
+ if (parentEnumerator.MoveNext())
+ {
+ KeyValuePair current = parentEnumerator.Current;
+ if (current.Value != null && current.Value.IsIndirectReference())
+ {
+ current = new KeyValuePair(current.Key, ((PdfIndirectReference)current.Value).GetRefersTo(true));
+ }
+ Current = current;
+ return true;
+ }
+ return false;
+ }
+
+ public void Reset()
+ {
+ parentEnumerator.Reset();
+ }
+
+ public KeyValuePair Current { get; private set; }
+
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+ }
+ }
+}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryValues.cs b/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryValues.cs
new file mode 100644
index 0000000000..8d73abb39c
--- /dev/null
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfDictionaryValues.cs
@@ -0,0 +1,173 @@
+/*
+ This file is part of the iText (R) project.
+ Copyright (c) 1998-2016 iText Group NV
+ Authors: Bruno Lowagie, Paulo Soares, et al.
+
+ 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
+ ITEXT GROUP. ITEXT 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://itextpdf.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 iText.
+
+ 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 iText 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 iText with a closed
+ source product.
+
+ For more information, please contact iText Software Corp. at this
+ address: sales@itextpdf.com
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace iText.Kernel.Pdf {
+
+ internal class PdfDictionaryValues : ICollection {
+ private readonly ICollection collection;
+
+ internal PdfDictionaryValues(ICollection collection) {
+ this.collection = collection;
+ }
+
+ public void Add(PdfObject item)
+ {
+ collection.Add(item);
+ }
+
+ public void Clear()
+ {
+ collection.Clear();
+ }
+
+ public bool Contains(PdfObject item)
+ {
+ if (collection.Contains(item))
+ return true;
+ if (item == null)
+ return false;
+ foreach (PdfObject pdfObject in this)
+ {
+ if (PdfObject.EqualContent(item, pdfObject))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void CopyTo(PdfObject[] array, int arrayIndex)
+ {
+ int count = collection.Count;
+ if (count == 0)
+ return;
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException("arrayIndex", arrayIndex, "arrayIndex mut not be negtive");
+ if (arrayIndex >= array.Length || count > array.Length - arrayIndex)
+ throw new ArgumentException("arrayIndex", "array too small");
+
+ int index = arrayIndex;
+ foreach (PdfObject item in this)
+ {
+ if (--count < 0)
+ break;
+ array[index++] = item;
+ }
+ }
+
+ public bool Remove(PdfObject item)
+ {
+ //Actually we will get exception:
+ // System.NotSupportedException : Mutating a value collection derived from a dictionary is not allowed.
+ return collection.Remove(item);
+ }
+
+ public int Count
+ {
+ get { return collection.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return collection.IsReadOnly; }
+ }
+
+
+ public IEnumerator GetEnumerator()
+ {
+ return new DirectEnumerator(collection.GetEnumerator());
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ private class DirectEnumerator : IEnumerator
+ {
+ private IEnumerator parentEnumerator;
+
+ public DirectEnumerator(IEnumerator parentEnumerator)
+ {
+ this.parentEnumerator = parentEnumerator;
+ }
+
+ public void Dispose()
+ {
+ parentEnumerator.Dispose();
+ }
+
+ public bool MoveNext()
+ {
+ if (parentEnumerator.MoveNext())
+ {
+ PdfObject obj = parentEnumerator.Current;
+ if (obj != null && obj.IsIndirectReference())
+ {
+ obj = ((PdfIndirectReference)obj).GetRefersTo(true);
+ }
+ Current = obj;
+ return true;
+ }
+ return false;
+ }
+
+ public void Reset()
+ {
+ parentEnumerator.Reset();
+ }
+
+ public PdfObject Current { get; private set; }
+
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+ }
+ }
+}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs b/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs
index 5f7dbaa3e5..4ca4acc3ee 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfDocument.cs
@@ -64,6 +64,7 @@ source product.
using iText.Kernel.XMP.Options;
namespace iText.Kernel.Pdf {
+ /// Main enter point to work with PDF document.
public class PdfDocument : IEventDispatcher, IDisposable {
/// Currently active page.
protected internal PdfPage currentPage = null;
@@ -238,6 +239,7 @@ public virtual byte[] GetXmpMetadata(bool createNew) {
XMPMeta xmpMeta = XMPMetaFactory.Create();
xmpMeta.SetObjectName(XMPConst.TAG_XMPMETA);
xmpMeta.SetObjectName("");
+ AddCustomMetadataExtensions(xmpMeta);
try {
xmpMeta.SetProperty(XMPConst.NS_DC, PdfConst.Format, "application/pdf");
xmpMeta.SetProperty(XMPConst.NS_PDF, PdfConst.Producer, Version.GetInstance().GetVersion());
@@ -249,6 +251,15 @@ public virtual byte[] GetXmpMetadata(bool createNew) {
return xmpMetadata;
}
+ /// Gets PdfObject by object number.
+ /// object number.
+ ///
+ ///
+ ///
+ /// or
+ ///
+ /// , if object not found.
+ ///
public virtual PdfObject GetPdfObject(int objNum) {
CheckClosingStatus();
PdfIndirectReference reference = xref.Get(objNum);
@@ -260,6 +271,8 @@ public virtual PdfObject GetPdfObject(int objNum) {
}
}
+ /// Get number of indirect objects in the document.
+ /// number of indirect objects.
public virtual int GetNumberOfPdfObjects() {
return xref.Size();
}
@@ -480,26 +493,32 @@ public virtual void SetDefaultPageSize(PageSize pageSize) {
defaultPageSize = pageSize;
}
+ ///
public virtual void AddEventHandler(String type, IEventHandler handler) {
eventDispatcher.AddEventHandler(type, handler);
}
+ ///
public virtual void DispatchEvent(Event @event) {
eventDispatcher.DispatchEvent(@event);
}
+ ///
public virtual void DispatchEvent(Event @event, bool delayed) {
eventDispatcher.DispatchEvent(@event, delayed);
}
+ ///
public virtual bool HasEventHandler(String type) {
return eventDispatcher.HasEventHandler(type);
}
+ ///
public virtual void RemoveEventHandler(String type, IEventHandler handler) {
eventDispatcher.RemoveEventHandler(type, handler);
}
+ ///
public virtual void RemoveAllHandlers() {
eventDispatcher.RemoveAllHandlers();
}
@@ -594,8 +613,7 @@ public virtual void Close() {
PdfObject crypto_1 = null;
if (properties.appendMode) {
if (structTreeRoot != null && structTreeRoot.GetPdfObject().IsModified()) {
- GetTagStructureContext().RemoveAllConnectionsToTags();
- structTreeRoot.Flush();
+ TryFlushTagStructure();
}
if (catalog.IsOCPropertiesMayHaveChanged() && catalog.GetOCProperties(false).GetPdfObject().IsModified()) {
catalog.GetOCProperties(false).Flush();
@@ -627,8 +645,7 @@ public virtual void Close() {
}
else {
if (structTreeRoot != null) {
- GetTagStructureContext().RemoveAllConnectionsToTags();
- structTreeRoot.Flush();
+ TryFlushTagStructure();
}
if (catalog.IsOCPropertiesMayHaveChanged()) {
catalog.GetPdfObject().Put(PdfName.OCProperties, catalog.GetOCProperties(false).GetPdfObject());
@@ -693,9 +710,6 @@ public virtual void Close() {
trailer.Put(PdfName.Info, info.GetPdfObject());
xref.WriteXrefTableAndTrailer(this, fileId, crypto_1);
writer.Flush();
- if (IsCloseWriter()) {
- writer.Close();
- }
Counter counter = GetCounter();
if (counter != null) {
counter.OnDocumentWritten(writer.GetCurrentPos());
@@ -703,20 +717,41 @@ public virtual void Close() {
}
catalog.GetPageTree().ClearPageRefs();
RemoveAllHandlers();
- if (reader != null && IsCloseReader()) {
- reader.Close();
- }
}
catch (System.IO.IOException e) {
throw new PdfException(PdfException.CannotCloseDocument, e, this);
}
+ finally {
+ if (writer != null && IsCloseWriter()) {
+ try {
+ writer.Close();
+ }
+ catch (Exception e) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
+ logger.Error(LogMessageConstant.PDF_WRITER_CLOSING_FAILED, e);
+ }
+ }
+ if (reader != null && IsCloseReader()) {
+ try {
+ reader.Close();
+ }
+ catch (Exception e) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
+ logger.Error(LogMessageConstant.PDF_READER_CLOSING_FAILED, e);
+ }
+ }
+ }
closed = true;
}
+ /// Gets close status of the document.
+ /// true, if the document has already been closed, otherwise false.
public virtual bool IsClosed() {
return closed;
}
+ /// Gets tagged status of the document.
+ /// true, if the document has tag structure, otherwise false.
public virtual bool IsTagged() {
return structTreeRoot != null;
}
@@ -736,11 +771,27 @@ public virtual void SetTagged() {
}
}
+ ///
+ /// Gets
+ ///
+ /// of tagged document.
+ ///
+ ///
+ ///
+ ///
+ /// in case tagged document, otherwise false.
+ ///
+ ///
+ ///
public virtual PdfStructTreeRoot GetStructTreeRoot() {
return structTreeRoot;
}
- public virtual int? GetNextStructParentIndex() {
+ /// Gets next parent index of tagged document.
+ /// -1 if document is not tagged, or >= 0 if tagged.
+ ///
+ ///
+ public virtual int GetNextStructParentIndex() {
return structParentIndex++;
}
@@ -778,7 +829,6 @@ public virtual TagStructureContext GetTagStructureContext() {
/// a document to copy pages to.
/// a position where to insert copied pages.
/// list of copied pages
- ///
public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel.Pdf.PdfDocument toDocument
, int insertBeforePage) {
return CopyPagesTo(pageFrom, pageTo, toDocument, insertBeforePage, null);
@@ -791,13 +841,12 @@ public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel
/// Use this method if you want to copy pages across tagged documents.
/// This will keep resultant PDF structure consistent.
///
- /// start of the range of pages to be copied.
- /// end of the range of pages to be copied.
+ /// 1-based start of the range of pages to be copied.
+ /// 1-based end of the range of pages to be copied.
/// a document to copy pages to.
/// a position where to insert copied pages.
/// a copier which bears a special copy logic. May be NULL
- /// list of copied pages
- ///
+ /// list of new copied pages
public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel.Pdf.PdfDocument toDocument
, int insertBeforePage, IPdfPageExtraCopier copier) {
IList pages = new List();
@@ -814,11 +863,10 @@ public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel
/// Use this method if you want to copy pages across tagged documents.
/// This will keep resultant PDF structure consistent.
///
- ///
- ///
- ///
- /// list of copied pages
- ///
+ /// 1-based start of the range of pages to be copied.
+ /// 1-based end of the range of pages to be copied.
+ /// a document to copy pages to.
+ /// list of new copied pages
public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel.Pdf.PdfDocument toDocument
) {
return CopyPagesTo(pageFrom, pageTo, toDocument, null);
@@ -831,12 +879,11 @@ public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel
/// Use this method if you want to copy pages across tagged documents.
/// This will keep resultant PDF structure consistent.
///
- ///
- ///
- ///
- /// a copier which bears a special copy logic. May be NULL
- /// list of copied pages
- ///
+ /// 1-based start of the range of pages to be copied.
+ /// 1-based end of the range of pages to be copied.
+ /// a document to copy pages to.
+ /// a copier which bears a special copy logic. May be null.
+ /// list of new copied pages.
public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel.Pdf.PdfDocument toDocument
, IPdfPageExtraCopier copier) {
return CopyPagesTo(pageFrom, pageTo, toDocument, toDocument.GetNumberOfPages() + 1, copier);
@@ -852,8 +899,7 @@ public virtual IList CopyPagesTo(int pageFrom, int pageTo, iText.Kernel
/// list of pages to be copied. TreeSet for the order of the pages to be natural.
/// a document to copy pages to.
/// a position where to insert copied pages.
- /// list of copied pages
- ///
+ /// list of new copied pages
public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.Pdf.PdfDocument toDocument,
int insertBeforePage) {
return CopyPagesTo(pagesToCopy, toDocument, insertBeforePage, null);
@@ -870,8 +916,7 @@ public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.P
/// a document to copy pages to.
/// a position where to insert copied pages.
/// a copier which bears a special copy logic. May be NULL
- /// list of copied pages
- ///
+ /// list of new copied pages
public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.Pdf.PdfDocument toDocument,
int insertBeforePage, IPdfPageExtraCopier copier) {
if (pagesToCopy.IsEmpty()) {
@@ -917,19 +962,30 @@ public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.P
// It's important to copy tag structure after link annotations were copied, because object content items in tag
// structure are not copied in case if their's OBJ key is annotation and doesn't contain /P entry.
if (toDocument.IsTagged()) {
- if (tagStructureContext != null) {
- tagStructureContext.ActualizeTagsProperties();
- }
- foreach (IDictionary increasingPagesRange in rangesOfPagesWithIncreasingNumbers) {
- if (insertInBetween) {
- GetStructTreeRoot().CopyTo(toDocument, insertBeforePage, increasingPagesRange);
+ if (IsTagged()) {
+ if (tagStructureContext != null) {
+ tagStructureContext.ActualizeTagsProperties();
}
- else {
- GetStructTreeRoot().CopyTo(toDocument, increasingPagesRange);
+ try {
+ foreach (IDictionary increasingPagesRange in rangesOfPagesWithIncreasingNumbers) {
+ if (insertInBetween) {
+ GetStructTreeRoot().CopyTo(toDocument, insertBeforePage, increasingPagesRange);
+ }
+ else {
+ GetStructTreeRoot().CopyTo(toDocument, increasingPagesRange);
+ }
+ insertBeforePage += increasingPagesRange.Count;
+ }
+ toDocument.GetTagStructureContext().NormalizeDocumentRootTag();
+ }
+ catch (Exception ex) {
+ throw new PdfException(PdfException.TagStructureCopyingFailedItMightBeCorruptedInOneOfTheDocuments, ex);
}
- insertBeforePage += increasingPagesRange.Count;
}
- toDocument.GetTagStructureContext().NormalizeDocumentRootTag();
+ else {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
+ logger.Warn(LogMessageConstant.NOT_TAGGED_PAGES_IN_TAGGED_DOCUMENT);
+ }
}
if (catalog.IsOutlineMode()) {
CopyOutlines(outlinesToCopy, toDocument, page2page);
@@ -947,7 +1003,6 @@ public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.P
/// list of pages to be copied. TreeSet for the order of the pages to be natural.
/// a document to copy pages to.
/// list of copied pages
- ///
public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.Pdf.PdfDocument toDocument) {
return CopyPagesTo(pagesToCopy, toDocument, null);
}
@@ -963,37 +1018,110 @@ public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.P
/// a document to copy pages to.
/// a copier which bears a special copy logic
/// list of copied pages
- ///
public virtual IList CopyPagesTo(IList pagesToCopy, iText.Kernel.Pdf.PdfDocument toDocument,
IPdfPageExtraCopier copier) {
return CopyPagesTo(pagesToCopy, toDocument, toDocument.GetNumberOfPages() + 1, copier);
}
+ ///
+ /// Checks, whether
+ ///
+ /// method will close associated PdfReader.
+ ///
+ ///
+ /// true,
+ ///
+ /// method is going to close associated PdfReader, otherwise false.
+ ///
public virtual bool IsCloseReader() {
return closeReader;
}
+ ///
+ /// Sets, whether
+ ///
+ /// method shall close associated PdfReader.
+ ///
+ ///
+ /// true,
+ ///
+ /// method shall close associated PdfReader, otherwise false.
+ ///
public virtual void SetCloseReader(bool closeReader) {
+ CheckClosingStatus();
this.closeReader = closeReader;
}
+ ///
+ /// Checks, whether
+ ///
+ /// method will close associated PdfWriter.
+ ///
+ ///
+ /// true,
+ ///
+ /// method is going to close associated PdfWriter, otherwise false.
+ ///
public virtual bool IsCloseWriter() {
return closeWriter;
}
+ ///
+ /// Sets, whether
+ ///
+ /// method shall close associated PdfWriter.
+ ///
+ ///
+ /// true,
+ ///
+ /// method shall close associated PdfWriter, otherwise false.
+ ///
public virtual void SetCloseWriter(bool closeWriter) {
+ CheckClosingStatus();
this.closeWriter = closeWriter;
}
+ ///
+ /// Checks, whether
+ ///
+ /// will flush unused objects,
+ /// e.g. unreachable from PDF Catalog. By default - false.
+ ///
+ ///
+ /// false, if
+ ///
+ /// shall not flush unused objects, otherwise true.
+ ///
public virtual bool IsFlushUnusedObjects() {
return flushUnusedObjects;
}
+ ///
+ /// Sets, whether
+ ///
+ /// shall flush unused objects,
+ /// e.g. unreachable from PDF Catalog.
+ ///
+ ///
+ /// false, if
+ ///
+ /// shall not flush unused objects, otherwise true.
+ ///
public virtual void SetFlushUnusedObjects(bool flushUnusedObjects) {
CheckClosingStatus();
this.flushUnusedObjects = flushUnusedObjects;
}
+ /// This method returns a complete outline tree of the whole document.
+ ///
+ /// if the flag is true, the method read the whole document and creates outline tree.
+ /// If false the method gets cached outline tree (if it was cached via calling getOutlines method before).
+ ///
+ ///
+ /// fully initialize
+ ///
+ /// object.
+ ///
public virtual PdfOutline GetOutlines(bool updateOutlines) {
CheckClosingStatus();
return catalog.GetOutlines(updateOutlines);
@@ -1011,14 +1139,14 @@ public virtual void InitializeOutlines() {
/// Name of the destination.
///
/// An object destination refers to. Must be an array or a dictionary with key /D and array.
- /// See PdfSpec 12.3.2.3 for more info.
+ /// See ISO 32000-1 12.3.2.3 for more info.
///
- ///
public virtual void AddNamedDestination(String key, PdfObject value) {
CheckClosingStatus();
catalog.AddNamedDestination(key, value);
}
+ /// Gets static copy of cross reference table.
public virtual IList ListIndirectReferences() {
CheckClosingStatus();
IList indRefs = new List(xref.Size());
@@ -1038,6 +1166,18 @@ public virtual PdfDictionary GetTrailer() {
return trailer;
}
+ ///
+ /// Adds
+ ///
+ /// that shall specify the colour characteristics of output devices
+ /// on which the document might be rendered.
+ ///
+ ///
+ ///
+ ///
+ /// to add.
+ ///
+ ///
public virtual void AddOutputIntent(PdfOutputIntent outputIntent) {
CheckClosingStatus();
if (outputIntent == null) {
@@ -1051,21 +1191,100 @@ public virtual void AddOutputIntent(PdfOutputIntent outputIntent) {
outputIntents.Add(outputIntent.GetPdfObject());
}
+ /// Checks whether PDF document conforms a specific standard.
+ ///
+ /// Checks whether PDF document conforms a specific standard.
+ /// Shall be override.
+ ///
+ /// An object to conform.
+ /// type of object to conform.
public virtual void CheckIsoConformance(Object obj, IsoKey key) {
}
+ /// Checks whether PDF document conforms a specific standard.
+ ///
+ /// Checks whether PDF document conforms a specific standard.
+ /// Shall be override.
+ ///
+ /// an object to conform.
+ /// type of object to conform.
+ ///
+ ///
+ ///
+ /// associated with an object to check.
+ ///
public virtual void CheckIsoConformance(Object obj, IsoKey key, PdfResources resources) {
}
+ /// Checks whether PDF document conforms a specific standard.
+ ///
+ /// Checks whether PDF document conforms a specific standard.
+ /// Shall be override.
+ ///
+ ///
+ /// a
+ ///
+ /// object to conform.
+ ///
+ ///
+ ///
+ ///
+ /// associated with an object to check.
+ ///
public virtual void CheckShowTextIsoConformance(Object gState, PdfResources resources) {
}
+ /// Adds file attachment at document level.
+ /// the file description
+ /// an array with the file.
+ /// the actual file name stored in the pdf
+ /// mime type of the file
+ /// the optional extra file parameters such as the creation or modification date
+ ///
+ /// if
+ ///
+ /// ,
+ ///
+ /// will be added. Shall be one of:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual void AddFileAttachment(String description, byte[] fileStore, String fileDisplay, PdfName mimeType
, PdfDictionary fileParameter, PdfName afRelationshipValue) {
AddFileAttachment(description, PdfFileSpec.CreateEmbeddedFileSpec(this, fileStore, description, fileDisplay
, mimeType, fileParameter, afRelationshipValue, true));
}
+ /// Adds file attachment at document level.
+ /// the file description
+ /// the path to the file.
+ /// the actual file name stored in the pdf
+ /// mime type of the file
+ ///
+ /// if
+ ///
+ /// ,
+ ///
+ /// will be added. Shall be one of:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
///
public virtual void AddFileAttachment(String description, String file, String fileDisplay, PdfName mimeType
, PdfName afRelationshipValue) {
@@ -1073,6 +1292,13 @@ public virtual void AddFileAttachment(String description, String file, String fi
, afRelationshipValue, true));
}
+ /// Adds file attachment at document level.
+ /// the file description
+ ///
+ ///
+ ///
+ /// object.
+ ///
public virtual void AddFileAttachment(String description, PdfFileSpec fs) {
CheckClosingStatus();
catalog.AddNameToNameTree(description, fs.GetPdfObject(), PdfName.EmbeddedFiles);
@@ -1190,10 +1416,26 @@ internal virtual PdfXrefTable GetXref() {
return xref;
}
+ ///
+ /// Initialize
+ ///
+ /// .
+ ///
protected internal virtual void InitTagStructureContext() {
tagStructureContext = new TagStructureContext(this);
}
+ /// Save the link annotation in a temporary storage for further copying.
+ ///
+ /// just copied
+ ///
+ /// link annotation belongs to.
+ ///
+ ///
+ ///
+ ///
+ /// itself.
+ ///
protected internal virtual void StoreLinkAnnotation(PdfPage page, PdfLinkAnnotation annotation) {
IList pageAnnotations = linkAnnotations.Get(page);
if (pageAnnotations == null) {
@@ -1203,16 +1445,30 @@ protected internal virtual void StoreLinkAnnotation(PdfPage page, PdfLinkAnnotat
pageAnnotations.Add(annotation);
}
+ /// Checks whether PDF document conforms a specific standard.
+ ///
+ /// Checks whether PDF document conforms a specific standard.
+ /// Shall be override.
+ ///
protected internal virtual void CheckIsoConformance() {
}
+ ///
+ /// Mark an object with
+ ///
+ /// .
+ ///
+ /// an object to mark.
protected internal virtual void MarkObjectAsMustBeFlushed(PdfObject pdfObject) {
if (pdfObject.IsIndirect()) {
pdfObject.GetIndirectReference().SetState(PdfObject.MUST_BE_FLUSHED);
}
}
- ///
+ /// Flush an object.
+ /// object to flush.
+ /// indicates whether object can be placed into object stream.
+ /// on error.
protected internal virtual void FlushObject(PdfObject pdfObject, bool canBeInObjStm) {
writer.FlushObject(pdfObject, canBeInObjStm);
}
@@ -1224,7 +1480,6 @@ protected internal virtual void FlushObject(PdfObject pdfObject, bool canBeInObj
///
/// otherwise
///
- ///
protected internal virtual void Open(PdfVersion newPdfVersion) {
try {
if (reader != null) {
@@ -1260,8 +1515,7 @@ protected internal virtual void Open(PdfVersion newPdfVersion) {
);
PdfDictionary str = catalog.GetPdfObject().GetAsDictionary(PdfName.StructTreeRoot);
if (str != null) {
- structTreeRoot = new PdfStructTreeRoot(str);
- structParentIndex = GetStructTreeRoot().GetParentTreeNextKey();
+ TryInitTagStructure(str);
}
if (properties.appendMode && (reader.HasRebuiltXref() || reader.HasFixedXref())) {
throw new PdfException(PdfException.AppendModeRequiresADocumentWithoutErrorsEvenIfRecoveryWasPossible);
@@ -1358,6 +1612,21 @@ protected internal virtual void Open(PdfVersion newPdfVersion) {
}
}
+ /// Adds custom XMP metadata extension.
+ /// Adds custom XMP metadata extension. Useful for PDF/UA, ZUGFeRD, etc.
+ ///
+ ///
+ ///
+ /// to add custom metadata to.
+ ///
+ protected internal virtual void AddCustomMetadataExtensions(XMPMeta xmpMeta) {
+ }
+
+ /// Updates XMP metadata.
+ ///
+ /// Updates XMP metadata.
+ /// Shall be override.
+ ///
protected internal virtual void UpdateXmpMetadata() {
try {
if (writer.properties.addXmpMetadata) {
@@ -1370,6 +1639,11 @@ protected internal virtual void UpdateXmpMetadata() {
}
}
+ ///
+ /// Update XMP metadata values from
+ ///
+ /// .
+ ///
///
protected internal virtual XMPMeta UpdateDefaultXmpMetadata() {
XMPMeta xmpMeta = XMPMetaFactory.ParseFromBuffer(GetXmpMetadata(true));
@@ -1456,7 +1730,8 @@ protected internal virtual ICollection GetDocumentFonts() {
protected internal virtual void FlushFonts() {
if (properties.appendMode) {
foreach (PdfFont font in GetDocumentFonts()) {
- if (font.GetPdfObject().GetIndirectReference().CheckState(PdfObject.MODIFIED)) {
+ if (font.GetPdfObject().CheckState(PdfObject.MUST_BE_INDIRECT) || font.GetPdfObject().GetIndirectReference
+ ().CheckState(PdfObject.MODIFIED)) {
font.Flush();
}
}
@@ -1468,6 +1743,13 @@ protected internal virtual void FlushFonts() {
}
}
+ /// Checks page before adding and add.
+ /// one-base index of the page.
+ ///
+ ///
+ ///
+ /// to add.
+ ///
protected internal virtual void CheckAndAddPage(int index, PdfPage page) {
if (page.IsFlushed()) {
throw new PdfException(PdfException.FlushedPageCannotBeAddedOrInserted, page);
@@ -1479,6 +1761,12 @@ protected internal virtual void CheckAndAddPage(int index, PdfPage page) {
catalog.GetPageTree().AddPage(index, page);
}
+ /// Checks page before adding.
+ ///
+ ///
+ ///
+ /// to add.
+ ///
protected internal virtual void CheckAndAddPage(PdfPage page) {
if (page.IsFlushed()) {
throw new PdfException(PdfException.FlushedPageCannotBeAddedOrInserted, page);
@@ -1491,19 +1779,51 @@ protected internal virtual void CheckAndAddPage(PdfPage page) {
}
/// checks whether a method is invoked at the closed document
- ///
protected internal virtual void CheckClosingStatus() {
if (closed) {
- throw new PdfException(PdfException.DocumentClosedImpossibleExecuteAction);
+ throw new PdfException(PdfException.DocumentClosedItIsImpossibleToExecuteAction);
}
}
+ ///
+ /// Gets
+ ///
+ /// instance.
+ ///
+ ///
+ ///
+ ///
+ /// instance.
+ ///
protected internal virtual Counter GetCounter() {
return CounterFactory.GetCounter(typeof(iText.Kernel.Pdf.PdfDocument));
}
+ private void TryInitTagStructure(PdfDictionary str) {
+ try {
+ structTreeRoot = new PdfStructTreeRoot(str);
+ structParentIndex = GetStructTreeRoot().GetParentTreeNextKey();
+ }
+ catch (Exception ex) {
+ structTreeRoot = null;
+ structParentIndex = -1;
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfDocument));
+ logger.Error(LogMessageConstant.TAG_STRUCTURE_INIT_FAILED, ex);
+ }
+ }
+
+ private void TryFlushTagStructure() {
+ try {
+ GetTagStructureContext().RemoveAllConnectionsToTags();
+ structTreeRoot.Flush();
+ }
+ catch (Exception ex) {
+ throw new PdfException(PdfException.TagStructureFlushingFailedItMightBeCorrupted, ex);
+ }
+ }
+
/// This method removes all annotation entries from form fields associated with a given page.
- ///
+ /// to remove from.
private void RemoveUnusedWidgetsFromFields(PdfPage page) {
if (page.IsFlushed()) {
return;
@@ -1522,7 +1842,7 @@ private void CopyLinkAnnotations(iText.Kernel.Pdf.PdfDocument toDocument, IDicti
excludedKeys.Add(PdfName.Dest);
excludedKeys.Add(PdfName.A);
foreach (KeyValuePair> entry in linkAnnotations) {
- // We don't want to copy those link annotations, which reference to not copied pages.
+ // We don't want to copy those link annotations, which reference to pages which weren't copied.
foreach (PdfLinkAnnotation annot in entry.Value) {
bool toCopyAnnot = true;
PdfDestination copiedDest = null;
@@ -1558,14 +1878,14 @@ private void CopyLinkAnnotations(iText.Kernel.Pdf.PdfDocument toDocument, IDicti
}
if (toCopyAnnot) {
PdfLinkAnnotation newAnnot = (PdfLinkAnnotation)PdfAnnotation.MakeAnnotation(annot.GetPdfObject().CopyTo(toDocument
- , excludedKeys, false));
+ , excludedKeys, true));
if (copiedDest != null) {
newAnnot.SetDestination(copiedDest);
}
if (copiedAction != null) {
newAnnot.SetAction(copiedAction);
}
- page2page.Get(entry.Key).AddAnnotation(-1, newAnnot, false);
+ entry.Key.AddAnnotation(-1, newAnnot, false);
}
}
}
@@ -1575,7 +1895,6 @@ private void CopyLinkAnnotations(iText.Kernel.Pdf.PdfDocument toDocument, IDicti
/// This method copies all given outlines
/// outlines to be copied
/// document where outlines should be copied
- ///
private void CopyOutlines(ICollection outlines, iText.Kernel.Pdf.PdfDocument toDocument, IDictionary
page2page) {
ICollection outlinesToCopy = new HashSet();
@@ -1609,7 +1928,6 @@ private void GetAllOutlinesToCopy(PdfOutline outline, ICollection ou
/// - Set of outlines to be copied
/// - new parent outline
/// - old parent outline
- ///
private void CloneOutlines(ICollection outlinesToCopy, PdfOutline newParent, PdfOutline oldParent
, IDictionary page2page, iText.Kernel.Pdf.PdfDocument toDocument) {
if (null == oldParent) {
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs b/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
index dd24ccd041..f15785fa9f 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfEncryption.cs
@@ -261,7 +261,7 @@ public static byte[] GenerateNewDocumentId() {
long time = SystemUtil.GetSystemTimeTicks();
long mem = SystemUtil.GetFreeMemory();
String s = time + "+" + mem + "+" + (seq++);
- return md5.Digest(s.GetBytes());
+ return md5.Digest(s.GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1));
}
public static PdfObject CreateInfoId(byte[] id, bool modified) {
@@ -371,6 +371,21 @@ public virtual byte[] ComputeUserPassword(byte[] ownerPassword) {
return userPassword;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfIndirectReference.cs b/itext/itext.kernel/itext/kernel/pdf/PdfIndirectReference.cs
index 525b2539d8..7cf6ce4d2e 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfIndirectReference.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfIndirectReference.cs
@@ -231,8 +231,8 @@ public override String ToString() {
if (CheckState(READ_ONLY)) {
states.Append("ReadOnly; ");
}
- return String.Format("{0} {1} R{2}", GetObjNumber(), GetGenNumber(), states.JSubstring(0, states.Length -
- 1));
+ return String.Format("{0} {1} R{2}", iText.IO.Util.JavaUtil.IntegerToString(GetObjNumber()), iText.IO.Util.JavaUtil.IntegerToString
+ (GetGenNumber()), states.JSubstring(0, states.Length - 1));
}
/// Gets a PdfWriter associated with the document object belongs to.
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfLiteral.cs b/itext/itext.kernel/itext/kernel/pdf/PdfLiteral.cs
index 1648cb13db..e22c364889 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfLiteral.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfLiteral.cs
@@ -94,6 +94,15 @@ public virtual int GetBytesCount() {
protected internal override void GenerateContent() {
}
+ public override bool Equals(Object o) {
+ return this == o || o != null && GetType() == o.GetType() && iText.IO.Util.JavaUtil.ArraysEquals(content,
+ ((iText.Kernel.Pdf.PdfLiteral)o).content);
+ }
+
+ public override int GetHashCode() {
+ return content == null ? 0 : iText.IO.Util.JavaUtil.ArraysHashCode(content);
+ }
+
protected internal override PdfObject NewInstance() {
return new iText.Kernel.Pdf.PdfLiteral();
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfName.cs b/itext/itext.kernel/itext/kernel/pdf/PdfName.cs
index b8cf87f09e..fa79341fdc 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfName.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfName.cs
@@ -271,6 +271,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Btn = CreateDirectName("Btn");
+ public static readonly iText.Kernel.Pdf.PdfName Butt = CreateDirectName("Butt");
+
public static readonly iText.Kernel.Pdf.PdfName ByteRange = CreateDirectName("ByteRange");
public static readonly iText.Kernel.Pdf.PdfName C = CreateDirectName("C");
@@ -456,6 +458,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName DeviceRGBK = CreateDirectName("DeviceRGBK");
+ public static readonly iText.Kernel.Pdf.PdfName Diamond = CreateDirectName("Diamond");
+
public static readonly iText.Kernel.Pdf.PdfName Difference = CreateDirectName("Difference");
public static readonly iText.Kernel.Pdf.PdfName Differences = CreateDirectName("Differences");
@@ -619,6 +623,20 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName FixedPrint = CreateDirectName("FixedPrint");
+ /// PdfName for the abbreviation of FlateDecode.
+ ///
+ /// PdfName for the abbreviation of FlateDecode. For the Flatness Tolerance PdfName use
+ ///
+ /// (Uppercase 'L')
+ ///
+ public static readonly iText.Kernel.Pdf.PdfName Fl = CreateDirectName("Fl");
+
+ /// PdfName for Flatness Tolerance.
+ ///
+ /// PdfName for Flatness Tolerance. For the PdfName with the FlateDecode abbreviation use
+ ///
+ /// (Lowercase 'L')
+ ///
public static readonly iText.Kernel.Pdf.PdfName FL = CreateDirectName("FL");
public static readonly iText.Kernel.Pdf.PdfName Flags = CreateDirectName("Flags");
@@ -865,6 +883,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName LJ = CreateDirectName("LJ");
+ public static readonly iText.Kernel.Pdf.PdfName LL = CreateDirectName("LL");
+
public static readonly iText.Kernel.Pdf.PdfName LLE = CreateDirectName("LLE");
public static readonly iText.Kernel.Pdf.PdfName LLO = CreateDirectName("LLO");
@@ -897,6 +917,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Markup = CreateDirectName("Markup");
+ public static readonly iText.Kernel.Pdf.PdfName Markup3D = CreateDirectName("Markup3D");
+
public static readonly iText.Kernel.Pdf.PdfName MarkStyle = CreateDirectName("MarkStyle");
public static readonly iText.Kernel.Pdf.PdfName Mask = CreateDirectName("Mask");
@@ -1098,10 +1120,14 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName PatternType = CreateDirectName("PatternType");
+ public static readonly iText.Kernel.Pdf.PdfName Pause = CreateDirectName("Pause");
+
public static readonly iText.Kernel.Pdf.PdfName Perceptual = CreateDirectName("Perceptual");
public static readonly iText.Kernel.Pdf.PdfName Perms = CreateDirectName("Perms");
+ public static readonly iText.Kernel.Pdf.PdfName PC = CreateDirectName("PC");
+
public static readonly iText.Kernel.Pdf.PdfName PCM = CreateDirectName("PCM");
public static readonly iText.Kernel.Pdf.PdfName Pdf_Version_1_2 = CreateDirectName("1.2");
@@ -1118,10 +1144,16 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Pg = CreateDirectName("Pg");
+ public static readonly iText.Kernel.Pdf.PdfName PI = CreateDirectName("PI");
+
public static readonly iText.Kernel.Pdf.PdfName PickTrayByPDFSize = CreateDirectName("PickTrayByPDFSize");
public static readonly iText.Kernel.Pdf.PdfName Placement = CreateDirectName("Placement");
+ public static readonly iText.Kernel.Pdf.PdfName Play = CreateDirectName("Play");
+
+ public static readonly iText.Kernel.Pdf.PdfName PO = CreateDirectName("PO");
+
public static readonly iText.Kernel.Pdf.PdfName Polygon = CreateDirectName("Polygon");
public static readonly iText.Kernel.Pdf.PdfName PolyLine = CreateDirectName("PolyLine");
@@ -1168,6 +1200,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Pushpin = CreateDirectName("PushPin");
+ public static readonly iText.Kernel.Pdf.PdfName PV = CreateDirectName("PV");
+
public static readonly iText.Kernel.Pdf.PdfName Q = CreateDirectName("Q");
public static readonly iText.Kernel.Pdf.PdfName Quote = CreateDirectName("Quote");
@@ -1190,6 +1224,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName RC = CreateDirectName("RC");
+ public static readonly iText.Kernel.Pdf.PdfName RClosedArrow = CreateDirectName("RClosedArrow");
+
public static readonly iText.Kernel.Pdf.PdfName RD = CreateDirectName("RD");
public static readonly iText.Kernel.Pdf.PdfName Reason = CreateDirectName("Reason");
@@ -1215,6 +1251,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName ResetForm = CreateDirectName("ResetForm");
+ public static readonly iText.Kernel.Pdf.PdfName Resume = CreateDirectName("Resume");
+
public static readonly iText.Kernel.Pdf.PdfName Requirements = CreateDirectName("Requirements");
public static readonly iText.Kernel.Pdf.PdfName Resources = CreateDirectName("Resources");
@@ -1231,6 +1269,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName RoleMap = CreateDirectName("RoleMap");
+ public static readonly iText.Kernel.Pdf.PdfName ROpenArrow = CreateDirectName("ROpenArrow");
+
public static readonly iText.Kernel.Pdf.PdfName Root = CreateDirectName("Root");
public static readonly iText.Kernel.Pdf.PdfName Rotate = CreateDirectName("Rotate");
@@ -1296,6 +1336,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Size = CreateDirectName("Size");
+ public static readonly iText.Kernel.Pdf.PdfName Slash = CreateDirectName("Slash");
+
public static readonly iText.Kernel.Pdf.PdfName SM = CreateDirectName("SM");
public static readonly iText.Kernel.Pdf.PdfName SMask = CreateDirectName("SMask");
@@ -1344,6 +1386,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName StemH = CreateDirectName("StemH");
+ public static readonly iText.Kernel.Pdf.PdfName Stop = CreateDirectName("Stop");
+
public static readonly iText.Kernel.Pdf.PdfName Stm = CreateDirectName("Stm");
public static readonly iText.Kernel.Pdf.PdfName StmF = CreateDirectName("StmF");
@@ -1439,6 +1483,10 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName TOCI = CreateDirectName("TOCI");
+ public static readonly iText.Kernel.Pdf.PdfName Toggle = CreateDirectName("Toggle");
+
+ public static readonly iText.Kernel.Pdf.PdfName Top = CreateDirectName("Top");
+
public static readonly iText.Kernel.Pdf.PdfName TopSecret = CreateDirectName("TopSecret");
public static readonly iText.Kernel.Pdf.PdfName ToUnicode = CreateDirectName("ToUnicode");
@@ -1561,6 +1609,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName Watermark = CreateDirectName("Watermark");
+ public static readonly iText.Kernel.Pdf.PdfName WC = CreateDirectName("WC");
+
public static readonly iText.Kernel.Pdf.PdfName WhitePoint = CreateDirectName("WhitePoint");
public static readonly iText.Kernel.Pdf.PdfName Width = CreateDirectName("Width");
@@ -1577,6 +1627,8 @@ public class PdfName : PdfPrimitiveObject, IComparable
public static readonly iText.Kernel.Pdf.PdfName WP = CreateDirectName("WP");
+ public static readonly iText.Kernel.Pdf.PdfName WS = CreateDirectName("WS");
+
public static readonly iText.Kernel.Pdf.PdfName WT = CreateDirectName("WT");
public static readonly iText.Kernel.Pdf.PdfName X = CreateDirectName("X");
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfNull.cs b/itext/itext.kernel/itext/kernel/pdf/PdfNull.cs
index 859fd89f2e..b4a6d3c9ec 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfNull.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfNull.cs
@@ -120,5 +120,13 @@ protected internal override PdfObject NewInstance() {
protected internal override void CopyContent(PdfObject from, PdfDocument document) {
}
+
+ public override bool Equals(Object obj) {
+ return this == obj || obj != null && GetType() == obj.GetType();
+ }
+
+ public override int GetHashCode() {
+ return 0;
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfNumber.cs b/itext/itext.kernel/itext/kernel/pdf/PdfNumber.cs
index 9829ad17bc..b04d6b91fc 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfNumber.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfNumber.cs
@@ -42,6 +42,8 @@ source product.
address: sales@itextpdf.com
*/
using System;
+using iText.IO;
+using iText.IO.Log;
using iText.IO.Source;
namespace iText.Kernel.Pdf {
@@ -50,6 +52,8 @@ public class PdfNumber : PdfPrimitiveObject {
private bool isDouble;
+ private bool changed = false;
+
public PdfNumber(double value)
: base() {
SetValue(value);
@@ -101,6 +105,7 @@ public virtual void SetValue(int value) {
this.value = value;
this.isDouble = false;
this.content = null;
+ this.changed = true;
}
public virtual void SetValue(double value) {
@@ -172,6 +177,22 @@ public override String ToString() {
}
}
+ public override bool Equals(Object o) {
+ return this == o || o != null && GetType() == o.GetType() && iText.IO.Util.JavaUtil.DoubleCompare(((iText.Kernel.Pdf.PdfNumber
+ )o).value, value) == 0;
+ }
+
+ public override int GetHashCode() {
+ if (changed) {
+ //if the instance was modified, hashCode also will be changed, it may cause inconsistency.
+ ILogger logger = LoggerFactory.GetLogger(typeof(PdfReader));
+ logger.Warn(LogMessageConstant.CALCULATE_HASHCODE_FOR_MODIFIED_PDFNUMBER);
+ changed = false;
+ }
+ long hash = iText.IO.Util.JavaUtil.DoubleToLongBits(value);
+ return (int)(hash ^ ((long)(((ulong)hash) >> 32)));
+ }
+
protected internal override PdfObject NewInstance() {
return new iText.Kernel.Pdf.PdfNumber();
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfObject.cs b/itext/itext.kernel/itext/kernel/pdf/PdfObject.cs
index 011b32f380..235ac28d12 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfObject.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfObject.cs
@@ -117,21 +117,24 @@ public abstract class PdfObject {
public abstract byte GetObjectType();
/// Flushes the object to the document.
- ///
public void Flush() {
Flush(true);
}
/// Flushes the object to the document.
/// indicates whether object can be placed into object stream.
- ///
public void Flush(bool canBeInObjStm) {
if (IsFlushed() || GetIndirectReference() == null) {
+ // TODO here we should take into account and log the case when object is MustBeIndirect, but has no indirect reference
+ // TODO DEVSIX-744
// Logger logger = LoggerFactory.getLogger(PdfObject.class);
// if (isFlushed()) {
// logger.warn("Meaningless call, the object has already flushed");
+ // } else if (isIndirect()){
+ // logger.warn("Meaningless call, the object will be transformed into indirect on closing, but at the moment it doesn't have an indirect reference and therefore couldn't be flushed. " +
+ // "To flush it now call makeIndirect(PdfDocument) method before calling flush() method.");
// } else {
- // logger.warn("Meaningless call, the object is direct object.");
+ // logger.warn("Meaningless call, the object is direct object. It will be flushed along with the indirect object that contains it.");
// }
return;
}
@@ -268,9 +271,10 @@ public virtual PdfObject CopyTo(PdfDocument document) {
/// copied object.
public virtual PdfObject CopyTo(PdfDocument document, bool allowDuplicating) {
if (document == null) {
- throw new PdfException(PdfException.DocumentToCopyToCannotBeNull);
+ throw new PdfException(PdfException.DocumentForCopyToCannotBeNull);
}
if (indirectReference != null) {
+ // TODO checkState(MUST_BE_INDIRECT) now is always false, because indirectReference != null. See also DEVSIX-602
if (indirectReference.GetWriter() != null || CheckState(MUST_BE_INDIRECT)) {
throw new PdfException(PdfException.CannotCopyIndirectObjectFromTheDocumentThatIsBeingWritten);
}
@@ -448,6 +452,7 @@ protected internal virtual void CopyContent(PdfObject from, PdfDocument document
///
copying to the other document
///
cloning inside of the current document
///
+ ///
/// This two cases are distinguished by the state of document parameter:
/// the second case is processed if document is null.
///
@@ -481,5 +486,13 @@ internal virtual PdfObject ProcessCopying(PdfDocument documentTo, bool allowDupl
return obj.Clone();
}
}
+
+ internal static bool EqualContent(PdfObject obj1, PdfObject obj2) {
+ PdfObject direct1 = obj1 != null && obj1.IsIndirectReference() ? ((PdfIndirectReference)obj1).GetRefersTo(
+ true) : obj1;
+ PdfObject direct2 = obj2 != null && obj2.IsIndirectReference() ? ((PdfIndirectReference)obj2).GetRefersTo(
+ true) : obj2;
+ return direct1 != null && direct1.Equals(direct2);
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfObjectStream.cs b/itext/itext.kernel/itext/kernel/pdf/PdfObjectStream.cs
index 5512f37cf9..d3610f1444 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfObjectStream.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfObjectStream.cs
@@ -57,7 +57,8 @@ internal class PdfObjectStream : PdfStream {
public PdfObjectStream(PdfDocument doc)
: base() {
- MakeIndirect(doc);
+ //avoid reuse existed references
+ MakeIndirect(doc, doc.GetXref().CreateNewIndirectReference(doc));
GetOutputStream().document = doc;
Put(PdfName.Type, PdfName.ObjStm);
Put(PdfName.N, size);
@@ -82,7 +83,6 @@ internal PdfObjectStream(iText.Kernel.Pdf.PdfObjectStream prev)
/// Adds object to the object stream.
/// object to add.
- ///
public virtual void AddObject(PdfObject @object) {
if (size.IntValue() == MAX_OBJ_STREAM_SIZE) {
throw new PdfException(PdfException.PdfObjectStreamReachMaxSize);
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfOutline.cs b/itext/itext.kernel/itext/kernel/pdf/PdfOutline.cs
index 7f53d13ec3..1b2ed57012 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfOutline.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfOutline.cs
@@ -49,9 +49,15 @@ source product.
using iText.Kernel.Pdf.Navigation;
namespace iText.Kernel.Pdf {
+ ///
+ /// Document outline object
+ /// See ISO-320001, 12.3.3 Document Outline.
+ ///
public class PdfOutline {
+ /// A flag for displaying the outline item’s text with italic font.
public static int FLAG_ITALIC = 1;
+ /// A flag for displaying the outline item’s text with bold font.
public static int FLAG_BOLD = 2;
private IList children = new List();
@@ -66,12 +72,27 @@ public class PdfOutline {
private PdfDocument pdfDoc;
+ /// Create instance of document outline.
+ /// the text that shall be displayed on the screen for this item.
+ /// Outline dictionary
+ ///
+ ///
+ ///
+ /// the outline belongs to.
+ ///
+ [System.ObsoleteAttribute(@"Use PdfCatalog.GetOutlines(bool) instead.")]
public PdfOutline(String title, PdfDictionary content, PdfDocument pdfDocument) {
this.title = title;
this.content = content;
this.pdfDoc = pdfDocument;
}
+ /// Create instance of document outline.
+ /// the text that shall be displayed on the screen for this item.
+ /// Outline dictionary
+ /// parent outline.
+ [System.ObsoleteAttribute(@"Use PdfCatalog.GetNextItem(PdfDictionary, PdfOutline, System.Collections.Generic.IDictionary{K, V}) ,AddOutline(System.String, int) and AddOutline(System.String) instead."
+ )]
public PdfOutline(String title, PdfDictionary content, iText.Kernel.Pdf.PdfOutline parent) {
this.title = title;
this.content = content;
@@ -81,8 +102,11 @@ public PdfOutline(String title, PdfDictionary content, iText.Kernel.Pdf.PdfOutli
}
/// This constructor creates root outline in the document.
- ///
- ///
+ ///
+ ///
+ ///
+ ///
+ [System.ObsoleteAttribute(@"Use PdfCatalog.GetOutlines(bool) instead.")]
protected internal PdfOutline(PdfDocument doc) {
content = new PdfDictionary();
content.Put(PdfName.Type, PdfName.Outlines);
@@ -91,74 +115,170 @@ protected internal PdfOutline(PdfDocument doc) {
doc.GetCatalog().AddRootOutline(this);
}
+ /// Gets title of the outline.
+ /// String value.
public virtual String GetTitle() {
return title;
}
+ ///
+ /// Sets title of the outline with
+ ///
+ /// encoding,
+ /// Title
+ /// key.
+ ///
+ /// String value.
public virtual void SetTitle(String title) {
this.title = title;
this.content.Put(PdfName.Title, new PdfString(title, PdfEncodings.UNICODE_BIG));
}
+ ///
+ /// Sets color for the outline entry’s text,
+ /// C
+ /// key.
+ ///
+ ///
+ ///
+ ///
+ ///
public virtual void SetColor(Color color) {
content.Put(PdfName.C, new PdfArray(color.GetColorValue()));
}
+ ///
+ /// Sets text style for the outline entry’s text,
+ /// F
+ /// key.
+ ///
+ ///
+ /// Could be either
+ ///
+ /// or
+ ///
+ /// . Default value is
+ /// 0
+ /// .
+ ///
public virtual void SetStyle(int style) {
if (style == FLAG_BOLD || style == FLAG_ITALIC) {
content.Put(PdfName.F, new PdfNumber(style));
}
}
+ /// Gets content dictionary.
+ ///
+ ///
+ ///
+ /// .
+ ///
public virtual PdfDictionary GetContent() {
return content;
}
+ /// Gets list of children outlines.
+ ///
+ /// List of
+ ///
+ /// .
+ ///
public virtual IList GetAllChildren() {
return children;
}
+ /// Gets parent outline.
+ ///
+ ///
+ ///
+ /// .
+ ///
public virtual iText.Kernel.Pdf.PdfOutline GetParent() {
return parent;
}
+ ///
+ /// Gets
+ ///
+ /// .
+ ///
+ ///
+ ///
+ ///
+ /// .
+ ///
public virtual PdfDestination GetDestination() {
return destination;
}
+ ///
+ /// Adds
+ ///
+ /// for the outline,
+ /// Dest
+ /// key.
+ ///
+ ///
+ /// instance of
+ ///
+ /// .
+ ///
public virtual void AddDestination(PdfDestination destination) {
SetDestination(destination);
content.Put(PdfName.Dest, destination.GetPdfObject());
}
+ ///
+ /// Adds
+ ///
+ /// for the outline,
+ /// A
+ /// key.
+ ///
+ ///
+ /// instance of
+ ///
+ /// .
+ ///
public virtual void AddAction(PdfAction action) {
content.Put(PdfName.A, action.GetPdfObject());
}
- ///
- /// Adds an PdfOutline as a child to existing PdfOutline
- /// and put it in the end of the existing PdfOutline children list
- ///
- /// an outline title
- /// a created outline
- ///
- public virtual iText.Kernel.Pdf.PdfOutline AddOutline(String title) {
- return AddOutline(title, -1);
+ /// Defines if the outline needs to be closed or not.
+ ///
+ /// Defines if the outline needs to be closed or not.
+ /// By default, outlines are open.
+ ///
+ /// if false, the outline will be closed by default
+ public virtual void SetOpen(bool open) {
+ if (!open) {
+ content.Put(PdfName.Count, new PdfNumber(-1));
+ }
+ else {
+ if (children.Count > 0) {
+ content.Put(PdfName.Count, new PdfNumber(children.Count));
+ }
+ else {
+ content.Remove(PdfName.Count);
+ }
+ }
}
///
- /// Adds an
+ /// Adds a new
/// PdfOutline
- /// as a child to existing PdfOutline
- /// and put it to specified position in the existing PdfOutline children list
+ /// with specified parameters as a child to existing
+ /// PdfOutline
+ /// and put it to specified position in the existing
+ /// PdfOutline
+ /// children list.
///
/// an outline title
///
/// a position in the current outline child List where a new outline should be added.
/// If the position equals -1, then the outline will be put in the end of children list.
///
- /// created outline
- ///
+ /// just created outline
public virtual iText.Kernel.Pdf.PdfOutline AddOutline(String title, int position) {
if (position == -1) {
position = children.Count;
@@ -185,32 +305,70 @@ public virtual iText.Kernel.Pdf.PdfOutline AddOutline(String title, int position
if (position == children.Count) {
content.Put(PdfName.Last, dictionary);
}
- if (children.Count > 0) {
- int count = (int)this.content.GetAsInt(PdfName.Count);
- if (count > 0) {
- content.Put(PdfName.Count, new PdfNumber(count++));
- }
- else {
- content.Put(PdfName.Count, new PdfNumber(count--));
- }
- }
- else {
- this.content.Put(PdfName.Count, new PdfNumber(-1));
+ PdfNumber count = this.content.GetAsNumber(PdfName.Count);
+ if (count == null || count.GetValue() != -1) {
+ content.Put(PdfName.Count, new PdfNumber(children.Count + 1));
}
children.Add(position, outline);
return outline;
}
+ ///
+ /// Adds an
+ /// PdfOutline
+ /// as a child to existing
+ /// PdfOutline
+ /// and put it in the end of the existing
+ /// PdfOutline
+ /// children list.
+ ///
+ /// an outline title
+ /// just created outline
+ public virtual iText.Kernel.Pdf.PdfOutline AddOutline(String title) {
+ return AddOutline(title, -1);
+ }
+
+ ///
+ /// Adds an
+ /// PdfOutline
+ /// as a child to existing
+ /// PdfOutline
+ /// and put it to the end of the existing
+ /// PdfOutline
+ /// children list.
+ ///
+ /// an outline to add.
+ /// just created outline
+ public virtual iText.Kernel.Pdf.PdfOutline AddOutline(iText.Kernel.Pdf.PdfOutline outline) {
+ iText.Kernel.Pdf.PdfOutline newOutline = AddOutline(outline.GetTitle());
+ newOutline.AddDestination(outline.GetDestination());
+ IList children = outline.GetAllChildren();
+ foreach (iText.Kernel.Pdf.PdfOutline child in children) {
+ newOutline.AddOutline(child);
+ }
+ return newOutline;
+ }
+
+ /// Clear list of children.
internal virtual void Clear() {
children.Clear();
}
+ ///
+ /// Sets
+ ///
+ /// .
+ ///
+ ///
+ /// instance of
+ ///
+ /// .
+ ///
internal virtual void SetDestination(PdfDestination destination) {
this.destination = destination;
}
- /// remove this outline from the document.
- ///
+ /// Remove this outline from the document.
internal virtual void RemoveOutline() {
PdfName type = content.GetAsName(PdfName.Type);
if (type != null && type.Equals(PdfName.Outlines)) {
@@ -246,15 +404,5 @@ internal virtual void RemoveOutline() {
}
}
}
-
- public virtual iText.Kernel.Pdf.PdfOutline AddOutline(iText.Kernel.Pdf.PdfOutline outline) {
- iText.Kernel.Pdf.PdfOutline newOutline = AddOutline(outline.GetTitle());
- newOutline.AddDestination(outline.GetDestination());
- IList children = outline.GetAllChildren();
- foreach (iText.Kernel.Pdf.PdfOutline child in children) {
- newOutline.AddOutline(child);
- }
- return newOutline;
- }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfOutputIntent.cs b/itext/itext.kernel/itext/kernel/pdf/PdfOutputIntent.cs
index 146ce11e27..77ebb470ae 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfOutputIntent.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfOutputIntent.cs
@@ -46,6 +46,10 @@ source product.
using iText.Kernel.Pdf.Colorspace;
namespace iText.Kernel.Pdf {
+ ///
+ /// Specify the colour characteristics of output devices on which the document might be rendered
+ /// See ISO 32000-1 14.11.5: Output Intents.
+ ///
public class PdfOutputIntent : PdfObjectWrapper {
/// Creates output intent dictionary.
///
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfOutputStream.cs b/itext/itext.kernel/itext/kernel/pdf/PdfOutputStream.cs
index c9dcca9564..1997cbe05f 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfOutputStream.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfOutputStream.cs
@@ -42,7 +42,6 @@ source product.
address: sales@itextpdf.com
*/
using System;
-using System.Collections.Generic;
using System.IO;
using iText.IO;
using iText.IO.Log;
@@ -156,13 +155,13 @@ private void Write(PdfArray pdfArray) {
private void Write(PdfDictionary pdfDictionary) {
WriteBytes(openDict);
- foreach (KeyValuePair entry in pdfDictionary.EntrySet()) {
+ foreach (PdfName key in pdfDictionary.KeySet()) {
bool isAlreadyWriteSpace = false;
- Write(entry.Key);
- PdfObject value = entry.Value;
+ Write(key);
+ PdfObject value = pdfDictionary.Get(key, false);
if (value == null) {
ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfOutputStream));
- logger.Warn(String.Format(LogMessageConstant.INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE, entry.Key));
+ logger.Warn(String.Format(LogMessageConstant.INVALID_KEY_VALUE_KEY_0_HAS_NULL_VALUE, key));
value = PdfNull.PDF_NULL;
}
if ((value.GetObjectType() == PdfObject.NUMBER || value.GetObjectType() == PdfObject.LITERAL || value.GetObjectType
@@ -187,7 +186,7 @@ private void Write(PdfDictionary pdfDictionary) {
private void Write(PdfIndirectReference indirectReference) {
if (document != null && !indirectReference.GetDocument().Equals(document)) {
- throw new PdfException(PdfException.PdfInderectObjectBelongToOtherPdfDocument);
+ throw new PdfException(PdfException.PdfIndirectObjectBelongsToOtherPdfDocument);
}
if (indirectReference.GetRefersTo() == null) {
Write(PdfNull.PDF_NULL);
@@ -358,7 +357,7 @@ private void Write(PdfStream pdfStream) {
}
}
catch (System.IO.IOException e) {
- throw new PdfException(PdfException.CannotWritePdfStream, e, pdfStream);
+ throw new PdfException(PdfException.CannotWriteToPdfStream, e, pdfStream);
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfPage.cs b/itext/itext.kernel/itext/kernel/pdf/PdfPage.cs
index 8f48929dd5..c69e93908a 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfPage.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfPage.cs
@@ -105,24 +105,24 @@ protected internal PdfPage(PdfDocument pdfDocument)
: this(pdfDocument, pdfDocument.GetDefaultPageSize()) {
}
+ /// Gets page size, defined by media box object.
+ /// Gets page size, defined by media box object. This method doesn't take page rotation into account.
+ ///
+ ///
+ ///
+ ///
+ /// that specify page size.
+ ///
public virtual Rectangle GetPageSize() {
- PdfArray box = GetPdfObject().GetAsArray(PdfName.MediaBox);
- if (box == null || box.Size() != 4) {
- throw new ArgumentException("MediaBox");
- }
- PdfNumber llx = box.GetAsNumber(0);
- PdfNumber lly = box.GetAsNumber(1);
- PdfNumber urx = box.GetAsNumber(2);
- PdfNumber ury = box.GetAsNumber(3);
- if (llx == null || lly == null || urx == null || ury == null) {
- throw new ArgumentException("MediaBox");
- }
- return new Rectangle(Math.Min(llx.FloatValue(), urx.FloatValue()), Math.Min(lly.FloatValue(), ury.FloatValue
- ()), Math.Abs(urx.FloatValue() - llx.FloatValue()), Math.Abs(ury.FloatValue() - lly.FloatValue()));
+ return GetMediaBox();
}
- /// Gets the rotated page.
- /// the rotated rectangle
+ /// Gets page size, considering page rotation.
+ ///
+ ///
+ ///
+ /// that specify size of rotated page.
+ ///
public virtual Rectangle GetPageSizeWithRotation() {
PageSize rect = new PageSize(GetPageSize());
int rotation = GetRotation();
@@ -133,6 +133,17 @@ public virtual Rectangle GetPageSizeWithRotation() {
return rect;
}
+ /// Gets the number of degrees by which the page shall be rotated clockwise when displayed or printed.
+ ///
+ ///
+ /// Gets the number of degrees by which the page shall be rotated clockwise when displayed or printed.
+ /// Shall be a multiple of 90.
+ ///
+ ///
+ ///
+ /// int
+ /// number of degrees. Default value: 0
+ ///
public virtual int GetRotation() {
PdfNumber rotate = GetPdfObject().GetAsNumber(PdfName.Rotate);
if (rotate == null) {
@@ -145,11 +156,44 @@ public virtual int GetRotation() {
}
}
+ /// Sets the page rotation.
+ ///
+ /// the
+ /// int
+ /// number of degrees by which the page shall be rotated clockwise
+ /// when displayed or printed. Shall be a multiple of 90.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetRotation(int degAngle) {
GetPdfObject().Put(PdfName.Rotate, new PdfNumber(degAngle));
return this;
}
+ ///
+ /// Gets the content stream at specified 0-based index in the Contents object
+ ///
+ /// .
+ /// The situation when Contents object is a
+ ///
+ /// is treated like a one element array.
+ ///
+ ///
+ /// the
+ /// int
+ /// index of returned
+ ///
+ /// .
+ ///
+ ///
+ ///
+ ///
+ /// object at specified index.
+ ///
+ /// if the index is out of range
public virtual PdfStream GetContentStream(int index) {
int count = GetContentStreamCount();
if (index >= count) {
@@ -170,6 +214,21 @@ public virtual PdfStream GetContentStream(int index) {
}
}
+ ///
+ /// Gets the size of Contents object
+ ///
+ /// .
+ /// The situation when Contents object is a
+ ///
+ /// is treated like a one element array.
+ ///
+ ///
+ /// the
+ /// int
+ /// size of Contents object, or 1 if Contents object is a
+ ///
+ /// .
+ ///
public virtual int GetContentStreamCount() {
PdfObject contents = GetPdfObject().Get(PdfName.Contents);
if (contents is PdfStream) {
@@ -185,6 +244,20 @@ public virtual int GetContentStreamCount() {
}
}
+ ///
+ /// Returns the Contents object if it is
+ ///
+ /// , or first stream in the array if it is
+ ///
+ /// .
+ ///
+ ///
+ /// first
+ ///
+ /// in Contents object, or
+ ///
+ /// if Contents is empty.
+ ///
public virtual PdfStream GetFirstContentStream() {
if (GetContentStreamCount() > 0) {
return GetContentStream(0);
@@ -192,6 +265,20 @@ public virtual PdfStream GetFirstContentStream() {
return null;
}
+ ///
+ /// Returns the Contents object if it is
+ ///
+ /// , or last stream in the array if it is
+ ///
+ /// .
+ ///
+ ///
+ /// first
+ ///
+ /// in Contents object, or
+ ///
+ /// if Contents is empty.
+ ///
public virtual PdfStream GetLastContentStream() {
int count = GetContentStreamCount();
if (count > 0) {
@@ -200,14 +287,60 @@ public virtual PdfStream GetLastContentStream() {
return null;
}
+ ///
+ /// Creates new
+ ///
+ /// object and puts it at the beginning of Contents array
+ /// (if Contents object is
+ ///
+ /// it will be replaced with one-element array).
+ ///
+ ///
+ /// Created
+ ///
+ /// object.
+ ///
public virtual PdfStream NewContentStreamBefore() {
return NewContentStream(true);
}
+ ///
+ /// Creates new
+ ///
+ /// object and puts it at the end of Contents array
+ /// (if Contents object is
+ ///
+ /// it will be replaced with one-element array).
+ ///
+ ///
+ /// Created
+ ///
+ /// object.
+ ///
public virtual PdfStream NewContentStreamAfter() {
return NewContentStream(false);
}
+ ///
+ /// Gets the
+ ///
+ /// wrapper object for this page resources.
+ /// If page doesn't have resource object, then it will be inherited from page's parents.
+ /// If neither parents nor page has the resource object, then the new one is created and added to page dictionary.
+ ///
+ /// NOTE: If you'll try to modify the inherited resources, then the new resources object will be created,
+ /// so you won't change the parent's resources.
+ /// This new object under the wrapper will be added to page dictionary on
+ ///
+ /// ,
+ /// or you can add it manually with this line, if needed:
+ /// getPdfObject().put(PdfName.Resources, getResources().getPdfObject());
+ ///
+ ///
+ ///
+ ///
+ /// wrapper of the page.
+ ///
public virtual PdfResources GetResources() {
if (this.resources == null) {
bool readOnly = false;
@@ -229,15 +362,34 @@ public virtual PdfResources GetResources() {
return this.resources;
}
+ ///
+ /// Sets
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// to set.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetResources(PdfResources pdfResources) {
GetPdfObject().Put(PdfName.Resources, pdfResources.GetPdfObject());
this.resources = pdfResources;
return this;
}
- /// Use this method to set the XMP Metadata for each page.
- /// The xmpMetadata to set.
- ///
+ /// Sets the XMP Metadata.
+ ///
+ /// the
+ /// byte[]
+ /// of XMP Metadata to set.
+ ///
+ /// in case of writing error.
public virtual void SetXmpMetadata(byte[] xmpMetadata) {
PdfStream xmp = ((PdfStream)new PdfStream().MakeIndirect(GetDocument()));
xmp.GetOutputStream().Write(xmpMetadata);
@@ -246,20 +398,44 @@ public virtual void SetXmpMetadata(byte[] xmpMetadata) {
GetPdfObject().Put(PdfName.Metadata, xmp);
}
- ///
- ///
+ /// Serializes XMP Metadata to byte array and sets it.
+ ///
+ /// the
+ ///
+ /// object to set.
+ ///
+ ///
+ /// the
+ ///
+ /// used while serialization.
+ ///
+ /// in case of XMP Metadata serialization error.
+ /// in case of writing error.
public virtual void SetXmpMetadata(XMPMeta xmpMeta, SerializeOptions serializeOptions) {
SetXmpMetadata(XMPMetaFactory.SerializeToBuffer(xmpMeta, serializeOptions));
}
- ///
- ///
+ /// Serializes XMP Metadata to byte array and sets it.
+ /// Serializes XMP Metadata to byte array and sets it. Uses padding equals to 2000.
+ ///
+ /// the
+ ///
+ /// object to set.
+ ///
+ /// in case of XMP Metadata serialization error.
+ /// in case of writing error.
public virtual void SetXmpMetadata(XMPMeta xmpMeta) {
SerializeOptions serializeOptions = new SerializeOptions();
serializeOptions.SetPadding(2000);
SetXmpMetadata(xmpMeta, serializeOptions);
}
+ /// Gets the XMP Metadata object.
+ ///
+ ///
+ ///
+ /// object, that represent XMP Metadata.
+ ///
///
public virtual PdfStream GetXmpMetadata() {
return GetPdfObject().GetAsStream(PdfName.Metadata);
@@ -272,7 +448,11 @@ public virtual PdfStream GetXmpMetadata() {
/// NOTE: Works only for pages from the document opened in reading mode, otherwise an exception is thrown.
///
/// a document to copy page to.
- /// copied page.
+ ///
+ /// copied
+ ///
+ /// .
+ ///
public virtual iText.Kernel.Pdf.PdfPage CopyTo(PdfDocument toDocument) {
return CopyTo(toDocument, null);
}
@@ -284,19 +464,32 @@ public virtual iText.Kernel.Pdf.PdfPage CopyTo(PdfDocument toDocument) {
/// NOTE: Works only for pages from the document opened in reading mode, otherwise an exception is thrown.
///
/// a document to copy page to.
- /// a copier which bears a specific copy logic. May be NULL
- /// copied page.
+ ///
+ /// a copier which bears a specific copy logic. May be
+ ///
+ ///
+ ///
+ /// copied
+ ///
+ /// .
+ ///
public virtual iText.Kernel.Pdf.PdfPage CopyTo(PdfDocument toDocument, IPdfPageExtraCopier copier) {
PdfDictionary dictionary = GetPdfObject().CopyTo(toDocument, excludedKeys, true);
iText.Kernel.Pdf.PdfPage page = new iText.Kernel.Pdf.PdfPage(dictionary);
CopyInheritedProperties(page, toDocument);
foreach (PdfAnnotation annot in GetAnnotations()) {
if (annot.GetSubtype().Equals(PdfName.Link)) {
- GetDocument().StoreLinkAnnotation(this, (PdfLinkAnnotation)annot);
+ GetDocument().StoreLinkAnnotation(page, (PdfLinkAnnotation)annot);
}
else {
- page.AddAnnotation(-1, PdfAnnotation.MakeAnnotation(((PdfDictionary)annot.GetPdfObject().CopyTo(toDocument
- , false))), false);
+ if (annot.GetSubtype().Equals(PdfName.Widget)) {
+ page.AddAnnotation(-1, PdfAnnotation.MakeAnnotation(((PdfDictionary)annot.GetPdfObject().CopyTo(toDocument
+ , false))), false);
+ }
+ else {
+ page.AddAnnotation(-1, PdfAnnotation.MakeAnnotation(((PdfDictionary)annot.GetPdfObject().CopyTo(toDocument
+ , true))), false);
+ }
}
}
if (toDocument.IsTagged()) {
@@ -319,7 +512,11 @@ public virtual iText.Kernel.Pdf.PdfPage CopyTo(PdfDocument toDocument, IPdfPageE
/// Copies page as FormXObject to the specified document.
/// a document to copy to.
- /// resultant XObject.
+ ///
+ /// copied
+ ///
+ /// object.
+ ///
///
public virtual PdfFormXObject CopyAsFormXObject(PdfDocument toDocument) {
PdfFormXObject xObject = new PdfFormXObject(GetCropBox());
@@ -332,6 +529,20 @@ public virtual PdfFormXObject CopyAsFormXObject(PdfDocument toDocument) {
return xObject;
}
+ ///
+ /// Gets the
+ ///
+ /// that owns that page, or
+ ///
+ /// if such document isn't exist.
+ ///
+ ///
+ ///
+ ///
+ /// that owns that page, or
+ ///
+ /// if such document isn't exist.
+ ///
public virtual PdfDocument GetDocument() {
if (GetPdfObject().GetIndirectReference() != null) {
return GetPdfObject().GetIndirectReference().GetDocument();
@@ -357,86 +568,160 @@ public override void Flush() {
/// Flushes page and its content stream.
///
- /// Flushes page and its content stream. If flushXObjects is true the images and FormXObjects
- /// associated with this page will also be flushed.
+ /// Flushes page and its content stream. If flushContentStreams is true, all content streams that are
+ /// rendered on this page (like FormXObjects, annotation appearance streams, patterns) and also all images associated
+ /// with this page will also be flushed.
///
/// For notes about tag structure flushing see
/// PdfPage#flush() method
/// .
///
///
- /// If PdfADocument is used, flushing will be applied only if flushXObjects is true.
+ /// If PdfADocument is used, flushing will be applied only if flushContentStreams is true.
///
- /// if true the images and FormXObjects associated with this page will also be flushed.
- ///
- public virtual void Flush(bool flushXObjects) {
+ ///
+ /// if true all content streams that are rendered on this page (like form xObjects,
+ /// annotation appearance streams, patterns) and also all images associated with this page
+ /// will be flushed.
+ ///
+ public virtual void Flush(bool flushContentStreams) {
// TODO log warning in case of failed flush in pdfa document case
if (IsFlushed()) {
return;
}
+ GetDocument().DispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.END_PAGE, this));
if (GetDocument().IsTagged() && !GetDocument().GetStructTreeRoot().IsFlushed()) {
- GetDocument().GetTagStructureContext().FlushPageTags(this);
- GetDocument().GetStructTreeRoot().CreateParentTreeEntryForPage(this);
+ TryFlushPageTags();
}
- GetDocument().DispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.END_PAGE, this));
- if (flushXObjects) {
+ if (resources != null && resources.IsModified() && !resources.IsReadOnly()) {
+ GetPdfObject().Put(PdfName.Resources, resources.GetPdfObject());
+ }
+ if (flushContentStreams) {
GetDocument().CheckIsoConformance(this, IsoKey.PAGE);
+ FlushContentStreams();
}
int contentStreamCount = GetContentStreamCount();
for (int i = 0; i < contentStreamCount; i++) {
GetContentStream(i).Flush(false);
}
- ICollection xObjects = null;
- if (resources != null) {
- if (resources.IsReadOnly() && !resources.IsModified()) {
- GetPdfObject().Remove(PdfName.Resources);
- }
- else {
- if (flushXObjects) {
- PdfDictionary xObjectsDict = GetPdfObject().GetAsDictionary(PdfName.Resources).GetAsDictionary(PdfName.XObject
- );
- xObjects = xObjectsDict != null ? xObjectsDict.Values() : null;
- }
- }
- }
resources = null;
base.Flush();
- if (flushXObjects && xObjects != null) {
- FlushXObjects(xObjects);
- }
}
+ ///
+ /// Gets
+ ///
+ /// object specified by page's Media Box, that defines the boundaries of the physical medium
+ /// on which the page shall be displayed or printed
+ ///
+ ///
+ ///
+ ///
+ /// object specified by page Media Box, expressed in default user space units.
+ ///
+ /// in case of any error while reading MediaBox object.
public virtual Rectangle GetMediaBox() {
InitParentPages();
PdfArray mediaBox = GetPdfObject().GetAsArray(PdfName.MediaBox);
if (mediaBox == null) {
mediaBox = (PdfArray)GetParentValue(parentPages, PdfName.MediaBox);
}
- return mediaBox.ToRectangle();
+ if (mediaBox == null) {
+ throw new PdfException(PdfException.CannotRetrieveMediaBoxAttribute);
+ }
+ if (mediaBox.Size() != 4) {
+ throw new PdfException(PdfException.WrongMediaBoxSize1).SetMessageParams(mediaBox.Size());
+ }
+ PdfNumber llx = mediaBox.GetAsNumber(0);
+ PdfNumber lly = mediaBox.GetAsNumber(1);
+ PdfNumber urx = mediaBox.GetAsNumber(2);
+ PdfNumber ury = mediaBox.GetAsNumber(3);
+ if (llx == null || lly == null || urx == null || ury == null) {
+ throw new PdfException(PdfException.InvalidMediaBoxValue);
+ }
+ return new Rectangle(Math.Min(llx.FloatValue(), urx.FloatValue()), Math.Min(lly.FloatValue(), ury.FloatValue
+ ()), Math.Abs(urx.FloatValue() - llx.FloatValue()), Math.Abs(ury.FloatValue() - lly.FloatValue()));
}
+ ///
+ /// Sets the Media Box object, that defines the boundaries of the physical medium
+ /// on which the page shall be displayed or printed.
+ ///
+ ///
+ /// the
+ ///
+ /// object to set, expressed in default user space units.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetMediaBox(Rectangle rectangle) {
GetPdfObject().Put(PdfName.MediaBox, new PdfArray(rectangle));
return this;
}
+ ///
+ /// Gets the
+ ///
+ /// specified by page's CropBox, that defines the visible region of default user space.
+ /// When the page is displayed or printed, its contents shall be clipped (cropped) to this rectangle
+ /// and then shall be imposed on the output medium in some implementation-defined manner.
+ ///
+ ///
+ /// the
+ ///
+ /// object specified by pages's CropBox, expressed in default user space units.
+ /// MediaBox by default.
+ ///
public virtual Rectangle GetCropBox() {
InitParentPages();
PdfArray cropBox = GetPdfObject().GetAsArray(PdfName.CropBox);
if (cropBox == null) {
cropBox = (PdfArray)GetParentValue(parentPages, PdfName.CropBox);
if (cropBox == null) {
- cropBox = new PdfArray(GetMediaBox());
+ return GetMediaBox();
}
}
return cropBox.ToRectangle();
}
+ /// Sets the CropBox object, that defines the visible region of default user space.
+ ///
+ /// Sets the CropBox object, that defines the visible region of default user space.
+ /// When the page is displayed or printed, its contents shall be clipped (cropped) to this rectangle
+ /// and then shall be imposed on the output medium in some implementation-defined manner.
+ ///
+ ///
+ /// the
+ ///
+ /// object to set, expressed in default user space units.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetCropBox(Rectangle rectangle) {
GetPdfObject().Put(PdfName.CropBox, new PdfArray(rectangle));
return this;
}
+ ///
+ /// Sets the ArtBox object, that define the extent of the page’s meaningful content
+ /// (including potential white space) as intended by the page’s creator.
+ ///
+ ///
+ /// the
+ ///
+ /// object to set, expressed in default user space units.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetArtBox(Rectangle rectangle) {
if (GetPdfObject().GetAsRectangle(PdfName.TrimBox) != null) {
GetPdfObject().Remove(PdfName.TrimBox);
@@ -447,10 +732,35 @@ public virtual iText.Kernel.Pdf.PdfPage SetArtBox(Rectangle rectangle) {
return this;
}
+ ///
+ /// Gets the
+ ///
+ /// object specified by page's ArtBox, that define the extent of the page’s
+ /// meaningful content (including potential white space) as intended by the page’s creator.
+ ///
+ ///
+ /// the
+ ///
+ /// object specified by page's ArtBox, expressed in default user space units.
+ /// CropBox by default.
+ ///
public virtual Rectangle GetArtBox() {
- return GetPdfObject().GetAsRectangle(PdfName.ArtBox);
+ Rectangle artBox = GetPdfObject().GetAsRectangle(PdfName.ArtBox);
+ return artBox == null ? GetCropBox() : artBox;
}
+ /// Sets the TrimBox object, that define the intended dimensions of the finished page after trimming.
+ ///
+ ///
+ /// the
+ ///
+ /// object to set, expressed in default user space units.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetTrimBox(Rectangle rectangle) {
if (GetPdfObject().GetAsRectangle(PdfName.ArtBox) != null) {
GetPdfObject().Remove(PdfName.ArtBox);
@@ -461,19 +771,40 @@ public virtual iText.Kernel.Pdf.PdfPage SetTrimBox(Rectangle rectangle) {
return this;
}
+ ///
+ /// Gets the
+ ///
+ /// object specified by page's TrimBox object,
+ /// that define the intended dimensions of the finished page after trimming.
+ ///
+ ///
+ /// the
+ ///
+ /// object specified by page's TrimBox, expressed in default user space units.
+ /// CropBox by default.
+ ///
public virtual Rectangle GetTrimBox() {
- return GetPdfObject().GetAsRectangle(PdfName.TrimBox);
+ Rectangle trimBox = GetPdfObject().GetAsRectangle(PdfName.TrimBox);
+ return trimBox == null ? GetCropBox() : trimBox;
}
/// Get decoded bytes for the whole page content.
/// byte array.
- /// in case any @see IOException.
+ ///
+ /// in case of any
+ /// IOException).
+ ///
public virtual byte[] GetContentBytes() {
try {
MemoryStream baos = new MemoryStream();
int streamCount = GetContentStreamCount();
+ byte[] streamBytes;
for (int i = 0; i < streamCount; i++) {
- baos.Write(GetStreamBytes(i));
+ streamBytes = GetStreamBytes(i);
+ baos.Write(streamBytes);
+ if (0 != streamBytes.Length && !char.IsWhiteSpace((char)streamBytes[streamBytes.Length - 1])) {
+ baos.Write('\n');
+ }
}
return baos.ToArray();
}
@@ -485,14 +816,17 @@ public virtual byte[] GetContentBytes() {
/// Gets decoded bytes of a certain stream of a page content.
/// index of stream inside Content.
/// byte array.
- /// in case any @see IOException.
+ ///
+ /// in case of any
+ /// IOException).
+ ///
public virtual byte[] GetStreamBytes(int index) {
return GetContentStream(index).GetBytes();
}
/// Calculates and returns next available MCID reference.
/// calculated MCID reference.
- ///
+ /// in case of not tagged document.
public virtual int GetNextMcid() {
if (!GetDocument().IsTagged()) {
throw new PdfException(PdfException.MustBeATaggedDocument);
@@ -504,6 +838,16 @@ public virtual int GetNextMcid() {
return mcid++;
}
+ ///
+ /// Gets
+ ///
+ /// key of the page’s entry in the structural parent tree.
+ ///
+ ///
+ ///
+ ///
+ /// key of the page’s entry in the structural parent tree.
+ ///
public virtual int? GetStructParentIndex() {
if (structParents == -1) {
PdfNumber n = GetPdfObject().GetAsNumber(PdfName.StructParents);
@@ -517,11 +861,40 @@ public virtual int GetNextMcid() {
return structParents;
}
+ /// Helper method to add an additional action to this page.
+ ///
+ /// Helper method to add an additional action to this page.
+ /// May be used in chain.
+ ///
+ ///
+ /// a
+ ///
+ /// specifying the name of an additional action
+ ///
+ ///
+ /// the
+ ///
+ /// to add as an additional action
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetAdditionalAction(PdfName key, PdfAction action) {
PdfAction.SetAdditionalAction(this, key, action);
return this;
}
+ ///
+ /// Gets array of annotation dictionaries that shall contain indirect references
+ /// to all annotations associated with the page.
+ ///
+ ///
+ /// the
+ /// List
+ /// containing all page's annotations.
+ ///
public virtual IList GetAnnotations() {
IList annotations = new List();
PdfArray annots = GetPdfObject().GetAsArray(PdfName.Annots);
@@ -534,6 +907,19 @@ public virtual IList GetAnnotations() {
return annotations;
}
+ /// Checks if page contains the specified annotation.
+ ///
+ /// the
+ ///
+ /// to check.
+ ///
+ ///
+ ///
+ ///
+ /// if page contains specified annotation and
+ ///
+ /// otherwise.
+ ///
public virtual bool ContainsAnnotation(PdfAnnotation annotation) {
foreach (PdfAnnotation a in GetAnnotations()) {
if (a.GetPdfObject().Equals(annotation.GetPdfObject())) {
@@ -543,10 +929,55 @@ public virtual bool ContainsAnnotation(PdfAnnotation annotation) {
return false;
}
+ /// Adds specified annotation to the end of annotations array and tagged it.
+ ///
+ /// Adds specified annotation to the end of annotations array and tagged it.
+ /// May be used in chain.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage AddAnnotation(PdfAnnotation annotation) {
return AddAnnotation(-1, annotation, true);
}
+ ///
+ /// Adds specified
+ ///
+ /// to specified index in annotations array with or without autotagging.
+ /// May be used in chain.
+ ///
+ ///
+ /// the index at which specified annotation will be added. If
+ /// -1
+ /// then annotation will be added
+ /// to the end of array.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ ///
+ /// if
+ ///
+ /// the added annotation will be autotagged.
+ /// (see
+ ///
+ /// )
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage AddAnnotation(int index, PdfAnnotation annotation, bool tagAnnotation
) {
if (GetDocument().IsTagged() && tagAnnotation) {
@@ -578,7 +1009,11 @@ public virtual iText.Kernel.Pdf.PdfPage AddAnnotation(int index, PdfAnnotation a
/// NOTE: If document is tagged, PdfDocument's PdfTagStructure instance will point at annotation tag parent after method call.
///
/// an annotation to be removed.
- /// this PdfPage instance.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage RemoveAnnotation(PdfAnnotation annotation) {
PdfArray annots = GetAnnots(false);
if (annots != null) {
@@ -605,6 +1040,18 @@ public virtual iText.Kernel.Pdf.PdfPage RemoveAnnotation(PdfAnnotation annotatio
return this;
}
+ ///
+ /// Gets the number of
+ ///
+ /// associated with this page.
+ ///
+ ///
+ /// the
+ /// int
+ /// number of
+ ///
+ /// associated with this page.
+ ///
public virtual int GetAnnotsSize() {
PdfArray annots = GetAnnots(false);
if (annots == null) {
@@ -616,7 +1063,6 @@ public virtual int GetAnnotsSize() {
/// This method gets outlines of a current page
///
/// return all outlines of a current page
- ///
public virtual IList GetOutlines(bool updateOutlines) {
GetDocument().GetOutlines(updateOutlines);
return GetDocument().GetCatalog().GetPagesWithOutlines().Get(GetPdfObject());
@@ -654,7 +1100,11 @@ public virtual iText.Kernel.Pdf.PdfPage SetIgnorePageRotationForContent(bool ign
/// May be NULL
///
/// The label prefix for page labels in this range. May be NULL
- ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetPageLabel(PageLabelNumberingStyleConstants numberingStyle, String
labelPrefix) {
return SetPageLabel(numberingStyle, labelPrefix, 1);
@@ -670,7 +1120,11 @@ public virtual iText.Kernel.Pdf.PdfPage SetPageLabel(PageLabelNumberingStyleCons
/// The value of the numeric portion for the first page label in the range. Must be greater or
/// equal 1.
///
- ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.PdfPage SetPageLabel(PageLabelNumberingStyleConstants numberingStyle, String
labelPrefix, int firstPage) {
if (firstPage < 1) {
@@ -720,6 +1174,27 @@ public virtual iText.Kernel.Pdf.PdfPage SetPageLabel(PageLabelNumberingStyleCons
return this;
}
+ ///
+ /// Helper method that associate specified value with specified key in the underlined
+ ///
+ /// .
+ /// May be used in chain.
+ ///
+ ///
+ /// the
+ ///
+ /// key with which the specified value is to be associated.
+ ///
+ ///
+ /// the
+ ///
+ /// value to be associated with the specified key.
+ ///
+ ///
+ /// this
+ ///
+ /// object.
+ ///
public virtual iText.Kernel.Pdf.PdfPage Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
@@ -818,22 +1293,71 @@ private PdfStream NewContentStream(bool before) {
return contentStream;
}
- private void FlushXObjects(ICollection xObjects) {
- foreach (PdfObject obj in xObjects) {
- PdfStream xObject = (PdfStream)obj;
- PdfDictionary innerResources = xObject.GetAsDictionary(PdfName.Resources);
- ICollection innerXObjects = null;
- if (innerResources != null) {
- PdfDictionary innerXObjectsDict = innerResources.GetAsDictionary(PdfName.XObject);
- innerXObjects = innerXObjectsDict != null ? innerXObjectsDict.Values() : null;
+ private void TryFlushPageTags() {
+ try {
+ GetDocument().GetTagStructureContext().FlushPageTags(this);
+ GetDocument().GetStructTreeRoot().CreateParentTreeEntryForPage(this);
+ }
+ catch (Exception ex) {
+ throw new PdfException(PdfException.TagStructureFlushingFailedItMightBeCorrupted, ex);
+ }
+ }
+
+ private void FlushContentStreams() {
+ FlushContentStreams(GetResources().GetPdfObject());
+ PdfArray annots = GetAnnots(false);
+ if (annots != null) {
+ for (int i = 0; i < annots.Size(); ++i) {
+ PdfDictionary apDict = annots.GetAsDictionary(i).GetAsDictionary(PdfName.AP);
+ if (apDict != null) {
+ FlushAppearanceStreams(apDict);
+ }
+ }
+ }
+ }
+
+ private void FlushContentStreams(PdfDictionary resources) {
+ if (resources != null) {
+ FlushWithResources(resources.GetAsDictionary(PdfName.XObject));
+ FlushWithResources(resources.GetAsDictionary(PdfName.Pattern));
+ FlushWithResources(resources.GetAsDictionary(PdfName.Shading));
+ }
+ }
+
+ private void FlushWithResources(PdfDictionary objsCollection) {
+ if (objsCollection == null) {
+ return;
+ }
+ foreach (PdfObject obj in objsCollection.Values()) {
+ if (obj.IsFlushed()) {
+ continue;
}
- obj.Flush();
- if (innerXObjects != null) {
- FlushXObjects(innerXObjects);
+ FlushContentStreams(((PdfDictionary)obj).GetAsDictionary(PdfName.Resources));
+ FlushMustBeIndirectObject(obj);
+ }
+ }
+
+ private void FlushAppearanceStreams(PdfDictionary appearanceStreamsDict) {
+ foreach (PdfObject val in appearanceStreamsDict.Values()) {
+ if (val is PdfDictionary) {
+ PdfDictionary ap = (PdfDictionary)val;
+ if (ap.IsDictionary()) {
+ FlushAppearanceStreams(ap);
+ }
+ else {
+ if (ap.IsStream()) {
+ FlushMustBeIndirectObject(ap);
+ }
+ }
}
}
}
+ private void FlushMustBeIndirectObject(PdfObject obj) {
+ // TODO DEVSIX-744
+ obj.MakeIndirect(GetDocument()).Flush();
+ }
+
/*
* initialization parentPages if needed
*/
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfPagesTree.cs b/itext/itext.kernel/itext/kernel/pdf/PdfPagesTree.cs
index 2d2dcec441..2e687082a2 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfPagesTree.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfPagesTree.cs
@@ -50,7 +50,7 @@ source product.
namespace iText.Kernel.Pdf {
///
/// Algorithm for construction
- /// PdfPages
+ ///
/// tree
///
internal class PdfPagesTree {
@@ -221,7 +221,8 @@ public virtual void AddPage(PdfPage pdfPage) {
/// one-base index of the page
///
///
- /// PdfPage
+ ///
+ /// to insert.
///
public virtual void AddPage(int index, PdfPage pdfPage) {
--index;
@@ -268,7 +269,7 @@ public virtual PdfPage RemovePage(int pageNum) {
/// Generate PdfPages tree.
///
/// root
- /// PdfPages
+ ///
///
/// in case empty document
protected internal virtual PdfObject GenerateTree() {
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfReader.cs b/itext/itext.kernel/itext/kernel/pdf/PdfReader.cs
index d33c574167..f95396941b 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfReader.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfReader.cs
@@ -122,7 +122,6 @@ public PdfReader(IRandomAccessSource byteSource, ReaderProperties properties) {
///
/// properties of the created reader
/// on error
- /// on error
public PdfReader(Stream @is, ReaderProperties properties)
: this(new RandomAccessSourceFactory().CreateSource(@is), properties) {
}
@@ -135,7 +134,6 @@ public PdfReader(Stream @is, ReaderProperties properties)
/// if user doesn't want to close stream, he should set closeStream=false;
///
/// on error
- /// on error
public PdfReader(Stream @is)
: this(@is, new ReaderProperties()) {
}
@@ -212,7 +210,6 @@ public virtual long GetLastXref() {
/// true if to get decoded stream bytes, false if to leave it originally encoded.
/// byte[]
///
- ///
public virtual byte[] ReadStreamBytes(PdfStream stream, bool decode) {
byte[] b = ReadStreamBytesRaw(stream);
if (decode && b != null) {
@@ -288,7 +285,6 @@ public virtual byte[] ReadStreamBytesRaw(PdfStream stream) {
/// true if to get decoded stream, false if to leave it originally encoded.
/// InputStream
///
- ///
public virtual Stream ReadStream(PdfStream stream, bool decode) {
byte[] bytes = ReadStreamBytes(stream, decode);
return bytes != null ? new MemoryStream(bytes) : null;
@@ -473,6 +469,9 @@ private void ReadDecryptObj() {
encrypted = true;
PdfName filter = enc.GetAsName(PdfName.Filter);
if (PdfName.Adobe_PubSec.Equals(filter)) {
+ if (properties.certificate == null) {
+ throw new PdfException(PdfException.CertificateIsNotProvidedDocumentIsEncryptedWithPublicKeyCertificate);
+ }
decrypt = new PdfEncryption(enc, properties.certificateKey, properties.certificate);
}
else {
@@ -516,7 +515,7 @@ protected internal virtual void ReadObjectStream(PdfStream objectStream) {
address[k] = tokens.GetIntValue() + first;
}
if (!ok) {
- throw new PdfException(PdfException.ErrorReadingObjectStream);
+ throw new PdfException(PdfException.ErrorWhileReadingObjectStream);
}
for (int k_1 = 0; k_1 < n; ++k_1) {
tokens.Seek(address[k_1]);
@@ -602,7 +601,7 @@ protected internal virtual PdfObject ReadObject(bool readAsDirect, bool objStm)
pdfString.SetDecryptInfoNum(currentIndirectReference.GetObjNumber());
pdfString.SetDecryptInfoGen(currentIndirectReference.GetGenNumber());
}
- return properties.password == null || objStm ? pdfString : pdfString.Decrypt(decrypt);
+ return !IsEncrypted() || objStm ? pdfString : pdfString.Decrypt(decrypt);
}
case PdfTokenizer.TokenType.Name: {
@@ -805,6 +804,22 @@ protected internal virtual PdfDictionary ReadXrefSection() {
tokens.NextValidToken();
int gen = tokens.GetIntValue();
tokens.NextValidToken();
+ if (pos == 0L && gen == 65535 && num == 1) {
+ // Very rarely can an XREF have an incorrect start number. (SUP-1557)
+ // e.g.
+ // xref
+ // 1 13
+ // 0000000000 65535 f
+ // 0000000009 00000 n
+ // 0000215136 00000 n
+ // [...]
+ // Because of how iText reads (and initializes) the XREF, this will lead to the XREF having two 0000 65535 entries.
+ // This throws off the parsing and other operations you'd like to perform.
+ // To fix this we reset our index and decrease the limit when we've encountered the magic entry at position 1.
+ num = 0;
+ end--;
+ continue;
+ }
PdfIndirectReference reference = xref.Get(num);
if (reference == null) {
reference = new PdfIndirectReference(pdfDocument, num, gen, pos);
@@ -821,7 +836,7 @@ protected internal virtual PdfDictionary ReadXrefSection() {
if (tokens.TokenValueEqualsTo(PdfTokenizer.N)) {
if (xref.Get(num) == null) {
if (pos == 0) {
- tokens.ThrowError(PdfException.FilePosition0CrossReferenceEntryInThisXrefSubsection);
+ tokens.ThrowError(PdfException.FilePosition1CrossReferenceEntryInThisXrefSubsection);
}
xref.Add(reference);
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfResources.cs b/itext/itext.kernel/itext/kernel/pdf/PdfResources.cs
index 09b0f98f1f..48c1905130 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfResources.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfResources.cs
@@ -43,12 +43,22 @@ source product.
*/
using System;
using System.Collections.Generic;
+using iText.IO.Util;
+using iText.Kernel;
using iText.Kernel.Font;
using iText.Kernel.Pdf.Colorspace;
using iText.Kernel.Pdf.Extgstate;
using iText.Kernel.Pdf.Xobject;
namespace iText.Kernel.Pdf {
+ ///
+ /// Wrapper class that represent resource dictionary - that define named resources
+ /// used by content streams operators.
+ ///
+ ///
+ /// Wrapper class that represent resource dictionary - that define named resources
+ /// used by content streams operators. (ISO 32000-1, 7.8.3 Resource Dictionaries)
+ ///
public class PdfResources : PdfObjectWrapper {
private const String F = "F";
@@ -96,35 +106,130 @@ public class PdfResources : PdfObjectWrapper {
private bool isModified = false;
+ /// Creates new instance from given dictionary.
+ ///
+ /// the
+ ///
+ /// object from which the resource object will be created.
+ ///
public PdfResources(PdfDictionary pdfObject)
: base(pdfObject) {
BuildResources(pdfObject);
}
+ /// Creates new instance from empty dictionary.
public PdfResources()
: this(new PdfDictionary()) {
}
- /// Add font to resources and register PdfFont in the document for further flushing.
- /// font resource name.
+ /// Adds font to resources and register PdfFont in the document for further flushing.
+ /// added font resource name.
public virtual PdfName AddFont(PdfDocument pdfDocument, PdfFont font) {
pdfDocument.GetDocumentFonts().Add(font);
return AddResource(font, fontNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added image resource name.
public virtual PdfName AddImage(PdfImageXObject image) {
return AddResource(image, imageNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as image.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added image resources name.
+ public virtual PdfName AddImage(PdfStream image) {
+ return AddResource(image, imageNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as image.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// .
+ ///
+ /// added image resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddImage(PdfStream) instead.")]
public virtual PdfName AddImage(PdfObject image) {
+ if (image.GetObjectType() != PdfObject.STREAM) {
+ throw new PdfException(PdfException.CannotAddNonStreamImageToResources1).SetMessageParams(image.GetType().
+ ToString());
+ }
return AddResource(image, imageNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added form resource name.
public virtual PdfName AddForm(PdfFormXObject form) {
return AddResource(form, formNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as form.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added form resources name.
+ public virtual PdfName AddForm(PdfStream form) {
+ return AddResource(form, formNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as form.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// .
+ ///
+ /// added form resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddForm(PdfStream) instead.")]
public virtual PdfName AddForm(PdfObject form) {
+ if (form.GetObjectType() != PdfObject.STREAM) {
+ throw new PdfException(PdfException.CannotAddNonStreamFormToResources1).SetMessageParams(form.GetType().ToString
+ ());
+ }
return AddResource(form, formNamesGen);
}
@@ -150,39 +255,234 @@ public virtual PdfName AddForm(PdfFormXObject form, PdfName name) {
return name;
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added graphics state parameter dictionary resource name.
public virtual PdfName AddExtGState(PdfExtGState extGState) {
return AddResource(extGState, egsNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as graphics state parameter dictionary.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added graphics state parameter dictionary resources name.
+ public virtual PdfName AddExtGState(PdfDictionary extGState) {
+ return AddResource(extGState, egsNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as graphics state parameter dictionary.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// .
+ ///
+ /// added graphics state parameter dictionary resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddExtGState(PdfDictionary) instead."
+ )]
public virtual PdfName AddExtGState(PdfObject extGState) {
+ if (extGState.GetObjectType() != PdfObject.DICTIONARY) {
+ throw new PdfException(PdfException.CannotAddNonDictionaryExtGStateToResources1).SetMessageParams(extGState
+ .GetType().ToString());
+ }
return AddResource(extGState, egsNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as properties list.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added properties list resources name.
+ public virtual PdfName AddProperties(PdfDictionary properties) {
+ return AddResource(properties, propNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as properties list.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// .
+ ///
+ /// added properties list resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddProperties(PdfDictionary) instead."
+ )]
public virtual PdfName AddProperties(PdfObject properties) {
+ if (properties.GetObjectType() != PdfObject.DICTIONARY) {
+ throw new PdfException(PdfException.CannotAddNonDictionaryPropertiesToResources1).SetMessageParams(properties
+ .GetType().ToString());
+ }
return AddResource(properties, propNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added color space resource name.
public virtual PdfName AddColorSpace(PdfColorSpace cs) {
return AddResource(cs, csNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as color space.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added color space resources name.
public virtual PdfName AddColorSpace(PdfObject colorSpace) {
return AddResource(colorSpace, csNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added pattern resource name.
public virtual PdfName AddPattern(PdfPattern pattern) {
return AddResource(pattern, patternNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as pattern.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added pattern resources name.
+ public virtual PdfName AddPattern(PdfDictionary pattern) {
+ return AddResource(pattern, patternNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as pattern.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// added pattern resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddPattern(PdfDictionary) instead."
+ )]
public virtual PdfName AddPattern(PdfObject pattern) {
+ if (pattern is PdfDictionary) {
+ throw new PdfException(PdfException.CannotAddNonDictionaryPatternToResources1).SetMessageParams(pattern.GetType
+ ().ToString());
+ }
return AddResource(pattern, patternNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// object to the resources.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added shading resource name.
public virtual PdfName AddShading(PdfShading shading) {
return AddResource(shading, shadingNamesGen);
}
+ ///
+ /// Adds
+ ///
+ /// to the resources as shading dictionary.
+ ///
+ ///
+ /// the
+ ///
+ /// to add.
+ ///
+ /// added shading dictionary resources name.
+ public virtual PdfName AddShading(PdfDictionary shading) {
+ return AddResource(shading, shadingNamesGen);
+ }
+
+ ///
+ /// Adds
+ ///
+ /// to the resources as shading dictionary.
+ ///
+ ///
+ /// the
+ ///
+ /// to add. Should be
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// added shading dictionary resources name.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1. Use more safe AddShading(PdfDictionary) instead."
+ )]
public virtual PdfName AddShading(PdfObject shading) {
+ if (shading is PdfDictionary) {
+ throw new PdfException(PdfException.CannotAddNonDictionaryShadingToResources1).SetMessageParams(shading.GetType
+ ().ToString());
+ }
return AddResource(shading, shadingNamesGen);
}
@@ -202,31 +502,84 @@ protected internal virtual void SetModified(bool isModified) {
this.isModified = isModified;
}
- /// Sets the default color space.
- ///
- ///
- ///
+ /// Sets the default color space (see ISO-320001 Paragraph 8.6.5.6).
+ ///
+ /// the name of Default Color Space. Should be
+ ///
+ /// ,
+ ///
+ /// , or
+ ///
+ /// .
+ ///
+ /// the value of the default color space to be set.
+ [System.ObsoleteAttribute(@"Will be removed in iText 7.1.0. Use SetDefaultGray(iText.Kernel.Pdf.Colorspace.PdfColorSpace) ,SetDefaultRgb(iText.Kernel.Pdf.Colorspace.PdfColorSpace) or SetDefaultCmyk(iText.Kernel.Pdf.Colorspace.PdfColorSpace) instead."
+ )]
public virtual void SetDefaultColorSpace(PdfName defaultCsKey, PdfColorSpace defaultCsValue) {
+ if (!defaultCsKey.Equals(PdfName.DefaultCMYK) && !defaultCsKey.Equals(PdfName.DefaultGray) && !defaultCsKey
+ .Equals(PdfName.DefaultRGB)) {
+ throw new PdfException(PdfException.UnsupportedDefaultColorSpaceName1).SetMessageParams(defaultCsKey.ToString
+ ());
+ }
AddResource(defaultCsValue.GetPdfObject(), PdfName.ColorSpace, defaultCsKey);
}
+ /// Sets the value of default Gray Color Space (see ISO-320001 Paragraph 8.6.5.6).
+ /// the color space to set.
public virtual void SetDefaultGray(PdfColorSpace defaultCs) {
- SetDefaultColorSpace(PdfName.DefaultGray, defaultCs);
+ AddResource(defaultCs.GetPdfObject(), PdfName.ColorSpace, PdfName.DefaultGray);
}
+ /// Sets the value of default RGB Color Space (see ISO-320001 Paragraph 8.6.5.6).
+ /// the color space to set.
public virtual void SetDefaultRgb(PdfColorSpace defaultCs) {
- SetDefaultColorSpace(PdfName.DefaultRGB, defaultCs);
+ AddResource(defaultCs.GetPdfObject(), PdfName.ColorSpace, PdfName.DefaultRGB);
}
+ /// Sets the value of default CMYK Color Space (see ISO-320001 Paragraph 8.6.5.6).
+ /// the color space to set.
public virtual void SetDefaultCmyk(PdfColorSpace defaultCs) {
- SetDefaultColorSpace(PdfName.DefaultCMYK, defaultCs);
+ AddResource(defaultCs.GetPdfObject(), PdfName.ColorSpace, PdfName.DefaultCMYK);
}
+ ///
+ /// Gets the mapped resource name of the
+ ///
+ /// under the given wrapper.
+ ///
+ ///
+ /// Note: if the name for the object won't be found, then the name of object's Indirect Reference will be searched.
+ ///
+ ///
+ /// the wrapper of the
+ ///
+ /// , for which the name will be searched.
+ ///
+ ///
+ ///
+ /// the mapped resource name or
+ ///
+ /// if object isn't added to resources.
+ ///
public virtual PdfName GetResourceName(PdfObjectWrapper resource)
where T : PdfObject {
- return resourceToName.Get(resource.GetPdfObject());
+ return GetResourceName(resource.GetPdfObject());
}
+ ///
+ /// Gets the mapped resource name of the given
+ ///
+ /// .
+ ///
+ ///
+ /// Note: if the name for the object won't be found, then the name of object's Indirect Reference will be searched.
+ ///
+ /// the object, for which the name will be searched.
+ ///
+ /// the mapped resource name or
+ ///
+ /// if object isn't added to resources.
+ ///
public virtual PdfName GetResourceName(PdfObject resource) {
PdfName resName = resourceToName.Get(resource);
if (resName == null) {
@@ -235,6 +588,8 @@ public virtual PdfName GetResourceName(PdfObject resource) {
return resName;
}
+ /// Gets the names of all the added resources.
+ /// the name of all the added resources.
public virtual ICollection GetResourceNames() {
ICollection names = new SortedSet();
// TODO: isn't it better to use HashSet? Do we really need certain order?
@@ -244,44 +599,76 @@ public virtual ICollection GetResourceNames() {
return names;
}
+ /// Gets the array of predefined procedure set names (see ISO-320001 Paragraph 14.2).
+ /// the array of predefined procedure set names.
public virtual PdfArray GetProcSet() {
return GetPdfObject().GetAsArray(PdfName.ProcSet);
}
+ /// Sets the array of predefined procedure set names (see ISO-320001 Paragraph 14.2).
+ /// the array of predefined procedure set names to be set.
public virtual void SetProcSet(PdfArray array) {
GetPdfObject().Put(PdfName.ProcSet, array);
}
+ /// Gets the names of all resources of specified type.
+ ///
+ /// the resource type. Should be
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// .
+ ///
+ ///
+ /// set of resources name of corresponding type. May be empty.
+ /// Will be empty in case of incorrect resource type.
+ ///
public virtual ICollection GetResourceNames(PdfName resType) {
PdfDictionary resourceCategory = GetPdfObject().GetAsDictionary(resType);
return resourceCategory == null ? new SortedSet() : resourceCategory.KeySet();
}
// TODO: TreeSet or HashSet enough?
- public virtual PdfDictionary GetResource(PdfName pdfName) {
- return GetPdfObject().GetAsDictionary(pdfName);
- }
-
- // public List getFonts(boolean updateFonts) throws IOException {
- // if (updateFonts) {
- // getPdfObject().remove(PdfName.Font);
- // PdfDictionary fMap = getResource(PdfName.Font);
- // if (fMap != null) {
- // addFont(fMap.entrySet());
- // }
- // PdfDictionary xMap = getResource(PdfName.XObject);
- // if (xMap != null && !xMap.isEmpty()) {
- // callXObjectFont(xMap.entrySet(), new HashSet());
- // }
- // }
- // List fonts = new ArrayList<>();
- // for (PdfObject fontDict : getPdfObject().getAsDictionary(PdfName.Font).values()) {
- // if (fontDict.isDictionary()) {
- // fonts.add((PdfDictionary) fontDict);
- // }
- // }
- // return fonts;
- // }
+ ///
+ /// Get the
+ ///
+ /// object that that contain resources of specified type.
+ ///
+ ///
+ /// the resource type. Should be
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// .
+ ///
+ ///
+ /// the
+ ///
+ /// object containing all resources of specified type,
+ /// or
+ ///
+ /// in case of incorrect resource type.
+ ///
+ public virtual PdfDictionary GetResource(PdfName resType) {
+ return GetPdfObject().GetAsDictionary(resType);
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return false;
}
@@ -297,7 +684,7 @@ protected internal virtual void AddResource(PdfObject resource, PdfName resType,
CheckAndResolveCircularReferences(resource);
}
if (readOnly) {
- SetPdfObject(new PdfDictionary(GetPdfObject()));
+ SetPdfObject(GetPdfObject().Clone(JavaCollectionsUtil.EmptyList()));
BuildResources(GetPdfObject());
isModified = true;
readOnly = false;
@@ -343,47 +730,6 @@ protected internal virtual void BuildResources(PdfDictionary dictionary) {
}
}
- // private void addFont(Collection entrySet) throws IOException {
- // for (PdfObject entry : entrySet) {
- // PdfDictionary fonts = getPdfObject().getAsDictionary(PdfName.Font);
- // if (entry.isIndirectReference() && !fonts.containsValue(entry)) {
- // fonts.put((PdfIndirectReference) entry.getValue(),
- // PdfFont.createFont((PdfDictionary) ((PdfIndirectReference) entry.getValue()).getRefersTo()));
- // } else if (entry.getValue().isDictionary()) {
- // PdfFont font = PdfFont.createFont((PdfDictionary) entry.getValue());
- // fontsMap.put(font.getPdfObject().getIndirectReference(), font);
- // }
- // }
- // }
- // private void addFontFromXObject(Set> entrySet, Set visitedResources) throws IOException {
- // PdfDictionary xObject = new PdfDictionary(entrySet);
- // PdfDictionary resources = xObject.getAsDictionary(PdfName.Resources);
- // if (resources == null)
- // return;
- // PdfDictionary font = resources.getAsDictionary(PdfName.Font);
- //
- // if (font != null) {
- // addFont(font.values());
- // }
- // PdfDictionary xobj = resources.getAsDictionary(PdfName.XObject);
- // if (xobj != null) {
- // if (visitedResources.add(xobj)) {
- // callXObjectFont(xobj.entrySet(), visitedResources);
- // visitedResources.remove(xobj);
- // } else {
- // throw new IOException(IOException.IllegalResourceTree);
- // }
- // }
- // }
- // private void callXObjectFont(Set> entrySet, Set visitedResources) throws IOException {
- // for (Map.Entry entry : entrySet) {
- // if (entry.getValue().isIndirectReference()) {
- // if (((PdfIndirectReference) entry.getValue()).getRefersTo().isStream()) {
- // addFontFromXObject(((PdfStream) ((PdfIndirectReference) entry.getValue()).getRefersTo()).entrySet(), visitedResources);
- // }
- // }
- // }
- // }
private void CheckAndResolveCircularReferences(PdfObject pdfObject) {
// Consider the situation when an XObject references the resources of the first page.
// We add this XObject to the first page, there is no need to resolve any circular references
@@ -424,11 +770,19 @@ internal class ResourceNameGenerator {
/// class.
///
///
- /// Type of resource (
+ /// Type of resource. Should be
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
///
/// ,
///
- /// etc).
+ /// .
///
/// Prefix used for generating names.
///
@@ -447,23 +801,52 @@ public ResourceNameGenerator(PdfName resourceType, String prefix, int seed) {
/// class.
///
///
- /// Type of resource (
+ /// Type of resource. Should be
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
///
/// ,
///
- /// etc).
+ /// .
///
/// Prefix used for generating names.
public ResourceNameGenerator(PdfName resourceType, String prefix)
: this(resourceType, prefix, 1) {
}
+ /// Gets the resource type of generator.
+ ///
+ /// Type of resource. May be
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// .
+ ///
public virtual PdfName GetResourceType() {
return resourceType;
}
/// Generates new (unique) resource name.
- /// New (unique) resource name.
+ ///
+ /// the
+ ///
+ /// object for which name will be generated.
+ ///
+ /// new (unique) resource name.
public virtual PdfName Generate(PdfResources resources) {
PdfName newName = new PdfName(prefix + counter++);
PdfDictionary r = resources.GetPdfObject();
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfStream.cs b/itext/itext.kernel/itext/kernel/pdf/PdfStream.cs
index 18e9ee3c98..f1c79bc6fd 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfStream.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfStream.cs
@@ -72,7 +72,6 @@ public class PdfStream : PdfDictionary {
///
/// the compression level (0 = best speed, 9 = best compression, -1 is default)
///
- /// on error.
public PdfStream(byte[] bytes, int compressionLevel)
: base() {
// Output stream associated with PDF stream.
@@ -111,7 +110,6 @@ public PdfStream(byte[] bytes)
/// the data to write to this stream
/// the compression level (0 = best speed, 9 = best compression, -1 is default)
///
- /// on error.
public PdfStream(PdfDocument doc, Stream inputStream, int compressionLevel)
: base() {
if (doc == null) {
@@ -141,7 +139,6 @@ public PdfStream(PdfDocument doc, Stream inputStream, int compressionLevel)
///
///
/// the data to write to this stream
- /// on error.
public PdfStream(PdfDocument doc, Stream inputStream)
: this(doc, inputStream, CompressionConstants.UNDEFINED_COMPRESSION) {
}
@@ -153,7 +150,6 @@ public PdfStream(PdfDocument doc, Stream inputStream)
///
/// the compression level (0 = best speed, 9 = best compression, -1 is default)
///
- /// on error.
public PdfStream(int compressionLevel)
: this(null, compressionLevel) {
}
@@ -219,7 +215,6 @@ public virtual int GetLength() {
/// Gets decoded stream bytes.
/// byte[]
- ///
public virtual byte[] GetBytes() {
return GetBytes(true);
}
@@ -238,7 +233,6 @@ public virtual byte[] GetBytes() {
/// InputStream
/// .
///
- /// error.
public virtual byte[] GetBytes(bool decoded) {
if (inputStream != null) {
LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfStream)).Warn("PdfStream was created by InputStream." +
@@ -300,7 +294,7 @@ public virtual void SetData(byte[] bytes) {
///
public virtual void SetData(byte[] bytes, bool append) {
if (inputStream != null) {
- throw new PdfException(PdfException.CannotSetDataToPdfstreamWhichWasCreatedByInputstream);
+ throw new PdfException(PdfException.CannotSetDataToPdfstreamWhichWasCreatedByInputStream);
}
bool outputStreamIsUninitialized = outputStream == null;
if (outputStreamIsUninitialized) {
@@ -392,7 +386,6 @@ protected internal virtual long GetOffset() {
/// PdfReader.checkPdfStreamLength()
/// method.
///
- /// error.
protected internal virtual void UpdateLength(int length) {
this.length = length;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfString.cs b/itext/itext.kernel/itext/kernel/pdf/PdfString.cs
index 0ceb6b15db..d608819e13 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfString.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfString.cs
@@ -70,8 +70,6 @@ namespace iText.Kernel.Pdf {
///
///
public class PdfString : PdfPrimitiveObject {
- private static String defaultCharset = "UTF-8";
-
protected internal String value;
protected internal String encoding;
@@ -156,9 +154,13 @@ public virtual String GetEncoding() {
/// Sets the encoding of this string.
/// NOTE. Byte content will be removed.
///
+ [System.ObsoleteAttribute(@"Create a new instance with PdfString(System.String, System.String) instead.")]
public virtual void SetEncoding(String encoding) {
+ if (value == null) {
+ GenerateValue();
+ this.content = null;
+ }
this.encoding = encoding;
- this.content = null;
}
///
@@ -240,6 +242,26 @@ public override PdfObject CopyTo(PdfDocument document, bool allowDuplicating) {
return (iText.Kernel.Pdf.PdfString)base.CopyTo(document, allowDuplicating);
}
+ public override bool Equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || GetType() != o.GetType()) {
+ return false;
+ }
+ iText.Kernel.Pdf.PdfString that = (iText.Kernel.Pdf.PdfString)o;
+ String v1 = GetValue();
+ String v2 = that.GetValue();
+ if (v1 != null && v1.Equals(v2)) {
+ String e1 = GetEncoding();
+ String e2 = that.GetEncoding();
+ if ((e1 == null && e2 == null) || (e1 != null && e1.Equals(e2))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public override String ToString() {
if (value == null) {
return iText.IO.Util.JavaUtil.GetStringForBytes(PdfTokenizer.DecodeStringContent(content, hexWriting));
@@ -249,6 +271,13 @@ public override String ToString() {
}
}
+ public override int GetHashCode() {
+ String v = GetValue();
+ String e = GetEncoding();
+ int result = v != null ? v.GetHashCode() : 0;
+ return 31 * result + (e != null ? e.GetHashCode() : 0);
+ }
+
protected internal virtual void GenerateValue() {
System.Diagnostics.Debug.Assert(content != null, "No byte[] content to generate value");
value = PdfEncodings.ConvertToString(PdfTokenizer.DecodeStringContent(content, hexWriting), null);
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfVersion.cs b/itext/itext.kernel/itext/kernel/pdf/PdfVersion.cs
index 2975b99f39..bc2d3423c3 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfVersion.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfVersion.cs
@@ -45,14 +45,14 @@ source product.
using System.Collections.Generic;
namespace iText.Kernel.Pdf {
- /// Enum listing all official PDF versions.
+ /// This class represents all official PDF versions.
public class PdfVersion : IComparable {
private static readonly IList values = new List(
);
public static readonly iText.Kernel.Pdf.PdfVersion PDF_1_0 = CreatePdfVersion(1, 0);
- public static readonly iText.Kernel.Pdf.PdfVersion PDF_1_1 = CreatePdfVersion(1, 0);
+ public static readonly iText.Kernel.Pdf.PdfVersion PDF_1_1 = CreatePdfVersion(1, 1);
public static readonly iText.Kernel.Pdf.PdfVersion PDF_1_2 = CreatePdfVersion(1, 2);
@@ -72,7 +72,7 @@ public class PdfVersion : IComparable {
private int minor;
- /// Creates a PdfVersion enum.
+ /// Creates a PdfVersion class.
/// major version number
/// minor version number
private PdfVersion(int major, int minor) {
@@ -89,7 +89,7 @@ public virtual PdfName ToPdfName() {
}
///
- /// Creates a PdfVersion enum from a String object if the specified version
+ /// Creates a PdfVersion class from a String object if the specified version
/// can be found.
///
/// version number
@@ -104,7 +104,7 @@ public static iText.Kernel.Pdf.PdfVersion FromString(String value) {
}
///
- /// Creates a PdfVersion enum from a
+ /// Creates a PdfVersion class from a
///
/// object if the specified version
/// can be found.
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfWriter.cs b/itext/itext.kernel/itext/kernel/pdf/PdfWriter.cs
index 07bbbcceea..b2b46ddbe6 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfWriter.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfWriter.cs
@@ -57,11 +57,6 @@ public class PdfWriter : PdfOutputStream {
private static readonly byte[] endobj = ByteUtils.GetIsoBytes("\nendobj\n");
- private Dictionary streamMap = new Dictionary();
-
- private readonly IntHashtable serialized = new IntHashtable();
-
private PdfOutputStream duplicateStream = null;
protected internal WriterProperties properties;
@@ -73,9 +68,21 @@ public class PdfWriter : PdfOutputStream {
///
internal PdfObjectStream objectStream = null;
+ /// Is used to avoid duplications on object copying.
+ ///
+ /// Is used to avoid duplications on object copying.
+ /// It stores hashes of the indirect reference from the source document and the corresponding
+ /// indirect references of the copied objects from the new document.
+ ///
protected internal IDictionary copiedObjects = new Dictionary();
+ /// Is used in smart mode to store serialized objects content.
+ private Dictionary serializedContentToObjectRef = new
+ Dictionary();
+
+ private Dictionary objectRefToSerializedContent = new Dictionary();
+
protected internal bool isUserWarnedAboutAcroFormCopying;
public PdfWriter(Stream os)
@@ -83,7 +90,7 @@ public PdfWriter(Stream os)
}
public PdfWriter(Stream os, WriterProperties properties)
- : base(os) {
+ : base(FileUtil.WrapWithBufferedOutputStream(os)) {
// For internal usage only
//forewarned is forearmed
this.properties = properties;
@@ -185,16 +192,25 @@ public override void Write(byte[] b, int off, int len) {
///
public override void Close() {
- base.Close();
- if (duplicateStream != null) {
- duplicateStream.Close();
+ try {
+ base.Close();
+ }
+ finally {
+ try {
+ if (duplicateStream != null) {
+ duplicateStream.Close();
+ }
+ }
+ catch (Exception ex) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.PdfWriter));
+ logger.Error("Closing of the duplicatedStream failed.", ex);
+ }
}
}
/// Gets the current object stream.
/// object stream.
///
- ///
internal virtual PdfObjectStream GetObjectStream() {
if (!IsFullCompression()) {
return null;
@@ -216,8 +232,7 @@ internal virtual PdfObjectStream GetObjectStream() {
///
/// object to flush.
/// indicates whether object can be placed into object stream.
- ///
- ///
+ /// on error.
protected internal virtual void FlushObject(PdfObject pdfObject, bool canBeInObjStm) {
PdfIndirectReference indirectReference = pdfObject.GetIndirectReference();
if (IsFullCompression() && canBeInObjStm) {
@@ -276,28 +291,36 @@ protected internal virtual PdfObject CopyObject(PdfObject obj, PdfDocument docum
obj = PdfNull.PDF_NULL;
}
PdfIndirectReference indirectReference = obj.GetIndirectReference();
- PdfIndirectReference copiedIndirectReference;
int copyObjectKey = 0;
- if (!allowDuplicating && indirectReference != null) {
- copyObjectKey = GetCopyObjectKey(obj);
- copiedIndirectReference = copiedObjects.Get(copyObjectKey);
+ bool tryToFindDuplicate = !allowDuplicating && indirectReference != null;
+ if (tryToFindDuplicate) {
+ copyObjectKey = CalculateIndRefKey(indirectReference);
+ PdfIndirectReference copiedIndirectReference = copiedObjects.Get(copyObjectKey);
if (copiedIndirectReference != null) {
return copiedIndirectReference.GetRefersTo();
}
}
- if (properties.smartMode && !CheckTypeOfPdfDictionary(obj, PdfName.Page)) {
- PdfObject copiedObject = SmartCopyObject(obj);
- if (copiedObject != null) {
- return copiedObjects.Get(GetCopyObjectKey(copiedObject)).GetRefersTo();
+ if (obj.IsDictionary()) {
+ PdfName subtype = ((PdfDictionary)obj).GetAsName(PdfName.Subtype);
+ if (subtype != null && subtype.Equals(PdfName.Widget)) {
+ tryToFindDuplicate = false;
+ }
+ }
+ if (properties.smartMode && tryToFindDuplicate && !CheckTypeOfPdfDictionary(obj, PdfName.Page)) {
+ PdfIndirectReference copiedObjectRef = TryToFindPreviouslyCopiedEqualObject(obj);
+ if (copiedObjectRef != null) {
+ PdfIndirectReference copiedIndirectReference = copiedObjects.Get(CalculateIndRefKey(copiedObjectRef));
+ copiedObjects[copyObjectKey] = copiedIndirectReference;
+ return copiedIndirectReference.GetRefersTo();
}
}
PdfObject newObject = obj.NewInstance();
if (indirectReference != null) {
if (copyObjectKey == 0) {
- copyObjectKey = GetCopyObjectKey(obj);
+ copyObjectKey = CalculateIndRefKey(indirectReference);
}
- PdfIndirectReference reference = newObject.MakeIndirect(document).GetIndirectReference();
- copiedObjects[copyObjectKey] = reference;
+ PdfIndirectReference indRef = newObject.MakeIndirect(document).GetIndirectReference();
+ copiedObjects[copyObjectKey] = indRef;
}
newObject.CopyContent(obj, document);
return newObject;
@@ -306,7 +329,6 @@ protected internal virtual PdfObject CopyObject(PdfObject obj, PdfDocument docum
/// Writes object to body of PDF document.
/// object to write.
///
- ///
protected internal virtual void WriteToBody(PdfObject pdfObj) {
if (crypto != null) {
crypto.SetHashKeyForNextObject(pdfObj.GetIndirectReference().GetObjNumber(), pdfObj.GetIndirectReference()
@@ -319,14 +341,12 @@ protected internal virtual void WriteToBody(PdfObject pdfObj) {
}
/// Writes PDF header.
- ///
protected internal virtual void WriteHeader() {
WriteByte('%').WriteString(document.GetPdfVersion().ToString()).WriteString("\n%\u00e2\u00e3\u00cf\u00d3\n"
);
}
/// Flushes all objects which have not been flushed yet.
- ///
protected internal virtual void FlushWaitingObjects() {
PdfXrefTable xref = document.GetXref();
bool needFlush = true;
@@ -351,7 +371,6 @@ protected internal virtual void FlushWaitingObjects() {
/// Flushes all modified objects which have not been flushed yet.
/// Flushes all modified objects which have not been flushed yet. Used in case incremental updates.
- ///
protected internal virtual void FlushModifiedWaitingObjects() {
PdfXrefTable xref = document.GetXref();
for (int i = 1; i < xref.Size(); i++) {
@@ -369,6 +388,15 @@ protected internal virtual void FlushModifiedWaitingObjects() {
}
}
+ /// Calculates hash code for the indirect reference taking into account the document it belongs to.
+ /// object to be hashed.
+ /// calculated hash code.
+ protected internal static int CalculateIndRefKey(PdfIndirectReference indRef) {
+ int result = indRef.GetHashCode();
+ result = 31 * result + indRef.GetDocument().GetHashCode();
+ return result;
+ }
+
/// Calculates hash code for object to be copied.
///
/// Calculates hash code for object to be copied.
@@ -376,27 +404,41 @@ protected internal virtual void FlushModifiedWaitingObjects() {
///
/// object to be copied.
/// calculated hash code.
+ [System.ObsoleteAttribute(@"Functionality will be removed.")]
protected internal virtual int GetCopyObjectKey(PdfObject obj) {
- PdfIndirectReference reference;
- if (obj.IsIndirectReference()) {
- reference = (PdfIndirectReference)obj;
- }
- else {
- reference = obj.GetIndirectReference();
+ return CalculateIndRefKey(obj.GetIndirectReference());
+ }
+
+ /// Used in the smart mode.
+ ///
+ /// Used in the smart mode.
+ /// It serializes given object content and tries to find previously copied object with the same content.
+ /// If already copied object is not found, it saves current object serialized content into the map.
+ ///
+ /// an object to check if some other object with the same content was already copied.
+ /// indirect reference of the object with the same content, which already has a copy in the new document.
+ ///
+ private PdfIndirectReference TryToFindPreviouslyCopiedEqualObject(PdfObject @object) {
+ PdfWriter.SerializedPdfObject objectKey;
+ if (@object.IsStream() || @object.IsDictionary()) {
+ objectKey = new PdfWriter.SerializedPdfObject(@object, objectRefToSerializedContent);
+ PdfIndirectReference objectRef = serializedContentToObjectRef.Get(objectKey);
+ if (objectRef != null) {
+ return objectRef;
+ }
+ serializedContentToObjectRef[objectKey] = @object.GetIndirectReference();
}
- int result = reference.GetHashCode();
- result = 31 * result + reference.GetDocument().GetHashCode();
- return result;
+ return null;
}
private void MarkArrayContentToFlush(PdfArray array) {
- foreach (PdfObject item in array) {
- MarkObjectToFlush(item);
+ for (int i = 0; i < array.Size(); i++) {
+ MarkObjectToFlush(array.Get(i, false));
}
}
private void MarkDictionaryContentToFlush(PdfDictionary dictionary) {
- foreach (PdfObject item in dictionary.Values()) {
+ foreach (PdfObject item in dictionary.Values(false)) {
MarkObjectToFlush(item);
}
}
@@ -434,29 +476,6 @@ private iText.Kernel.Pdf.PdfWriter SetDebugMode() {
return this;
}
- private PdfObject SmartCopyObject(PdfObject obj) {
- PdfWriter.ByteStore streamKey;
- if (obj.IsStream()) {
- streamKey = new PdfWriter.ByteStore((PdfStream)obj, serialized);
- PdfIndirectReference streamRef = streamMap.Get(streamKey);
- if (streamRef != null) {
- return streamRef;
- }
- streamMap[streamKey] = obj.GetIndirectReference();
- }
- else {
- if (obj.IsDictionary()) {
- streamKey = new PdfWriter.ByteStore((PdfDictionary)obj, serialized);
- PdfIndirectReference streamRef = streamMap.Get(streamKey);
- if (streamRef != null) {
- return streamRef.GetRefersTo();
- }
- streamMap[streamKey] = obj.GetIndirectReference();
- }
- }
- return null;
- }
-
///
private byte[] GetDebugBytes() {
if (duplicateStream != null) {
@@ -473,14 +492,35 @@ private static bool CheckTypeOfPdfDictionary(PdfObject dictionary, PdfName expec
));
}
- internal class ByteStore {
- private readonly byte[] b;
+ internal class SerializedPdfObject {
+ private readonly byte[] serializedContent;
private readonly int hash;
private IDigest md5;
- private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb, IntHashtable serialized) {
+ private Dictionary objToSerializedContent;
+
+ internal SerializedPdfObject(PdfObject obj, Dictionary objToSerializedContent) {
+ System.Diagnostics.Debug.Assert(obj.IsDictionary() || obj.IsStream());
+ this.objToSerializedContent = objToSerializedContent;
+ try {
+ md5 = Org.BouncyCastle.Security.DigestUtilities.GetDigest("MD5");
+ }
+ catch (Exception e) {
+ throw new PdfException(e);
+ }
+ ByteBufferOutputStream bb = new ByteBufferOutputStream();
+ int level = 100;
+ SerObject(obj, level, bb);
+ this.serializedContent = bb.ToByteArray();
+ hash = CalculateHash(this.serializedContent);
+ md5 = null;
+ }
+
+ // TODO 2: object is not checked if it was already serialized on start, double work could be done
+ // TODO 3: indirect objects often stored multiple times as parts of the other objects
+ private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb) {
if (level <= 0) {
return;
}
@@ -490,21 +530,24 @@ private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb, IntH
}
PdfIndirectReference reference = null;
ByteBufferOutputStream savedBb = null;
+ int indRefKey = -1;
if (obj.IsIndirectReference()) {
reference = (PdfIndirectReference)obj;
- int key = GetCopyObjectKey(obj);
- if (serialized.ContainsKey(key)) {
- bb.Append((int)serialized.Get(key));
+ indRefKey = CalculateIndRefKey(reference);
+ byte[] cached = objToSerializedContent.Get(indRefKey);
+ if (cached != null) {
+ bb.Append(cached);
return;
}
else {
savedBb = bb;
bb = new ByteBufferOutputStream();
+ obj = reference.GetRefersTo();
}
}
if (obj.IsStream()) {
bb.Append("$B");
- SerDic((PdfDictionary)obj, level - 1, bb, serialized);
+ SerDic((PdfDictionary)obj, level - 1, bb);
if (level > 0) {
md5.Reset();
bb.Append(md5.Digest(((PdfStream)obj).GetBytes(false)));
@@ -512,11 +555,11 @@ private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb, IntH
}
else {
if (obj.IsDictionary()) {
- SerDic((PdfDictionary)obj, level - 1, bb, serialized);
+ SerDic((PdfDictionary)obj, level - 1, bb);
}
else {
if (obj.IsArray()) {
- SerArray((PdfArray)obj, level - 1, bb, serialized);
+ SerArray((PdfArray)obj, level - 1, bb);
}
else {
if (obj.IsString()) {
@@ -533,22 +576,20 @@ private void SerObject(PdfObject obj, int level, ByteBufferOutputStream bb, IntH
}
}
}
+ // PdfNull case is also here
if (savedBb != null) {
- int key = GetCopyObjectKey(reference);
- if (!serialized.ContainsKey(key)) {
- serialized.Put(key, CalculateHash(bb.GetBuffer()));
- }
+ objToSerializedContent[indRefKey] = bb.GetBuffer();
savedBb.Append(bb);
}
}
- private void SerDic(PdfDictionary dic, int level, ByteBufferOutputStream bb, IntHashtable serialized) {
+ private void SerDic(PdfDictionary dic, int level, ByteBufferOutputStream bb) {
bb.Append("$D");
if (level <= 0) {
return;
}
PdfName[] keys = new PdfName[dic.KeySet().Count];
- dic.KeySet().ToArray(keys);
+ keys = dic.KeySet().ToArray(keys);
iText.IO.Util.JavaUtil.Sort(keys);
foreach (Object key in keys) {
if (key.Equals(PdfName.P) && (dic.Get((PdfName)key).IsIndirectReference() || dic.Get((PdfName)key).IsDictionary
@@ -556,49 +597,19 @@ private void SerDic(PdfDictionary dic, int level, ByteBufferOutputStream bb, Int
// ignore recursive call
continue;
}
- SerObject((PdfObject)key, level, bb, serialized);
- SerObject(dic.Get((PdfName)key, false), level, bb, serialized);
+ SerObject((PdfObject)key, level, bb);
+ SerObject(dic.Get((PdfName)key, false), level, bb);
}
}
- private void SerArray(PdfArray array, int level, ByteBufferOutputStream bb, IntHashtable serialized) {
+ private void SerArray(PdfArray array, int level, ByteBufferOutputStream bb) {
bb.Append("$A");
if (level <= 0) {
return;
}
for (int k = 0; k < array.Size(); ++k) {
- SerObject(array.Get(k, false), level, bb, serialized);
- }
- }
-
- internal ByteStore(PdfStream str, IntHashtable serialized) {
- try {
- md5 = Org.BouncyCastle.Security.DigestUtilities.GetDigest("MD5");
- }
- catch (Exception e) {
- throw new PdfException(e);
- }
- ByteBufferOutputStream bb = new ByteBufferOutputStream();
- int level = 100;
- SerObject(str, level, bb, serialized);
- this.b = bb.ToByteArray();
- hash = CalculateHash(this.b);
- md5 = null;
- }
-
- internal ByteStore(PdfDictionary dict, IntHashtable serialized) {
- try {
- md5 = Org.BouncyCastle.Security.DigestUtilities.GetDigest("MD5");
- }
- catch (Exception e) {
- throw new PdfException(e);
+ SerObject(array.Get(k, false), level, bb);
}
- ByteBufferOutputStream bb = new ByteBufferOutputStream();
- int level = 100;
- SerObject(dict, level, bb, serialized);
- this.b = bb.ToByteArray();
- hash = CalculateHash(this.b);
- md5 = null;
}
private static int CalculateHash(byte[] b) {
@@ -611,26 +622,13 @@ private static int CalculateHash(byte[] b) {
}
public override bool Equals(Object obj) {
- return obj is PdfWriter.ByteStore && GetHashCode() == obj.GetHashCode() && iText.IO.Util.JavaUtil.ArraysEquals
- (b, ((PdfWriter.ByteStore)obj).b);
+ return obj is PdfWriter.SerializedPdfObject && GetHashCode() == obj.GetHashCode() && iText.IO.Util.JavaUtil.ArraysEquals
+ (serializedContent, ((PdfWriter.SerializedPdfObject)obj).serializedContent);
}
public override int GetHashCode() {
return hash;
}
-
- protected internal virtual int GetCopyObjectKey(PdfObject obj) {
- PdfIndirectReference reference;
- if (obj.IsIndirectReference()) {
- reference = (PdfIndirectReference)obj;
- }
- else {
- reference = obj.GetIndirectReference();
- }
- int result = reference.GetHashCode();
- result = 31 * result + reference.GetDocument().GetHashCode();
- return result;
- }
}
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/PdfXrefTable.cs b/itext/itext.kernel/itext/kernel/pdf/PdfXrefTable.cs
index 888d49e3b7..7a2216eec8 100644
--- a/itext/itext.kernel/itext/kernel/pdf/PdfXrefTable.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/PdfXrefTable.cs
@@ -43,8 +43,8 @@ source product.
*/
using System;
using System.Collections.Generic;
+using System.Text;
using iText.IO.Source;
-using iText.IO.Util;
using iText.Kernel;
namespace iText.Kernel.Pdf {
@@ -53,10 +53,6 @@ internal class PdfXrefTable {
private const int MAX_GENERATION = 65535;
- private const String objectOffsetFormatter = "0000000000";
-
- private const String objectGenerationFormatter = "00000";
-
private static readonly byte[] freeXRefEntry = ByteUtils.GetIsoBytes("f \n");
private static readonly byte[] inUseXRefEntry = ByteUtils.GetIsoBytes("n \n");
@@ -125,6 +121,13 @@ protected internal virtual PdfIndirectReference CreateNextIndirectReference(PdfD
return ((PdfIndirectReference)reference.SetState(PdfObject.MODIFIED));
}
+ //For Object streams
+ internal virtual PdfIndirectReference CreateNewIndirectReference(PdfDocument document) {
+ PdfIndirectReference reference = new PdfIndirectReference(document, ++count);
+ Add(reference);
+ return ((PdfIndirectReference)reference.SetState(PdfObject.MODIFIED));
+ }
+
protected internal virtual void FreeReference(PdfIndirectReference reference) {
reference.SetOffset(0);
reference.SetState(PdfObject.FREE);
@@ -148,7 +151,6 @@ protected internal virtual void SetCapacity(int capacity) {
/// Writes cross reference table and trailer to PDF.
///
- ///
protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject
crypto) {
PdfWriter writer = document.GetWriter();
@@ -282,9 +284,10 @@ protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, P
writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n');
for (int i_2 = first; i_2 < first + len; i_2++) {
PdfIndirectReference reference = xrefTable.Get(i_2);
- writer.WriteString(DecimalFormatUtil.FormatNumber(reference.GetOffset(), objectOffsetFormatter)).WriteSpace
- ().WriteString(DecimalFormatUtil.FormatNumber(reference.GetGenNumber(), objectGenerationFormatter)).WriteSpace
- ();
+ StringBuilder off = new StringBuilder("0000000000").Append(reference.GetOffset());
+ StringBuilder gen = new StringBuilder("00000").Append(reference.GetGenNumber());
+ writer.WriteString(off.JSubstring(off.Length - 10, off.Length)).WriteSpace().WriteString(gen.JSubstring(gen
+ .Length - 5, gen.Length)).WriteSpace();
if (reference.IsFree()) {
writer.WriteBytes(freeXRefEntry);
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfAction.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfAction.cs
index dbb88c42a7..55f006ac9e 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfAction.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfAction.cs
@@ -50,103 +50,182 @@ source product.
using iText.Kernel.Pdf.Navigation;
namespace iText.Kernel.Pdf.Action {
+ /// A wrapper for action dictionaries (ISO 32000-1 section 12.6).
+ ///
+ /// A wrapper for action dictionaries (ISO 32000-1 section 12.6).
+ /// An action dictionary defines the characteristics and behaviour of an action.
+ ///
public class PdfAction : PdfObjectWrapper {
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_EXCLUDE = 1;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_INCLUDE_NO_VALUE_FIELDS = 2;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_HTML_FORMAT = 4;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_HTML_GET = 8;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_COORDINATES = 16;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_XFDF = 32;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_INCLUDE_APPEND_SAVES = 64;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_INCLUDE_ANNOTATIONS = 128;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_PDF = 256;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_CANONICAL_FORMAT = 512;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_EXCL_NON_USER_ANNOTS = 1024;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_EXCL_F_KEY = 2048;
- /// a possible submitvalue
+ /// A possible submit value
public const int SUBMIT_EMBED_FORM = 8196;
- /// a possible submitvalue
+ /// A possible submit value
public const int RESET_EXCLUDE = 1;
+ /// Constructs an empty action that can be further modified.
public PdfAction()
: this(new PdfDictionary()) {
Put(PdfName.Type, PdfName.Action);
}
+ ///
+ /// Constructs a
+ ///
+ /// instance with a given dictionary. It can be used for handy
+ /// property reading in reading mode or modifying in stamping mode.
+ ///
+ /// the dictionary to construct the wrapper around
public PdfAction(PdfDictionary pdfObject)
: base(pdfObject) {
MarkObjectAsIndirect(GetPdfObject());
}
+ /// Creates a GoTo action (section 12.6.4.2 of ISO 32000-1) via a given destination.
+ /// the desired destination of the action
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoTo(PdfDestination destination) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.GoTo).Put(PdfName.D, destination.GetPdfObject
());
}
+ ///
+ /// Creates a GoTo action (section 12.6.4.2 of ISO 32000-1) via a given
+ ///
+ /// name.
+ ///
+ ///
+ ///
+ ///
+ /// name
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoTo(String destination) {
return CreateGoTo(new PdfStringDestination(destination));
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the file in which the destination shall be located
+ /// the destination in the remote document to jump to
+ /// a flag specifying whether to open the destination document in a new window
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(PdfFileSpec fileSpec, PdfDestination destination
, bool newWindow) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.GoToR).Put(PdfName.F, fileSpec.GetPdfObject
()).Put(PdfName.D, destination.GetPdfObject()).Put(PdfName.NewWindow, new PdfBoolean(newWindow));
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the file in which the destination shall be located
+ /// the destination in the remote document to jump to
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(PdfFileSpec fileSpec, PdfDestination destination
) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.GoToR).Put(PdfName.F, fileSpec.GetPdfObject
()).Put(PdfName.D, destination.GetPdfObject());
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the remote destination file to jump to
+ /// the remote destination document page to jump to
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(String filename, int pageNum) {
return CreateGoToR(filename, pageNum, false);
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the remote destination file to jump to
+ /// the remote destination document page to jump to
+ /// a flag specifying whether to open the destination document in a new window
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(String filename, int pageNum, bool newWindow) {
return CreateGoToR(new PdfStringFS(filename), PdfExplicitDestination.CreateFitH(pageNum, 10000), newWindow
);
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the remote destination file to jump to
+ /// the string destination in the remote document to jump to
+ /// a flag specifying whether to open the destination document in a new window
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(String filename, String destination, bool newWindow
) {
return CreateGoToR(new PdfStringFS(filename), new PdfStringDestination(destination), newWindow);
}
+ /// Creates a GoToR action, or remote action (section 12.6.4.3 of ISO 32000-1).
+ /// the remote destination file to jump to
+ /// the string destination in the remote document to jump to
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToR(String filename, String destination) {
return CreateGoToR(filename, destination, false);
}
+ /// Creates a GoToE action, or embedded file action (section 12.6.4.4 of ISO 32000-1).
+ /// the destination in the target to jump to
+ ///
+ /// if true, the destination document should be opened in a new window;
+ /// if false, the destination document should replace the current document in the same window
+ ///
+ ///
+ /// A target dictionary specifying path information to the target document.
+ /// Each target dictionary specifies one element in the full path to the target and
+ /// may have nested target dictionaries specifying additional elements
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToE(PdfDestination destination, bool newWindow, PdfTargetDictionary
targetDictionary) {
return CreateGoToE(null, destination, newWindow, targetDictionary);
}
+ /// Creates a GoToE action, or embedded file action (section 12.6.4.4 of ISO 32000-1).
+ /// The root document of the target relative to the root document of the source
+ /// the destination in the target to jump to
+ ///
+ /// if true, the destination document should be opened in a new window;
+ /// if false, the destination document should replace the current document in the same window
+ ///
+ ///
+ /// A target dictionary specifying path information to the target document.
+ /// Each target dictionary specifies one element in the full path to the target and
+ /// may have nested target dictionaries specifying additional elements
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateGoToE(PdfFileSpec fileSpec, PdfDestination destination
, bool newWindow, PdfTargetDictionary targetDictionary) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.
@@ -163,10 +242,19 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateGoToE(PdfFileSpec fileSpec
return action;
}
+ /// Creates a Launch action (section 12.6.4.5 of ISO 32000-1).
+ /// the application that shall be launched or the document that shall beopened or printed
+ ///
+ /// a flag specifying whether to open the destination document in a new window
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateLaunch(PdfFileSpec fileSpec, bool newWindow) {
return CreateLaunch(fileSpec, null, newWindow);
}
+ /// Creates a Launch action (section 12.6.4.5 of ISO 32000-1).
+ /// the application that shall be launched or the document that shall beopened or printed
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateLaunch(PdfFileSpec fileSpec) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.
Launch);
@@ -176,6 +264,12 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateLaunch(PdfFileSpec fileSpe
return action;
}
+ /// Creates a Launch action (section 12.6.4.5 of ISO 32000-1).
+ /// the application that shall be launched or the document that shall beopened or printed
+ ///
+ /// A dictionary containing Windows-specific launch parameters
+ /// a flag specifying whether to open the destination document in a new window
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateLaunch(PdfFileSpec fileSpec, PdfWin win, bool newWindow
) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.
@@ -189,6 +283,18 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateLaunch(PdfFileSpec fileSpe
return action;
}
+ /// Creates a Thread action (section 12.6.4.6 of ISO 32000-1).
+ ///
+ /// Creates a Thread action (section 12.6.4.6 of ISO 32000-1).
+ /// A thread action jumps to a specified bead on an article thread (see 12.4.3, “Articles”),
+ /// in either the current document or a different one. Table 205 shows the action dictionary
+ /// entries specific to this type of action.
+ ///
+ /// the file containing the thread. If this entry is absent, the thread is in the current file
+ ///
+ /// the destination thread
+ /// the bead in the destination thread
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateThread(PdfFileSpec fileSpec, PdfObject destinationThread
, PdfObject bead) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.
@@ -199,30 +305,84 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateThread(PdfFileSpec fileSpe
return action;
}
+ /// Creates a Thread action (section 12.6.4.6 of ISO 32000-1).
+ ///
+ /// Creates a Thread action (section 12.6.4.6 of ISO 32000-1).
+ /// A thread action jumps to a specified bead on an article thread (see 12.4.3, “Articles”),
+ /// in either the current document or a different one. Table 205 shows the action dictionary
+ /// entries specific to this type of action.
+ ///
+ /// the file containing the thread. If this entry is absent, the thread is in the current file
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateThread(PdfFileSpec fileSpec) {
return CreateThread(fileSpec, null, null);
}
+ /// Creates a URI action (section 12.6.4.7 of ISO 32000-1).
+ /// the uniform resource identifier to resolve
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateURI(String uri) {
return CreateURI(uri, false);
}
+ /// Creates a URI action (section 12.6.4.7 of ISO 32000-1).
+ /// the uniform resource identifier to resolve
+ /// a flag specifying whether to track the mouse position when the URI is resolved
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateURI(String uri, bool isMap) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.URI).Put(PdfName.URI, new PdfString(
uri)).Put(PdfName.IsMap, new PdfBoolean(isMap));
}
+ /// Creates a Sound action (section 12.6.4.8 of ISO 32000-1).
+ /// a sound object defining the sound that shall be played (see section 13.3 of ISO 32000-1)
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateSound(PdfStream sound) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Sound).Put(PdfName.Sound, sound);
}
+ /// Creates a Sound action (section 12.6.4.8 of ISO 32000-1).
+ /// a sound object defining the sound that shall be played (see section 13.3 of ISO 32000-1)
+ ///
+ /// the volume at which to play the sound, in the range -1.0 to 1.0. Default value: 1.0
+ ///
+ /// a flag specifying whether to play the sound synchronously or asynchronously.
+ /// If this flag is true, the conforming reader retains control, allowing no further user
+ /// interaction other than canceling the sound, until the sound has been completely played.
+ /// Default value: false
+ ///
+ ///
+ /// a flag specifying whether to repeat the sound indefinitely
+ /// If this entry is present, the Synchronous entry shall be ignored. Default value: false
+ ///
+ /// a flag specifying whether to mix this sound with any other sound already playing
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateSound(PdfStream sound, float volume, bool synchronous
, bool repeat, bool mix) {
+ if (volume < -1 || volume > 1) {
+ throw new ArgumentException("volume");
+ }
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Sound).Put(PdfName.Sound, sound).Put
(PdfName.Volume, new PdfNumber(volume)).Put(PdfName.Synchronous, new PdfBoolean(synchronous)).Put(PdfName
.Repeat, new PdfBoolean(repeat)).Put(PdfName.Mix, new PdfBoolean(mix));
}
+ /// Creates a Movie annotation (section 12.6.4.9 of ISO 32000-1).
+ /// a movie annotation identifying the movie that shall be played
+ /// the title of a movie annotation identifying the movie that shall be played
+ ///
+ /// the operation that shall be performed on the movie. Shall be one of the following:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
+ /// created annotation
public static iText.Kernel.Pdf.Action.PdfAction CreateMovie(PdfAnnotation annotation, String title, PdfName
operation) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.
@@ -233,34 +393,90 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateMovie(PdfAnnotation annota
return action;
}
+ /// Creates a Hide action (section 12.6.4.10 of ISO 32000-1).
+ /// the annotation to be hidden or shown
+ /// a flag indicating whether to hide the annotation (true) or show it (false)
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateHide(PdfAnnotation annotation, bool hidden) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Hide).Put(PdfName.T, annotation.GetPdfObject
()).Put(PdfName.H, new PdfBoolean(hidden));
}
+ /// Creates a Hide action (section 12.6.4.10 of ISO 32000-1).
+ /// the annotations to be hidden or shown
+ /// a flag indicating whether to hide the annotation (true) or show it (false)
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateHide(PdfAnnotation[] annotations, bool hidden) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Hide).Put(PdfName.T, GetPdfArrayFromAnnotationsList
(annotations)).Put(PdfName.H, new PdfBoolean(hidden));
}
+ /// Creates a Hide action (section 12.6.4.10 of ISO 32000-1).
+ ///
+ /// a text string giving the fully qualified field name of an interactive form field whose
+ /// associated widget annotation or annotations are to be affected
+ ///
+ /// a flag indicating whether to hide the annotation (true) or show it (false)
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateHide(String text, bool hidden) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Hide).Put(PdfName.T, new PdfString(text
)).Put(PdfName.H, new PdfBoolean(hidden));
}
+ /// Creates a Hide action (section 12.6.4.10 of ISO 32000-1).
+ ///
+ /// a text string array giving the fully qualified field names of interactive form fields whose
+ /// associated widget annotation or annotations are to be affected
+ ///
+ /// a flag indicating whether to hide the annotation (true) or show it (false)
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateHide(String[] text, bool hidden) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Hide).Put(PdfName.T, GetArrayFromStringList
(text)).Put(PdfName.H, new PdfBoolean(hidden));
}
+ /// Creates a Named action (section 12.6.4.11 of ISO 32000-1).
+ ///
+ /// the name of the action that shall be performed. Shall be one of the following:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateNamed(PdfName namedAction) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Named).Put(PdfName.N, namedAction);
}
+ /// Creates a Set-OCG-State action (section 12.6.4.12 of ISO 32000-1).
+ ///
+ /// a list of
+ ///
+ /// state descriptions
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateSetOcgState(IList states) {
return CreateSetOcgState(states, false);
}
+ /// Creates a Set-OCG-State action (section 12.6.4.12 of ISO 32000-1).
+ ///
+ /// states a list of
+ ///
+ /// state descriptions
+ ///
+ ///
+ /// If true, indicates that radio-button state relationships between optional content groups
+ /// should be preserved when the states are applied
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateSetOcgState(IList states, bool preserveRb
) {
PdfArray stateArr = new PdfArray();
@@ -271,6 +487,12 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateSetOcgState(IListCreates a Rendition action (section 12.6.4.13 of ISO 32000-1).
+ /// the name of the media clip, for use in the user interface.
+ /// a full file specification or form XObject that specifies the actual media data
+ /// an ASCII string identifying the type of data
+ /// a screen annotation
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateRendition(String file, PdfFileSpec fileSpec, String
mimeType, PdfAnnotation screenAnnotation) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.Rendition).Put(PdfName.OP, new PdfNumber
@@ -278,18 +500,33 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateRendition(String file, Pdf
mimeType).GetPdfObject());
}
+ /// Creates a JavaScript action (section 12.6.4.16 of ISO 32000-1).
+ /// a text string containing the JavaScript script to be executed.
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateJavaScript(String javaScript) {
return new iText.Kernel.Pdf.Action.PdfAction().Put(PdfName.S, PdfName.JavaScript).Put(PdfName.JS, new PdfString
(javaScript));
}
+ /// Creates a Submit-Form Action (section 12.7.5.2 of ISO 32000-1).
+ /// a uniform resource locator, as described in 7.11.5, "URL Specifications"
+ ///
+ /// an array identifying which fields to include in the submission or which to exclude,
+ /// depending on the setting of the Include/Exclude flag in the Flags entry.
+ /// This is an optional parameter and can be null
+ ///
+ ///
+ /// a set of flags specifying various characteristics of the action (see Table 237 of ISO 32000-1).
+ /// Default value to be passed: 0.
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateSubmitForm(String file, Object[] names, int flags) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction();
action.Put(PdfName.S, PdfName.SubmitForm);
- PdfDictionary dic = new PdfDictionary();
- dic.Put(PdfName.F, new PdfString(file));
- dic.Put(PdfName.FS, PdfName.URL);
- action.Put(PdfName.F, dic);
+ PdfDictionary urlFileSpec = new PdfDictionary();
+ urlFileSpec.Put(PdfName.F, new PdfString(file));
+ urlFileSpec.Put(PdfName.FS, PdfName.URL);
+ action.Put(PdfName.F, urlFileSpec);
if (names != null) {
action.Put(PdfName.Fields, BuildArray(names));
}
@@ -297,6 +534,16 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateSubmitForm(String file, Ob
return action;
}
+ /// Creates a Reset-Form Action (section 12.7.5.3 of ISO 32000-1).
+ ///
+ /// an array identifying which fields to reset or which to exclude from resetting,
+ /// depending on the setting of the Include/Exclude flag in the Flags entry (see Table 239 of ISO 32000-1).
+ ///
+ ///
+ /// a set of flags specifying various characteristics of the action (see Table 239 of ISO 32000-1).
+ /// Default value to be passed: 0.
+ ///
+ /// created action
public static iText.Kernel.Pdf.Action.PdfAction CreateResetForm(Object[] names, int flags) {
iText.Kernel.Pdf.Action.PdfAction action = new iText.Kernel.Pdf.Action.PdfAction();
action.Put(PdfName.S, PdfName.ResetForm);
@@ -307,6 +554,22 @@ public static iText.Kernel.Pdf.Action.PdfAction CreateResetForm(Object[] names,
return action;
}
+ ///
+ /// Adds an additional action to the provided
+ /// PdfObjectWrapper
+ /// wrapper.
+ ///
+ /// the wrapper to add an additional action to
+ ///
+ /// a
+ ///
+ /// specifying the name of an additional action
+ ///
+ ///
+ /// the
+ ///
+ /// to add as an additional action
+ ///
public static void SetAdditionalAction(PdfObjectWrapper wrapper, PdfName key, iText.Kernel.Pdf.Action.PdfAction
action) {
PdfDictionary dic;
@@ -321,30 +584,62 @@ public static void SetAdditionalAction(PdfObjectWrapper wrapper,
wrapper.GetPdfObject().Put(PdfName.AA, dic);
}
- /// Add a chained action.
- ///
- public virtual void Next(iText.Kernel.Pdf.Action.PdfAction na) {
- PdfObject nextAction = GetPdfObject().Get(PdfName.Next);
- if (nextAction == null) {
- Put(PdfName.Next, na.GetPdfObject());
+ /// Adds a chained action.
+ /// the next action or sequence of actions that shall be performed after the current action
+ ///
+ public virtual void Next(iText.Kernel.Pdf.Action.PdfAction nextAction) {
+ PdfObject currentNextAction = GetPdfObject().Get(PdfName.Next);
+ if (currentNextAction == null) {
+ Put(PdfName.Next, nextAction.GetPdfObject());
}
else {
- if (nextAction.IsDictionary()) {
- PdfArray array = new PdfArray(nextAction);
- array.Add(na.GetPdfObject());
+ if (currentNextAction.IsDictionary()) {
+ PdfArray array = new PdfArray(currentNextAction);
+ array.Add(nextAction.GetPdfObject());
Put(PdfName.Next, array);
}
else {
- ((PdfArray)nextAction).Add(na.GetPdfObject());
+ ((PdfArray)currentNextAction).Add(nextAction.GetPdfObject());
}
}
}
+ ///
+ /// Inserts the value into the underlying object of this
+ ///
+ /// and associates it with the specified key.
+ /// If the key is already present in this
+ ///
+ /// , this method will override the old value with the specified one.
+ ///
+ /// key to insert or to override
+ /// the value to associate with the specified key
+ ///
+ /// this
+ ///
+ /// instance
+ ///
public virtual iText.Kernel.Pdf.Action.PdfAction Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfActionOcgState.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfActionOcgState.cs
index 32f88de906..059645960d 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfActionOcgState.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfActionOcgState.cs
@@ -45,26 +45,74 @@ source product.
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Action {
- /// USed in Set OCG State actions.
+ /// This is a helper class for optional content states use in Set-OCG-State actions.
+ ///
+ /// This is a helper class for optional content states use in Set-OCG-State actions.
+ /// See
+ ///
+ /// .
+ ///
public class PdfActionOcgState {
- /// Can be: OFF, ON, Toggle
+ ///
+ /// Can be:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
private PdfName state;
+ /// Optional content group dictionaries
private IList ocgs;
+ /// Constructs an optional content state object.
+ ///
+ /// a
+ ///
+ /// describing the state. Shall be one of the following:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
+ /// a list of the OCG dictionaries
public PdfActionOcgState(PdfName state, IList ocgs) {
this.state = state;
this.ocgs = ocgs;
}
+ /// Gets the state the optional content groups should be switched to
+ ///
+ /// the state, one of the following:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
public virtual PdfName GetState() {
return state;
}
+ /// Gets a list of optional content groups that shall have the state changed
+ /// the list of optional content groups
public virtual IList GetOcgs() {
return ocgs;
}
+ ///
+ /// Gets a list of
+ ///
+ /// that is describing this particular optional content group states.
+ ///
+ ///
+ /// a list of
+ ///
+ /// for construction of a
+ ///
+ ///
public virtual IList GetObjectList() {
IList states = new List();
states.Add(state);
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfMediaClipData.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfMediaClipData.cs
index 952fbfdb15..be03c5f71a 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfMediaClipData.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfMediaClipData.cs
@@ -46,13 +46,29 @@ source product.
using iText.Kernel.Pdf.Filespec;
namespace iText.Kernel.Pdf.Action {
+ /// This class is a wrapper of media clip data dictionary that defines the data for a media object that can be played.
+ ///
public class PdfMediaClipData : PdfObjectWrapper {
private static readonly PdfString TEMPACCESS = new PdfString("TEMPACCESS");
+ ///
+ /// Constructs a new
+ ///
+ /// wrapper using an existing dictionary.
+ ///
+ /// the dictionary to construct the wrapper from
public PdfMediaClipData(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ ///
+ /// Constructs a new
+ ///
+ /// wrapper around a newly created dictionary.
+ ///
+ /// the name of the file to create a media clip for
+ /// a file specification that specifies the actual media data
+ /// an ASCII string identifying the type of data
public PdfMediaClipData(String file, PdfFileSpec fs, String mimeType)
: this(new PdfDictionary()) {
PdfDictionary dic = new PdfDictionary();
@@ -66,6 +82,22 @@ public PdfMediaClipData(String file, PdfFileSpec fs, String mimeType)
GetPdfObject().Put(PdfName.D, fs.GetPdfObject());
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfRendition.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfRendition.cs
index a303a64553..3e7d0bcbb8 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfRendition.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfRendition.cs
@@ -46,11 +46,22 @@ source product.
using iText.Kernel.Pdf.Filespec;
namespace iText.Kernel.Pdf.Action {
+ /// This a wrapper around a rendition dictionary.
+ /// This a wrapper around a rendition dictionary. See ISO 32000-1 sections 13.2.3.2, 13.2.3.3.
public class PdfRendition : PdfObjectWrapper {
+ ///
+ /// Creates a new wrapper around an existing
+ ///
+ ///
+ /// a rendition object to create a wrapper for
public PdfRendition(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ /// Creates a new wrapper around a newly created media rendition dictionary object.
+ /// a text string specifying the name of the file to display
+ /// a file specification that specifies the actual media data
+ /// an ASCII string identifying the type of data
public PdfRendition(String file, PdfFileSpec fs, String mimeType)
: this(new PdfDictionary()) {
GetPdfObject().Put(PdfName.S, PdfName.MR);
@@ -58,6 +69,22 @@ public PdfRendition(String file, PdfFileSpec fs, String mimeType)
GetPdfObject().Put(PdfName.C, new PdfMediaClipData(file, fs, mimeType).GetPdfObject());
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfTargetDictionary.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfTargetDictionary.cs
index a2341487ee..2744a07d0a 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfTargetDictionary.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfTargetDictionary.cs
@@ -45,92 +45,249 @@ source product.
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Action {
+ ///
+ /// A target dictionary locates the target in relation to the source,
+ /// in much the same way that a relative path describes the physical
+ /// relationship between two files in a file system.
+ ///
+ ///
+ /// A target dictionary locates the target in relation to the source,
+ /// in much the same way that a relative path describes the physical
+ /// relationship between two files in a file system. Target dictionaries may be
+ /// nested recursively to specify one or more intermediate targets before reaching the final one.
+ ///
public class PdfTargetDictionary : PdfObjectWrapper {
+ ///
+ /// Creates a new
+ ///
+ /// object by the underlying dictionary.
+ ///
+ /// the underlying dictionary object
public PdfTargetDictionary(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ ///
+ /// Creates a new
+ ///
+ /// object given its type. The type must be either
+ ///
+ /// , or
+ ///
+ /// . If it is
+ ///
+ /// , additional entries must be specified
+ /// according to the spec.
+ ///
+ /// the relationship between the current document and the target
public PdfTargetDictionary(PdfName r)
: this(new PdfDictionary()) {
Put(PdfName.R, r);
}
+ ///
+ /// Creates a new
+ ///
+ /// object.
+ ///
+ /// the relationship between the current document and the target
+ /// the name of the file in the EmbeddedFiles name tree
+ ///
+ /// if the value is an integer, it specifies the page number (zero-based) in the current
+ /// document containing the file attachment annotation. If the value is a string,
+ /// it specifies a named destination in the current document that provides the page
+ /// number of the file attachment annotation
+ ///
+ ///
+ /// If the value is an integer, it specifies the index (zero-based) of the annotation in the
+ /// Annots array of the page specified by P. If the value is a text string,
+ /// it specifies the value of NM in the annotation dictionary
+ ///
+ ///
+ /// A target dictionary specifying additional path information to the target document.
+ /// If this entry is absent, the current document is the target file containing the destination
+ ///
public PdfTargetDictionary(PdfName r, PdfString n, PdfObject p, PdfObject a, iText.Kernel.Pdf.Action.PdfTargetDictionary
t)
: this(new PdfDictionary()) {
Put(PdfName.R, r).Put(PdfName.N, n).Put(PdfName.P, p).Put(PdfName.A, a).Put(PdfName.T, t.GetPdfObject());
}
- /// Sets the name of the file in the EmbeddedFiles name tree.
+ /// Creates a new target object pointing to the parent of the current document.
+ ///
+ /// created
+ ///
+ ///
+ public static iText.Kernel.Pdf.Action.PdfTargetDictionary CreateParentTarget() {
+ return new iText.Kernel.Pdf.Action.PdfTargetDictionary(PdfName.P);
+ }
+
+ /// Creates a new target object pointing to a file in the EmbeddedFiles name tree.
+ /// the name of the file in the EmbeddedFiles name tree
+ /// created object
+ public static iText.Kernel.Pdf.Action.PdfTargetDictionary CreateChildTarget(String embeddedFileName) {
+ return new iText.Kernel.Pdf.Action.PdfTargetDictionary(PdfName.C).Put(PdfName.N, new PdfString(embeddedFileName
+ ));
+ }
+
+ /// Creates a new target object pointing to a file attachment annotation.
+ ///
+ /// a named destination in the current document that
+ /// provides the page number of the file attachment annotation
+ ///
+ ///
+ /// a unique annotation identifier (
+ ///
+ /// entry) of the annotation
+ ///
+ /// created object
+ public static iText.Kernel.Pdf.Action.PdfTargetDictionary CreateChildTarget(String namedDestination, String
+ annotationIdentifier) {
+ return new iText.Kernel.Pdf.Action.PdfTargetDictionary(PdfName.C).Put(PdfName.P, new PdfString(namedDestination
+ )).Put(PdfName.A, new PdfString(annotationIdentifier));
+ }
+
+ /// Creates a new target object pointing to a file attachment annotation.
+ /// the number of the page in the current document, one-based
+ /// the index of the annotation in the Annots entry of the page, zero-based
+ /// created object
+ public static iText.Kernel.Pdf.Action.PdfTargetDictionary CreateChildTarget(int pageNumber, int annotationIndex
+ ) {
+ return new iText.Kernel.Pdf.Action.PdfTargetDictionary(PdfName.C).Put(PdfName.P, new PdfNumber(pageNumber
+ - 1)).Put(PdfName.A, new PdfNumber(annotationIndex));
+ }
+
+ ///
+ /// Sets the name of the file in the EmbeddedFiles name tree for the child target located
+ /// in the EmbeddedFiles.
+ ///
/// the name of the file
- ///
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetName(String name) {
return Put(PdfName.N, new PdfString(name));
}
- /// Gets name of the file
- ///
+ ///
+ /// Gets name of the file in the EmbeddedFiles name tree for the child target located
+ /// in the EmbeddedFiles.
+ ///
+ /// the name of the child file for this target
public virtual PdfString GetName() {
return GetPdfObject().GetAsString(PdfName.N);
}
- /// Sets the page number in the current document containing the file attachment annotation.
- ///
- ///
+ ///
+ /// Sets the page number in the current document containing the file attachment annotation for the
+ /// child target associates with a file attachment annotation.
+ ///
+ ///
+ /// the page number (one-based) in the current document containing
+ /// the file attachment annotation
+ ///
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetPage(int pageNumber) {
- return Put(PdfName.P, new PdfNumber(pageNumber));
+ return Put(PdfName.P, new PdfNumber(pageNumber - 1));
}
- /// Sets a named destination in the current document that provides the page number of the file attachment annotation.
- ///
- ///
- ///
+ ///
+ /// Sets a named destination in the current document that provides the page number of the file
+ /// attachment annotation for the child target associated with a file attachment annotation.
+ ///
+ ///
+ /// a named destination in the current document that provides the page
+ /// number of the file attachment annotation
+ ///
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetPage(String namedDestination) {
return Put(PdfName.P, new PdfString(namedDestination));
}
- /// Get the page number or a named destination that provides the page number containing the file attachment annotation
- ///
- ///
+ /// Get the contents of the /P entry of this target object.
+ ///
+ /// Get the contents of the /P entry of this target object.
+ /// If the value is an integer, it specifies the page number (zero-based)
+ /// in the current document containing the file attachment annotation.
+ /// If the value is a string, it specifies a named destination in the current
+ /// document that provides the page number of the file attachment annotation.
+ ///
+ /// the /P entry of target object
public virtual PdfObject GetPage() {
return GetPdfObject().Get(PdfName.P);
}
- /// Sets the index of the annotation in Annots array of the page specified by /P entry.
- ///
- ///
- public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetAnnotation(int annotNumber) {
- return Put(PdfName.A, new PdfNumber(annotNumber));
+ ///
+ /// Sets the index of the annotation in Annots array of the page specified by /P entry
+ /// for the child target associated with a file attachment annotation.
+ ///
+ /// the index (zero-based) of the annotation in the Annots array
+ /// this object wrapper
+ public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetAnnotation(int annotationIndex) {
+ return Put(PdfName.A, new PdfNumber(annotationIndex));
}
- /// Sets the text value, which specifies the value of the /NM entry in the annotation dictionary.
- ///
- ///
+ ///
+ /// Sets the text value, which uniquely identifies an annotation (/NM entry) in an annotation dictionary
+ /// for the child target associated with a file attachment annotation.
+ ///
+ /// specifies the value of NM in the annotation dictionary of the target annotation
+ ///
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetAnnotation(String annotationName) {
return Put(PdfName.A, new PdfString(annotationName));
}
+ /// Gets the object in the /A entry of the underlying object.
+ ///
+ /// Gets the object in the /A entry of the underlying object. If the value is an integer,
+ /// it specifies the index (zero-based) of the annotation in the Annots array of the page specified by P.
+ /// If the value is a text string, it specifies the value of NM in the annotation dictionary.
+ ///
+ /// the /A entry in the target object
public virtual PdfObject GetAnnotation() {
return GetPdfObject().Get(PdfName.A);
}
/// Sets a target dictionary specifying additional path information to the target document.
- ///
- ///
+ ///
+ /// Sets a target dictionary specifying additional path information to the target document.
+ /// If this entry is absent, the current document is the target file containing the destination.
+ ///
+ /// the additional path target dictionary
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary SetTarget(iText.Kernel.Pdf.Action.PdfTargetDictionary
target) {
return Put(PdfName.T, target.GetPdfObject());
}
+ /// Get a target dictionary specifying additional path information to the target document.
+ ///
+ /// Get a target dictionary specifying additional path information to the target document.
+ /// If the current target object is the final node in the target path, null is returned.
+ ///
+ /// a target dictionary specifying additional path information to the target document
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary GetTarget() {
- return new iText.Kernel.Pdf.Action.PdfTargetDictionary(GetPdfObject().GetAsDictionary(PdfName.T));
+ PdfDictionary targetDictObject = GetPdfObject().GetAsDictionary(PdfName.T);
+ return targetDictObject != null ? new iText.Kernel.Pdf.Action.PdfTargetDictionary(targetDictObject) : null;
}
+ ///
+ /// This is a convenient method to put key-value pairs to the underlying
+ ///
+ /// .
+ ///
+ ///
+ /// the key, a
+ ///
+ /// instance
+ ///
+ /// the value
+ /// this object wrapper
public virtual iText.Kernel.Pdf.Action.PdfTargetDictionary Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
}
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return false;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/action/PdfWin.cs b/itext/itext.kernel/itext/kernel/pdf/action/PdfWin.cs
index 985489c02b..31f5eafc60 100644
--- a/itext/itext.kernel/itext/kernel/pdf/action/PdfWin.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/action/PdfWin.cs
@@ -44,16 +44,40 @@ source product.
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Action {
+ /// This class is a wrapper around a Windows launch parameter dictionary.
public class PdfWin : PdfObjectWrapper {
+ /// Creates a new wrapper around an existing Windows launch parameter dictionary.
+ /// the dictionary to create a wrapper for
public PdfWin(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ /// Creates a new wrapper around a newly created Windows launch parameter dictionary.
+ ///
+ /// the file name of the application that shall be launched or the document that shall be opened or printed,
+ /// in standard Windows pathname format. If the name string includes a backslash character (\),
+ /// the backslash shall itself be preceded by a backslash.
+ ///
public PdfWin(PdfString f)
: this(new PdfDictionary()) {
GetPdfObject().Put(PdfName.F, f);
}
+ /// Creates a new wrapper around a newly created Windows launch parameter dictionary.
+ ///
+ /// the file name of the application that shall be launched or the document that shall be opened or printed,
+ /// in standard Windows pathname format. If the name string includes a backslash character (\),
+ /// the backslash shall itself be preceded by a backslash
+ ///
+ /// a bye string specifying the default directory in standard DOS syntax
+ ///
+ /// an ASCII string specifying the operation to perform on the file. Shall be one of the following:
+ /// "open", "print"
+ ///
+ ///
+ /// a parameter string that shall be passed to the application.
+ /// This entry shall be omitted if a document is abound to be opened
+ ///
public PdfWin(PdfString f, PdfString d, PdfString o, PdfString p)
: this(new PdfDictionary()) {
GetPdfObject().Put(PdfName.F, f);
@@ -62,6 +86,7 @@ public PdfWin(PdfString f, PdfString d, PdfString o, PdfString p)
GetPdfObject().Put(PdfName.P, p);
}
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return false;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/annot/PdfAnnotation.cs b/itext/itext.kernel/itext/kernel/pdf/annot/PdfAnnotation.cs
index 7c728ce764..12d4b2d1a6 100644
--- a/itext/itext.kernel/itext/kernel/pdf/annot/PdfAnnotation.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/annot/PdfAnnotation.cs
@@ -49,74 +49,290 @@ source product.
using iText.Kernel.Pdf.Layer;
namespace iText.Kernel.Pdf.Annot {
+ /// This is a super class for the annotation dictionary wrappers.
+ ///
+ /// This is a super class for the annotation dictionary wrappers. Derived classes represent
+ /// different standard types of annotations. See ISO-320001 12.5.6, “Annotation Types.”
+ ///
public abstract class PdfAnnotation : PdfObjectWrapper {
- /// Annotation flags.
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int INVISIBLE = 1;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int HIDDEN = 2;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int PRINT = 4;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int NO_ZOOM = 8;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int NO_ROTATE = 16;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int NO_VIEW = 32;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int READ_ONLY = 64;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int LOCKED = 128;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int TOGGLE_NO_VIEW = 256;
+ /// Annotation flag.
+ ///
+ /// Annotation flag.
+ /// See also
+ ///
+ /// and ISO-320001, table 165.
+ ///
public const int LOCKED_CONTENTS = 512;
- /// Annotation highlighting modes.
+ /// Widget annotation highlighting mode.
+ ///
+ /// Widget annotation highlighting mode. See ISO-320001, Table 188 (H key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfName HIGHLIGHT_NONE = PdfName.N;
+ /// Widget annotation highlighting mode.
+ ///
+ /// Widget annotation highlighting mode. See ISO-320001, Table 188 (H key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfName HIGHLIGHT_INVERT = PdfName.I;
+ /// Widget annotation highlighting mode.
+ ///
+ /// Widget annotation highlighting mode. See ISO-320001, Table 188 (H key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfName HIGHLIGHT_OUTLINE = PdfName.O;
+ /// Widget annotation highlighting mode.
+ ///
+ /// Widget annotation highlighting mode. See ISO-320001, Table 188 (H key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfName HIGHLIGHT_PUSH = PdfName.P;
+ /// Widget annotation highlighting mode.
+ ///
+ /// Widget annotation highlighting mode. See ISO-320001, Table 188 (H key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfName HIGHLIGHT_TOGGLE = PdfName.T;
- /// Annotation highlighting modes.
+ /// Annotation border style.
+ ///
+ /// Annotation border style. See ISO-320001, Table 166 (S key).
+ /// Also see
+ ///
+ ///
public static readonly PdfName STYLE_SOLID = PdfName.S;
+ /// Annotation border style.
+ ///
+ /// Annotation border style. See ISO-320001, Table 166 (S key).
+ /// Also see
+ ///
+ ///
public static readonly PdfName STYLE_DASHED = PdfName.D;
+ /// Annotation border style.
+ ///
+ /// Annotation border style. See ISO-320001, Table 166 (S key).
+ /// Also see
+ ///
+ ///
public static readonly PdfName STYLE_BEVELED = PdfName.B;
+ /// Annotation border style.
+ ///
+ /// Annotation border style. See ISO-320001, Table 166 (S key).
+ /// Also see
+ ///
+ ///
public static readonly PdfName STYLE_INSET = PdfName.I;
+ /// Annotation border style.
+ ///
+ /// Annotation border style. See ISO-320001, Table 166 (S key).
+ /// Also see
+ ///
+ ///
public static readonly PdfName STYLE_UNDERLINE = PdfName.U;
- /// Annotation states.
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Marked = new PdfString("Marked");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Unmarked = new PdfString("Unmarked");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Accepted = new PdfString("Accepted");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Rejected = new PdfString("Rejected");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Canceled = new PdfString("Cancelled");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString Completed = new PdfString("Completed");
+ /// Annotation state.
+ ///
+ /// Annotation state. See ISO-320001 12.5.6.3 "Annotation States" and Table 171 in particular.
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString None = new PdfString("None");
- /// Annotation state models.
+ /// Annotation state model.
+ ///
+ /// Annotation state model. See ISO-320001, Table 172 (StateModel key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString MarkedModel = new PdfString("Marked");
+ /// Annotation state model.
+ ///
+ /// Annotation state model. See ISO-320001, Table 172 (StateModel key).
+ /// Also see
+ ///
+ /// .
+ ///
public static readonly PdfString ReviewModel = new PdfString("Review");
protected internal PdfPage page;
- public static iText.Kernel.Pdf.Annot.PdfAnnotation MakeAnnotation(PdfObject pdfObject, iText.Kernel.Pdf.Annot.PdfAnnotation
- parent) {
+ ///
+ /// Factory method that creates the type specific
+ ///
+ /// from the given
+ ///
+ /// that represents annotation object. This method is useful for property reading in reading mode or
+ /// modifying in stamping mode. See derived classes of this class to see possible specific annotation types
+ /// created.
+ ///
+ ///
+ /// a
+ ///
+ /// that represents annotation in the document.
+ ///
+ ///
+ /// created
+ ///
+ /// .
+ ///
+ public static iText.Kernel.Pdf.Annot.PdfAnnotation MakeAnnotation(PdfObject pdfObject) {
iText.Kernel.Pdf.Annot.PdfAnnotation annotation = null;
if (pdfObject.IsIndirectReference()) {
pdfObject = ((PdfIndirectReference)pdfObject).GetRefersTo();
@@ -229,17 +445,40 @@ public static iText.Kernel.Pdf.Annot.PdfAnnotation MakeAnnotation(PdfObject pdfO
}
}
}
- if (annotation is PdfMarkupAnnotation) {
- PdfMarkupAnnotation markup = (PdfMarkupAnnotation)annotation;
- PdfDictionary inReplyTo = markup.GetInReplyToObject();
- if (inReplyTo != null) {
- markup.SetInReplyTo(MakeAnnotation(inReplyTo));
- }
- PdfDictionary popup = markup.GetPopupObject();
- if (popup != null) {
- markup.SetPopup((PdfPopupAnnotation)MakeAnnotation(popup, markup));
- }
- }
+ return annotation;
+ }
+
+ ///
+ /// Factory method that creates the type specific
+ ///
+ /// from the given
+ ///
+ /// that represents annotation object. This method is useful for property reading in reading mode or
+ /// modifying in stamping mode.
+ ///
+ ///
+ /// a
+ ///
+ /// that represents annotation in the document.
+ ///
+ ///
+ /// parent annotation of the
+ ///
+ /// to be created. This parameter is
+ /// only needed if passed
+ ///
+ /// represents a pop-up annotation in the document.
+ ///
+ ///
+ /// created
+ ///
+ /// .
+ ///
+ [System.ObsoleteAttribute(@"This method will be removed in iText 7.1. Please, simply use MakeAnnotation(iText.Kernel.Pdf.PdfObject) ."
+ )]
+ public static iText.Kernel.Pdf.Annot.PdfAnnotation MakeAnnotation(PdfObject pdfObject, iText.Kernel.Pdf.Annot.PdfAnnotation
+ parent) {
+ iText.Kernel.Pdf.Annot.PdfAnnotation annotation = MakeAnnotation(pdfObject);
if (annotation is PdfPopupAnnotation) {
PdfPopupAnnotation popup = (PdfPopupAnnotation)annotation;
if (parent != null) {
@@ -260,6 +499,13 @@ protected internal PdfAnnotation(PdfDictionary pdfObject)
MarkObjectAsIndirect(GetPdfObject());
}
+ ///
+ /// Gets a
+ ///
+ /// which value is a subtype of this annotation.
+ /// See ISO-320001 12.5.6, “Annotation Types” for the reference to the possible types.
+ ///
+ /// subtype of this annotation.
public abstract PdfName GetSubtype();
/// Sets the layer this annotation belongs to.
@@ -268,56 +514,242 @@ public virtual void SetLayer(IPdfOCG layer) {
GetPdfObject().Put(PdfName.OC, layer.GetIndirectReference());
}
+ ///
+ /// Sets a
+ ///
+ /// to this annotation which will be performed when the annotation is activated.
+ ///
+ ///
+ ///
+ ///
+ /// to set to this annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAction(PdfAction action) {
return Put(PdfName.A, action.GetPdfObject());
}
+ ///
+ /// Sets an additional
+ ///
+ /// to this annotation which will be performed in response to
+ /// the specific trigger event defined by
+ ///
+ /// . See ISO-320001 12.6.3, "Trigger Events".
+ ///
+ ///
+ /// a
+ ///
+ /// that denotes a type of the additional action to set.
+ ///
+ ///
+ ///
+ ///
+ /// to set as additional to this annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAdditionalAction(PdfName key, PdfAction action) {
PdfAction.SetAdditionalAction(this, key, action);
return this;
}
+ ///
+ /// Gets the text that shall be displayed for the annotation or, if this type of annotation does not display text,
+ /// an alternate description of the annotation’s contents in human-readable form.
+ ///
+ /// annotation text content.
public virtual PdfString GetContents() {
return GetPdfObject().GetAsString(PdfName.Contents);
}
+ ///
+ /// Sets the text that shall be displayed for the annotation or, if this type of annotation does not display text,
+ /// an alternate description of the annotation’s contents in human-readable form.
+ ///
+ ///
+ /// a
+ ///
+ /// containing text content to be set to the annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetContents(PdfString contents) {
return Put(PdfName.Contents, contents);
}
+ ///
+ /// Sets the text that shall be displayed for the annotation or, if this type of annotation does not display text,
+ /// an alternate description of the annotation’s contents in human-readable form.
+ ///
+ ///
+ /// a java
+ ///
+ /// containing text content to be set to the annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetContents(String contents) {
return SetContents(new PdfString(contents));
}
+ ///
+ /// Gets a
+ ///
+ /// that represents a page of the document on which annotation is placed,
+ /// i.e. which has this annotation in it's /Annots array.
+ ///
+ ///
+ ///
+ ///
+ /// that is a page pdf object or null if annotation is not added to the page yet.
+ ///
public virtual PdfDictionary GetPageObject() {
return GetPdfObject().GetAsDictionary(PdfName.P);
}
+ ///
+ /// Gets a
+ ///
+ /// on which annotation is placed.
+ ///
+ ///
+ ///
+ ///
+ /// on which annotation is placed or null if annotation is not placed yet.
+ ///
public virtual PdfPage GetPage() {
+ if (page == null && GetPdfObject().IsIndirect()) {
+ PdfIndirectReference annotationIndirectReference = GetPdfObject().GetIndirectReference();
+ PdfDocument doc = annotationIndirectReference.GetDocument();
+ PdfDictionary pageDictionary = GetPageObject();
+ if (pageDictionary != null) {
+ page = doc.GetPage(pageDictionary);
+ }
+ else {
+ for (int i = 1; i <= doc.GetNumberOfPages(); i++) {
+ PdfPage docPage = doc.GetPage(i);
+ foreach (iText.Kernel.Pdf.Annot.PdfAnnotation annot in docPage.GetAnnotations()) {
+ if (annot.GetPdfObject().GetIndirectReference().Equals(annotationIndirectReference)) {
+ page = docPage;
+ break;
+ }
+ }
+ }
+ }
+ }
return page;
}
+ /// Method that modifies annotation page property, which defines to which page annotation belongs.
+ ///
+ /// Method that modifies annotation page property, which defines to which page annotation belongs.
+ /// Keep in mind that this doesn't actually add an annotation to the page,
+ /// it should be done via
+ ///
+ /// .
+ /// Also you don't need to set this property manually, this is done automatically on addition to the page.
+ ///
+ ///
+ /// the
+ ///
+ /// to which annotation will be added.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetPage(PdfPage page) {
this.page = page;
return Put(PdfName.P, page.GetPdfObject());
}
+ ///
+ /// Gets the annotation name, a text string uniquely identifying it among all the
+ /// annotations on its page.
+ ///
+ ///
+ /// a
+ ///
+ /// with annotation name as it's value or null if name
+ /// is not specified.
+ ///
public virtual PdfString GetName() {
return GetPdfObject().GetAsString(PdfName.NM);
}
+ ///
+ /// Sets the annotation name, a text string uniquely identifying it among all the
+ /// annotations on its page.
+ ///
+ ///
+ /// a
+ ///
+ /// to be set as annotation name.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetName(PdfString name) {
return Put(PdfName.NM, name);
}
+ /// The date and time when the annotation was most recently modified.
+ ///
+ /// The date and time when the annotation was most recently modified.
+ /// This is an optional property of the annotation.
+ ///
+ ///
+ /// a
+ ///
+ /// with the modification date as it's value or null if date is not specified.
+ ///
public virtual PdfString GetDate() {
return GetPdfObject().GetAsString(PdfName.M);
}
+ /// The date and time when the annotation was most recently modified.
+ ///
+ /// a
+ ///
+ /// with date. The format should be a date string as described
+ /// in ISO-320001 7.9.4, “Dates”.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetDate(PdfString date) {
return Put(PdfName.M, date);
}
+ /// A set of flags specifying various characteristics of the annotation (see ISO-320001 12.5.3, “Annotation Flags”).
+ ///
+ ///
+ /// A set of flags specifying various characteristics of the annotation (see ISO-320001 12.5.3, “Annotation Flags”).
+ /// For specific annotation flag constants see
+ ///
+ /// .
+ /// Default value: 0.
+ ///
+ /// an integer interpreted as one-bit flags specifying various characteristics of the annotation.
public virtual int GetFlags() {
PdfNumber f = GetPdfObject().GetAsNumber(PdfName.F);
if (f != null) {
@@ -328,51 +760,273 @@ public virtual int GetFlags() {
}
}
+ /// Sets a set of flags specifying various characteristics of the annotation (see ISO-320001 12.5.3, “Annotation Flags”).
+ ///
+ ///
+ /// Sets a set of flags specifying various characteristics of the annotation (see ISO-320001 12.5.3, “Annotation Flags”).
+ /// On the contrary from
+ ///
+ /// , this method sets a complete set of enabled and disabled flags at once.
+ /// If not set specifically the default value is 0.
+ ///
+ /// an integer interpreted as set of one-bit flags specifying various characteristics of the annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetFlags(int flags) {
return Put(PdfName.F, new PdfNumber(flags));
}
+ /// Sets a flag that specifies a characteristic of the annotation to enabled state (see ISO-320001 12.5.3, “Annotation Flags”).
+ ///
+ ///
+ /// Sets a flag that specifies a characteristic of the annotation to enabled state (see ISO-320001 12.5.3, “Annotation Flags”).
+ /// On the contrary from
+ ///
+ /// , this method sets only specified flags to enabled state,
+ /// but doesn't disable other flags.
+ /// Possible flags:
+ ///
+ ///
+ ///
+ /// - If set, do not display the annotation if it does not belong to one of the
+ /// standard annotation types and no annotation handler is available. If clear, display such unknown annotation
+ /// using an appearance stream specified by its appearance dictionary, if any.
+ ///
+ ///
+ ///
+ /// - If set, do not display or print the annotation or allow it to interact with
+ /// the user, regardless of its annotation type or whether an annotation handler is available.
+ ///
+ ///
+ ///
+ /// - If set, print the annotation when the page is printed. If clear, never print
+ /// the annotation, regardless of whether it is displayed on the screen.
+ ///
+ ///
+ ///
+ /// - If set, do not scale the annotation’s appearance to match the magnification of
+ /// the page. The location of the annotation on the page (defined by the upper-left corner of its annotation
+ /// rectangle) shall remain fixed, regardless of the page magnification.}
+ ///
+ ///
+ ///
+ /// - If set, do not rotate the annotation’s appearance to match the rotation
+ /// of the page. The upper-left corner of the annotation rectangle shall remain in a fixed location on the page,
+ /// regardless of the page rotation.
+ ///
+ ///
+ ///
+ /// - If set, do not display the annotation on the screen or allow it to interact
+ /// with the user. The annotation may be printed (depending on the setting of the Print flag) but should be considered
+ /// hidden for purposes of on-screen display and user interaction.
+ ///
+ ///
+ ///
+ /// - If set, do not allow the annotation to interact with the user. The annotation
+ /// may be displayed or printed (depending on the settings of the NoView and Print flags) but should not respond to mouse
+ /// clicks or change its appearance in response to mouse motions.
+ ///
+ ///
+ ///
+ /// - If set, do not allow the annotation to be deleted or its properties
+ /// (including position and size) to be modified by the user. However, this flag does not restrict changes to
+ /// the annotation’s contents, such as the value of a form field.
+ ///
+ ///
+ ///
+ /// - If set, invert the interpretation of the NoView flag for certain events.
+ ///
+ ///
+ ///
+ /// - If set, do not allow the contents of the annotation to be modified
+ /// by the user. This flag does not restrict deletion of the annotation or changes to other annotation properties,
+ /// such as position and size.
+ ///
+ ///
+ ///
+ /// - an integer interpreted as set of one-bit flags which will be enabled for this annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetFlag(int flag) {
int flags = GetFlags();
flags = flags | flag;
return SetFlags(flags);
}
+ /// Resets a flag that specifies a characteristic of the annotation to disabled state (see ISO-320001 12.5.3, “Annotation Flags”).
+ ///
+ /// an integer interpreted as set of one-bit flags which will be reset to disabled state.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation ResetFlag(int flag) {
int flags = GetFlags();
- flags = flags & (~flag & 0xff);
+ flags = flags & ~flag;
return SetFlags(flags);
}
+ ///
+ /// Checks if the certain flag that specifies a characteristic of the annotation
+ /// is in enabled state (see ISO-320001 12.5.3, “Annotation Flags”).
+ ///
+ ///
+ /// Checks if the certain flag that specifies a characteristic of the annotation
+ /// is in enabled state (see ISO-320001 12.5.3, “Annotation Flags”).
+ /// This method allows only one flag to be checked at once, use constants listed in
+ ///
+ /// .
+ ///
+ ///
+ /// an integer interpreted as set of one-bit flags. Only one bit must be set in this integer, otherwise
+ /// exception is thrown.
+ ///
+ /// true if the given flag is in enabled state.
public virtual bool HasFlag(int flag) {
+ if (flag == 0) {
+ return false;
+ }
+ if ((flag & flag - 1) != 0) {
+ throw new ArgumentException("Only one flag must be checked at once.");
+ }
int flags = GetFlags();
return (flags & flag) != 0;
}
+ ///
+ /// An appearance dictionary specifying how the annotation shall be presented visually on the page during its
+ /// interactions with the user (see ISO-320001 12.5.5, “Appearance Streams”).
+ ///
+ ///
+ /// An appearance dictionary specifying how the annotation shall be presented visually on the page during its
+ /// interactions with the user (see ISO-320001 12.5.5, “Appearance Streams”). An appearance dictionary is a dictionary
+ /// containing one or several appearance streams or subdictionaries.
+ ///
+ ///
+ /// an appearance
+ ///
+ /// or null if it is not specified.
+ ///
public virtual PdfDictionary GetAppearanceDictionary() {
return GetPdfObject().GetAsDictionary(PdfName.AP);
}
+ /// Specific appearance object corresponding to the specific appearance type.
+ ///
+ /// Specific appearance object corresponding to the specific appearance type. This object might be either an appearance
+ /// stream or an appearance subdictionary. In the latter case, the subdictionary defines multiple appearance streams
+ /// corresponding to different appearance states of the annotation. See ISO-320001 12.5.5, “Appearance Streams”.
+ ///
+ ///
+ /// a
+ ///
+ /// specifying appearance type. Possible types are
+ /// Normal
+ /// ,
+ /// Rollover
+ /// and
+ /// Down
+ /// .
+ ///
+ ///
+ /// null if their is no such appearance type or an appearance object which might be either
+ /// an appearance stream or an appearance subdictionary.
+ ///
public virtual PdfDictionary GetAppearanceObject(PdfName appearanceType) {
PdfDictionary ap = GetAppearanceDictionary();
if (ap != null) {
- return ap.GetAsDictionary(appearanceType);
+ PdfObject apObject = ap.Get(appearanceType);
+ if (apObject is PdfDictionary) {
+ return (PdfDictionary)apObject;
+ }
}
return null;
}
+ /// The normal appearance is used when the annotation is not interacting with the user.
+ ///
+ /// The normal appearance is used when the annotation is not interacting with the user.
+ /// This appearance is also used for printing the annotation.
+ /// See also
+ ///
+ /// .
+ ///
+ /// an appearance object which might be either an appearance stream or an appearance subdictionary.
public virtual PdfDictionary GetNormalAppearanceObject() {
return GetAppearanceObject(PdfName.N);
}
+ ///
+ /// The rollover appearance is used when the user moves the cursor into the annotation’s active area
+ /// without pressing the mouse button.
+ ///
+ ///
+ /// The rollover appearance is used when the user moves the cursor into the annotation’s active area
+ /// without pressing the mouse button. If not specified normal appearance is used.
+ /// See also
+ ///
+ /// .
+ ///
+ ///
+ /// null if rollover appearance is not specified or an appearance object which might be either
+ /// an appearance stream or an appearance subdictionary.
+ ///
public virtual PdfDictionary GetRolloverAppearanceObject() {
return GetAppearanceObject(PdfName.R);
}
+ /// The down appearance is used when the mouse button is pressed or held down within the annotation’s active area.
+ ///
+ ///
+ /// The down appearance is used when the mouse button is pressed or held down within the annotation’s active area.
+ /// If not specified normal appearance is used.
+ /// See also
+ ///
+ /// .
+ ///
+ ///
+ /// null if down appearance is not specified or an appearance object which might be either
+ /// an appearance stream or an appearance subdictionary.
+ ///
public virtual PdfDictionary GetDownAppearanceObject() {
return GetAppearanceObject(PdfName.D);
}
+ /// Sets a specific type of the appearance.
+ ///
+ /// Sets a specific type of the appearance. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// specifying appearance type. Possible types are
+ /// Normal
+ /// ,
+ /// Rollover
+ /// and
+ /// Down
+ /// .
+ ///
+ /// an appearance object which might be either an appearance stream or an appearance subdictionary.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAppearance(PdfName appearanceType, PdfDictionary appearance
) {
PdfDictionary ap = GetAppearanceDictionary();
@@ -384,69 +1038,345 @@ public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAppearance(PdfName appear
return this;
}
+ /// Sets normal appearance.
+ ///
+ /// Sets normal appearance. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ /// an appearance object which might be either an appearance stream or an appearance subdictionary.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetNormalAppearance(PdfDictionary appearance) {
return SetAppearance(PdfName.N, appearance);
}
+ /// Sets rollover appearance.
+ ///
+ /// Sets rollover appearance. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ /// an appearance object which might be either an appearance stream or an appearance subdictionary.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetRolloverAppearance(PdfDictionary appearance) {
return SetAppearance(PdfName.R, appearance);
}
+ /// Sets down appearance.
+ ///
+ /// Sets down appearance. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ /// an appearance object which might be either an appearance stream or an appearance subdictionary.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetDownAppearance(PdfDictionary appearance) {
return SetAppearance(PdfName.D, appearance);
}
+ ///
+ /// Sets a specific type of the appearance using
+ ///
+ /// wrapper.
+ /// This method is used to set only an appearance subdictionary. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// specifying appearance type. Possible types are
+ /// Normal
+ /// ,
+ /// Rollover
+ /// and
+ /// Down
+ /// .
+ ///
+ ///
+ /// an appearance subdictionary wrapped in
+ ///
+ /// .
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAppearance(PdfName appearanceType, PdfAnnotationAppearance
appearance) {
return SetAppearance(appearanceType, appearance.GetPdfObject());
}
+ ///
+ /// Sets normal appearance using
+ ///
+ /// wrapper. This method is used to set only
+ /// appearance subdictionary. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// an appearance subdictionary wrapped in
+ ///
+ /// .
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetNormalAppearance(PdfAnnotationAppearance appearance
) {
return SetAppearance(PdfName.N, appearance);
}
+ ///
+ /// Sets rollover appearance using
+ ///
+ /// wrapper. This method is used to set only
+ /// appearance subdictionary. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// an appearance subdictionary wrapped in
+ ///
+ /// .
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetRolloverAppearance(PdfAnnotationAppearance appearance
) {
return SetAppearance(PdfName.R, appearance);
}
+ ///
+ /// Sets down appearance using
+ ///
+ /// wrapper. This method is used to set only
+ /// appearance subdictionary. See
+ ///
+ /// and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// an appearance subdictionary wrapped in
+ ///
+ /// .
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetDownAppearance(PdfAnnotationAppearance appearance) {
return SetAppearance(PdfName.D, appearance);
}
+ ///
+ /// The annotation’s appearance state, which selects the applicable appearance stream
+ /// from an appearance subdictionary if there is such.
+ ///
+ ///
+ /// The annotation’s appearance state, which selects the applicable appearance stream
+ /// from an appearance subdictionary if there is such. See
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// which defines selected appearance state.
+ ///
public virtual PdfName GetAppearanceState() {
return GetPdfObject().GetAsName(PdfName.AS);
}
+ ///
+ /// Sets the annotation’s appearance state, which selects the applicable appearance stream
+ /// from an appearance subdictionary.
+ ///
+ ///
+ /// Sets the annotation’s appearance state, which selects the applicable appearance stream
+ /// from an appearance subdictionary. See
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// which defines appearance state to be selected.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAppearanceState(PdfName @as) {
return Put(PdfName.AS, @as);
}
+ ///
+ ///
+ /// An array specifying the characteristics of the annotation’s border.
+ ///
+ ///
+ ///
+ /// An array specifying the characteristics of the annotation’s border.
+ /// The array consists of three numbers defining the horizontal corner radius,
+ /// vertical corner radius, and border width, all in default user space units.
+ /// If the corner radii are 0, the border has square (not rounded) corners; if
+ /// the border width is 0, no border is drawn.
+ ///
+ /// The array may have a fourth element, an optional dash array (see ISO-320001 8.4.3.6, “Line Dash Pattern”).
+ ///
+ ///
+ /// an
+ ///
+ /// specifying the characteristics of the annotation’s border.
+ ///
public virtual PdfArray GetBorder() {
return GetPdfObject().GetAsArray(PdfName.Border);
}
+ /// Sets the characteristics of the annotation’s border.
+ ///
+ /// an
+ ///
+ /// specifying the characteristics of the annotation’s border.
+ /// See
+ ///
+ /// for more detailes.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetBorder(PdfArray border) {
return Put(PdfName.Border, border);
}
+ ///
+ /// An array of numbers in the range 0.0 to 1.0, representing a colour used for the following purposes:
+ ///
+ ///
The background of the annotation’s icon when closed
+ ///
The title bar of the annotation’s pop-up window
+ ///
The border of a link annotation
+ ///
+ /// The number of array elements determines the colour space in which the colour shall be defined:
+ ///
+ ///
0 - No colour; transparent
+ ///
1 - DeviceGray
+ ///
3 - DeviceRGB
+ ///
4 - DeviceCMYK
+ ///
+ ///
+ /// An array of numbers in the range 0.0 to 1.0, representing an annotation colour.
public virtual PdfArray GetColorObject() {
return GetPdfObject().GetAsArray(PdfName.C);
}
+ /// Sets an annotation color.
+ ///
+ /// Sets an annotation color. For more details on annotation color purposes and the format
+ /// of the passing
+ ///
+ /// see
+ ///
+ /// .
+ ///
+ /// an array of numbers in the range 0.0 to 1.0, specifying color.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetColor(PdfArray color) {
return Put(PdfName.C, color);
}
+ /// Sets an annotation color.
+ ///
+ /// Sets an annotation color. For more details on annotation color purposes and the format
+ /// of the passing array see
+ ///
+ /// .
+ ///
+ /// an array of numbers in the range 0.0 to 1.0, specifying color.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetColor(float[] color) {
return SetColor(new PdfArray(color));
}
+ /// Sets an annotation color.
+ ///
+ /// Sets an annotation color. For more details on annotation color purposes
+ /// see
+ ///
+ /// .
+ ///
+ ///
+ ///
+ ///
+ /// object of the either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// type.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetColor(Color color) {
return SetColor(new PdfArray(color.GetColorValue()));
}
+ ///
+ /// The integer key of the annotation’s entry in the structural parent tree
+ /// (see ISO-320001 14.7.4.4, “Finding Structure Elements from Content Items”).
+ ///
+ /// integer key in structural parent tree or -1 if annotation is not tagged.
public virtual int GetStructParentIndex() {
PdfNumber n = GetPdfObject().GetAsNumber(PdfName.StructParent);
if (n == null) {
@@ -457,34 +1387,136 @@ public virtual int GetStructParentIndex() {
}
}
+ ///
+ /// Sets he integer key of the annotation’s entry in the structural parent tree
+ /// (see ISO-320001 14.7.4.4, “Finding Structure Elements from Content Items”).
+ ///
+ ///
+ /// Sets he integer key of the annotation’s entry in the structural parent tree
+ /// (see ISO-320001 14.7.4.4, “Finding Structure Elements from Content Items”).
+ /// Note: Normally, there is no need to take care of this manually, struct parent index is set automatically
+ /// if annotation is added to the tagged document's page.
+ ///
+ ///
+ /// integer which is to be the key of the annotation's entry
+ /// in structural parent tree.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetStructParentIndex(int structParentIndex) {
return Put(PdfName.StructParent, new PdfNumber(structParentIndex));
}
- public virtual PdfArray GetQuadPoints() {
- return GetPdfObject().GetAsArray(PdfName.QuadPoints);
- }
-
+ /// A flag specifying whether the annotation shall initially be displayed open.
+ ///
+ /// A flag specifying whether the annotation shall initially be displayed open.
+ /// This flag has affect to not all kinds of annotations.
+ ///
+ /// true if annotation is initially open, false - if closed.
public virtual bool GetOpen() {
PdfBoolean open = GetPdfObject().GetAsBoolean(PdfName.Open);
return open != null && open.GetValue();
}
+ /// Sets a flag specifying whether the annotation shall initially be displayed open.
+ ///
+ /// Sets a flag specifying whether the annotation shall initially be displayed open.
+ /// This flag has affect to not all kinds of annotations.
+ ///
+ /// true if annotation shall initially be open, false - if closed.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetOpen(bool open) {
return Put(PdfName.Open, new PdfBoolean(open));
}
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ ///
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ /// Quadrilaterals are used to define:
+ ///
+ ///
regions inside annotation rectangle in which the link annotation should be activated;
+ ///
a word or group of contiguous words in the text underlying the text markup annotation;
+ ///
the content region that is intended to be removed for a redaction annotation;
+ ///
+ ///
+ /// IMPORTANT NOTE: According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// an
+ ///
+ /// of 8 × n numbers specifying the coordinates of n quadrilaterals.
+ ///
+ public virtual PdfArray GetQuadPoints() {
+ return GetPdfObject().GetAsArray(PdfName.QuadPoints);
+ }
+
+ ///
+ /// Sets n quadrilaterals in default user space by passing an
+ ///
+ /// of 8 × n numbers. For more info of what
+ /// quadrilaterals define see
+ ///
+ /// .
+ ///
+ /// IMPORTANT NOTE: According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// an
+ ///
+ /// of 8 × n numbers specifying the coordinates of n quadrilaterals.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetQuadPoints(PdfArray quadPoints) {
return Put(PdfName.QuadPoints, quadPoints);
}
+ ///
+ /// Sets border style dictionary that has more settings than the array specified for the Border entry (
+ ///
+ /// ).
+ /// See ISO-320001, Table 166 and
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a border style dictionary specifying the line width and dash pattern that shall be used
+ /// in drawing the annotation’s border.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetBorderStyle(PdfDictionary borderStyle) {
return Put(PdfName.BS, borderStyle);
}
- /// Setter for the annotation's border style.
+ /// Setter for the annotation's preset border style.
///
- /// Setter for the annotation's border style. Possible values are
+ /// Setter for the annotation's preset border style. Possible values are
///
///
///
@@ -502,9 +1534,11 @@ public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetBorderStyle(PdfDictionary
///
/// - A single line along the bottom of the annotation rectangle.
///
+ /// See also ISO-320001, Table 166.
///
/// The new value for the annotation's border style.
/// The annotation which this method was called on.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetBorderStyle(PdfName style) {
PdfDictionary styleDict = GetBorderStyle();
if (null == styleDict) {
@@ -514,6 +1548,24 @@ public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetBorderStyle(PdfName style
return SetBorderStyle(styleDict);
}
+ /// Setter for the annotation's preset dashed border style.
+ ///
+ /// Setter for the annotation's preset dashed border style. This property has affect only if
+ ///
+ /// style was used for the annotation border style (see
+ ///
+ /// .
+ /// See ISO-320001 8.4.3.6, “Line Dash Pattern” for the format in which dash pattern shall be specified.
+ ///
+ ///
+ /// a dash array defining a pattern of dashes and gaps that
+ /// shall be used in drawing a dashed border.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetDashPattern(PdfArray dashPattern) {
PdfDictionary styleDict = GetBorderStyle();
if (null == styleDict) {
@@ -523,57 +1575,221 @@ public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetDashPattern(PdfArray dash
return SetBorderStyle(styleDict);
}
+ /// The dictionaries for some annotation types (such as free text and polygon annotations) can include the BS entry.
+ ///
+ ///
+ /// The dictionaries for some annotation types (such as free text and polygon annotations) can include the BS entry.
+ /// That entry specifies a border style dictionary that has more settings than the array specified for the Border
+ /// entry (see
+ ///
+ /// ). If an annotation dictionary includes the BS entry, then the Border
+ /// entry is ignored. If annotation includes AP (see
+ ///
+ /// ) it takes
+ /// precedence over the BS entry. For more info on BS entry see ISO-320001, Table 166.
+ ///
+ ///
+ ///
+ ///
+ /// which is a border style dictionary or null if it is not specified.
+ ///
public virtual PdfDictionary GetBorderStyle() {
return GetPdfObject().GetAsDictionary(PdfName.BS);
}
- public static iText.Kernel.Pdf.Annot.PdfAnnotation MakeAnnotation(PdfObject pdfObject) {
- return MakeAnnotation(pdfObject, null);
- }
-
+ /// Sets annotation title.
+ /// Sets annotation title. This property affects not all annotation types.
+ ///
+ /// a
+ ///
+ /// which value is to be annotation title.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetTitle(PdfString title) {
return Put(PdfName.T, title);
}
+ /// Annotation title.
+ ///
+ /// Annotation title. For example for markup annotations, the title is the text label that shall be displayed in the
+ /// title bar of the annotation’s pop-up window when open and active. For movie annotation Movie actions
+ /// (ISO-320001 12.6.4.9, “Movie Actions”) may use this title to reference the movie annotation.
+ ///
+ ///
+ ///
+ ///
+ /// which value is an annotation title or null if it isn't specifed.
+ ///
public virtual PdfString GetTitle() {
return GetPdfObject().GetAsString(PdfName.T);
}
+ ///
+ /// Sets an appearance characteristics dictionary containing additional information for constructing the
+ /// annotation’s appearance stream.
+ ///
+ ///
+ /// Sets an appearance characteristics dictionary containing additional information for constructing the
+ /// annotation’s appearance stream. See ISO-320001, Table 189.
+ /// This property affects
+ ///
+ /// and
+ ///
+ /// .
+ ///
+ ///
+ /// the
+ ///
+ /// with additional information for appearance stream.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetAppearanceCharacteristics(PdfDictionary characteristics
) {
return Put(PdfName.MK, characteristics);
}
+ ///
+ /// An appearance characteristics dictionary containing additional information for constructing the
+ /// annotation’s appearance stream.
+ ///
+ ///
+ /// An appearance characteristics dictionary containing additional information for constructing the
+ /// annotation’s appearance stream. See ISO-320001, Table 189.
+ /// This property affects
+ ///
+ /// and
+ ///
+ /// .
+ ///
+ /// an appearance characteristics dictionary or null if it isn't specified.
public virtual PdfDictionary GetAppearanceCharacteristics() {
return GetPdfObject().GetAsDictionary(PdfName.MK);
}
+ ///
+ /// An
+ ///
+ /// to perform, such as launching an application, playing a sound,
+ /// changing an annotation’s appearance state etc, when the annotation is activated.
+ ///
+ ///
+ ///
+ ///
+ /// which defines the characteristics and behaviour of an action.
+ ///
public virtual PdfDictionary GetAction() {
return GetPdfObject().GetAsDictionary(PdfName.A);
}
+ /// An additional actions dictionary that extends the set of events that can trigger the execution of an action.
+ ///
+ ///
+ /// An additional actions dictionary that extends the set of events that can trigger the execution of an action.
+ /// See ISO-320001 12.6.3 Trigger Events.
+ ///
+ ///
+ /// an additional actions
+ ///
+ /// .
+ ///
+ ///
public virtual PdfDictionary GetAdditionalAction() {
return GetPdfObject().GetAsDictionary(PdfName.AA);
}
+ /// The annotation rectangle, defining the location of the annotation on the page in default user space units.
+ ///
+ ///
+ /// a
+ ///
+ /// which specifies a rectangle by two diagonally opposite corners.
+ /// Typically, the array is of form [llx lly urx ury].
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation SetRectangle(PdfArray array) {
return Put(PdfName.Rect, array);
}
+ /// The annotation rectangle, defining the location of the annotation on the page in default user space units.
+ ///
+ ///
+ /// a
+ ///
+ /// which specifies a rectangle by two diagonally opposite corners.
+ /// Typically, the array is of form [llx lly urx ury].
+ ///
public virtual PdfArray GetRectangle() {
return GetPdfObject().GetAsArray(PdfName.Rect);
}
+ ///
+ /// Inserts the value into into the underlying
+ ///
+ /// of this
+ ///
+ /// and associates it
+ /// with the specified key. If the key is already present in this
+ ///
+ /// , this method will override
+ /// the old value with the specified one.
+ ///
+ /// key to insert or to override
+ /// the value to associate with the specified key
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
}
+ ///
+ /// Removes the specified key from the underlying
+ ///
+ /// of this
+ ///
+ /// .
+ ///
+ /// key to be removed
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfAnnotation Remove(PdfName key) {
GetPdfObject().Remove(key);
return this;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/annot/PdfLineAnnotation.cs b/itext/itext.kernel/itext/kernel/pdf/annot/PdfLineAnnotation.cs
index 949da1e132..9bb987e724 100644
--- a/itext/itext.kernel/itext/kernel/pdf/annot/PdfLineAnnotation.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/annot/PdfLineAnnotation.cs
@@ -41,96 +41,477 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
+using System;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Annot {
+ /// The purpose of a line annotation is to display a single straight line on the page.
+ ///
+ /// The purpose of a line annotation is to display a single straight line on the page.
+ /// When opened, it displays a pop-up window containing the text of the associated note.
+ /// See also ISO-320001 12.5.6.7 "Line Annotations".
+ ///
public class PdfLineAnnotation : PdfMarkupAnnotation {
+ ///
+ /// Creates a
+ ///
+ /// instance.
+ ///
+ ///
+ /// the annotation rectangle, defining the location of the annotation on the page
+ /// in default user space units. See
+ ///
+ /// .
+ ///
+ ///
+ /// an array of four numbers, [x1 y1 x2 y2], specifying the starting and ending coordinates
+ /// of the line in default user space. See also
+ ///
+ /// .
+ ///
public PdfLineAnnotation(Rectangle rect, float[] line)
: base(rect) {
Put(PdfName.L, new PdfArray(line));
}
- public PdfLineAnnotation(PdfDictionary pdfObject)
- : base(pdfObject) {
+ ///
+ /// Creates a
+ ///
+ /// instance from the given
+ ///
+ /// that represents annotation object. This method is useful for property reading in reading mode or
+ /// modifying in stamping mode.
+ ///
+ ///
+ /// a
+ ///
+ /// that represents existing annotation in the document.
+ ///
+ public PdfLineAnnotation(PdfDictionary pdfDictionary)
+ : base(pdfDictionary) {
}
+ ///
public override PdfName GetSubtype() {
return PdfName.Line;
}
+ ///
+ /// An array of four numbers, [x1 y1 x2 y2], specifying the starting and ending coordinates of the line
+ /// in default user space.
+ ///
+ ///
+ /// An array of four numbers, [x1 y1 x2 y2], specifying the starting and ending coordinates of the line
+ /// in default user space. If the
+ ///
+ /// (see
+ ///
+ /// ) entry is present, this value represents
+ /// the endpoints of the leader lines rather than the endpoints of the line itself.
+ ///
+ /// An array of four numbers specifying the starting and ending coordinates of the line in default user space.
+ ///
public virtual PdfArray GetLine() {
return GetPdfObject().GetAsArray(PdfName.L);
}
+ /// An array of two names specifying the line ending styles that is used in drawing the line.
+ ///
+ /// An array of two names specifying the line ending styles that is used in drawing the line.
+ /// The first and second elements of the array shall specify the line ending styles for the endpoints defined,
+ /// respectively, by the first and second pairs of coordinates, (x1, y1) and (x2, y2), in the
+ ///
+ /// array
+ /// (see
+ ///
+ /// . For possible values see
+ ///
+ /// .
+ ///
+ ///
+ /// An array of two names specifying the line ending styles that is used in drawing the line; or null if line
+ /// endings style is not explicitly defined, default value is [/None /None].
+ ///
public virtual PdfArray GetLineEndingStyles() {
return GetPdfObject().GetAsArray(PdfName.LE);
}
+ /// Sets the line ending styles that are used in drawing the line.
+ ///
+ /// Sets the line ending styles that are used in drawing the line.
+ /// The first and second elements of the array shall specify the line ending styles for the endpoints defined,
+ /// respectively, by the first and second pairs of coordinates, (x1, y1) and (x2, y2), in the
+ ///
+ /// array
+ /// (see
+ ///
+ /// . Possible values for styles are:
+ ///
+ ///
+ ///
+ /// - A square filled with the annotation's interior color, if any;
+ ///
+ ///
+ /// - A circle filled with the annotation's interior color, if any;
+ ///
+ ///
+ /// - A diamond shape filled with the annotation's interior color, if any;
+ ///
+ ///
+ /// - Two short lines meeting in an acute angle to form an open arrowhead;
+ ///
+ ///
+ /// - Two short lines meeting in an acute angle as in the
+ ///
+ /// style and
+ /// connected by a third line to form a triangular closed arrowhead filled with the annotation's interior color, if any;
+ ///
+ ///
+ /// - No line ending;
+ ///
+ ///
+ /// - A short line at the endpoint perpendicular to the line itself;
+ ///
+ ///
+ /// - Two short lines in the reverse direction from
+ ///
+ /// ;
+ ///
+ ///
+ /// - A triangular closed arrowhead in the reverse direction from
+ ///
+ /// ;
+ ///
+ ///
+ /// - A short line at the endpoint approximately 30 degrees clockwise from perpendicular to the line itself;
+ ///
+ /// see also ISO-320001, Table 176 "Line ending styles".
+ ///
+ /// An array of two names specifying the line ending styles that is used in drawing the line.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetLineEndingStyles(PdfArray lineEndingStyles) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LE, lineEndingStyles);
}
+ ///
+ /// The length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself.
+ ///
+ ///
+ /// The length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself. A positive value means that the leader lines appear in the direction that is clockwise
+ /// when traversing the line from its starting point to its ending point (as specified by
+ ///
+ /// (see
+ ///
+ /// );
+ /// a negative value indicates the opposite direction.
+ ///
+ /// a float specifying the length of leader lines in default user space.
+ [System.ObsoleteAttribute(@"use GetLeaderLineLength() instead.")]
public virtual float GetLeaderLine() {
- PdfNumber n = GetPdfObject().GetAsNumber(PdfName.LE);
+ PdfNumber n = GetPdfObject().GetAsNumber(PdfName.LL);
return n == null ? 0 : n.FloatValue();
}
+ ///
+ /// Sets the length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself.
+ ///
+ ///
+ /// Sets the length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself. A positive value means that the leader lines appear in the direction that is clockwise
+ /// when traversing the line from its starting point to its ending point (as specified by
+ ///
+ /// (see
+ ///
+ /// );
+ /// a negative value indicates the opposite direction.
+ ///
+ /// a float specifying the length of leader lines in default user space.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
+ [System.ObsoleteAttribute(@"use SetLeaderLineLength(float) instead.")]
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetLeaderLine(float leaderLine) {
- return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LE, new PdfNumber(leaderLine));
+ return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LL, new PdfNumber(leaderLine));
}
+ ///
+ /// The length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself.
+ ///
+ ///
+ /// The length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself. A positive value means that the leader lines appear in the direction that is clockwise
+ /// when traversing the line from its starting point to its ending point (as specified by
+ ///
+ /// (see
+ ///
+ /// );
+ /// a negative value indicates the opposite direction.
+ ///
+ /// a float specifying the length of leader lines in default user space.
+ public virtual float GetLeaderLineLength() {
+ PdfNumber n = GetPdfObject().GetAsNumber(PdfName.LL);
+ return n == null ? 0 : n.FloatValue();
+ }
+
+ ///
+ /// Sets the length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself.
+ ///
+ ///
+ /// Sets the length of leader lines in default user space that extend from each endpoint of the line perpendicular
+ /// to the line itself. A positive value means that the leader lines appear in the direction that is clockwise
+ /// when traversing the line from its starting point to its ending point (as specified by
+ ///
+ /// (see
+ ///
+ /// );
+ /// a negative value indicates the opposite direction.
+ ///
+ /// a float specifying the length of leader lines in default user space.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
+ public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetLeaderLineLength(float leaderLineLength) {
+ return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LL, new PdfNumber(leaderLineLength));
+ }
+
+ ///
+ /// A non-negative number that represents the length of leader line extensions that extend from the line proper
+ /// 180 degrees from the leader lines.
+ ///
+ ///
+ /// a non-negative float that represents the length of leader line extensions; or if the leader line extension
+ /// is not explicitly set, returns the default value, which is 0.
+ ///
public virtual float GetLeaderLineExtension() {
PdfNumber n = GetPdfObject().GetAsNumber(PdfName.LLE);
return n == null ? 0 : n.FloatValue();
}
+ /// Sets the length of leader line extensions that extend from the line proper 180 degrees from the leader lines.
+ ///
+ ///
+ /// Sets the length of leader line extensions that extend from the line proper 180 degrees from the leader lines.
+ /// This value shall not be set unless
+ ///
+ /// (see
+ ///
+ /// ) is set.
+ ///
+ /// a non-negative float that represents the length of leader line extensions.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetLeaderLineExtension(float leaderLineExtension) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LLE, new PdfNumber(leaderLineExtension));
}
+ ///
+ /// A non-negative number that represents the length of the leader line offset, which is the amount of empty space
+ /// between the endpoints of the annotation and the beginning of the leader lines.
+ ///
+ ///
+ /// a non-negative number that represents the length of the leader line offset,
+ /// or null if leader line offset is not set.
+ ///
public virtual float GetLeaderLineOffset() {
PdfNumber n = GetPdfObject().GetAsNumber(PdfName.LLO);
return n == null ? 0 : n.FloatValue();
}
+ ///
+ /// Sets the length of the leader line offset, which is the amount of empty space between the endpoints of the
+ /// annotation and the beginning of the leader lines.
+ ///
+ /// a non-negative number that represents the length of the leader line offset.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetLeaderLineOffset(float leaderLineOffset) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.LLO, new PdfNumber(leaderLineOffset));
}
+ ///
+ /// If true, the text specified by the
+ ///
+ /// or
+ ///
+ /// entries
+ /// (see
+ ///
+ /// and
+ ///
+ /// )
+ /// is replicated as a caption in the appearance of the line.
+ ///
+ ///
+ /// true, if the annotation text is replicated as a caption, false otherwise. If this property is
+ /// not set, default value is used which is false.
+ ///
public virtual bool GetContentsAsCaption() {
PdfBoolean b = GetPdfObject().GetAsBoolean(PdfName.Cap);
return b != null && b.GetValue();
}
+ ///
+ /// If set to true, the text specified by the
+ ///
+ /// or
+ ///
+ /// entries
+ /// (see
+ ///
+ /// and
+ ///
+ /// )
+ /// will be replicated as a caption in the appearance of the line.
+ ///
+ /// true, if the annotation text should be replicated as a caption, false otherwise.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetContentsAsCaption(bool contentsAsCaption) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.Cap, new PdfBoolean(contentsAsCaption));
}
+ /// A name describing the annotation's caption positioning.
+ ///
+ /// A name describing the annotation's caption positioning. Valid values are
+ ///
+ /// , meaning the caption
+ /// is centered inside the line, and
+ ///
+ /// , meaning the caption is on top of the line.
+ ///
+ ///
+ /// a name describing the annotation's caption positioning, or null if the caption positioning is not
+ /// explicitly defined (in this case the default value is used, which is
+ ///
+ /// ).
+ ///
public virtual PdfName GetCaptionPosition() {
return GetPdfObject().GetAsName(PdfName.CP);
}
+ /// Sets annotation's caption positioning.
+ ///
+ /// Sets annotation's caption positioning. Valid values are
+ ///
+ /// , meaning the caption
+ /// is centered inside the line, and
+ ///
+ /// , meaning the caption is on top of the line.
+ ///
+ /// a name describing the annotation's caption positioning.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetCaptionPosition(PdfName captionPosition) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.CP, captionPosition);
}
+ /// A measure dictionary (see ISO-320001, Table 261) that specifies the scale and units that apply to the line annotation.
+ ///
+ ///
+ /// a
+ ///
+ /// that represents a measure dictionary.
+ ///
public virtual PdfDictionary GetMeasure() {
return GetPdfObject().GetAsDictionary(PdfName.Measure);
}
+ /// Sets a measure dictionary that specifies the scale and units that apply to the line annotation.
+ ///
+ /// a
+ ///
+ /// that represents a measure dictionary, see ISO-320001, Table 261 for valid
+ /// contents specification.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetMeasure(PdfDictionary measure) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.Measure, measure);
}
+ /// An array of two numbers that specifies the offset of the caption text from its normal position.
+ ///
+ /// An array of two numbers that specifies the offset of the caption text from its normal position.
+ /// The first value is the horizontal offset along the annotation line from its midpoint, with a positive value
+ /// indicating offset to the right and a negative value indicating offset to the left. The second value is the vertical
+ /// offset perpendicular to the annotation line, with a positive value indicating a shift up and a negative value indicating
+ /// a shift down.
+ ///
+ ///
+ /// a
+ ///
+ /// of two numbers that specifies the offset of the caption text from its normal position,
+ /// or null if caption offset is not explicitly specified (in this case a default value is used, which is [0, 0]).
+ ///
public virtual PdfArray GetCaptionOffset() {
return GetPdfObject().GetAsArray(PdfName.CO);
}
+ /// Sets the offset of the caption text from its normal position.
+ ///
+ /// a
+ ///
+ /// of two numbers that specifies the offset of the caption text from its
+ /// normal position. The first value defines the horizontal offset along the annotation line from
+ /// its midpoint, with a positive value indicating offset to the right and a negative value indicating
+ /// offset to the left. The second value defines the vertical offset perpendicular to the annotation line,
+ /// with a positive value indicating a shift up and a negative value indicating a shift down.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetCaptionOffset(PdfArray captionOffset) {
return (iText.Kernel.Pdf.Annot.PdfLineAnnotation)Put(PdfName.CO, captionOffset);
}
+ /// Sets the offset of the caption text from its normal position.
+ ///
+ /// an array of two floats that specifies the offset of the caption text from its
+ /// normal position. The first value defines the horizontal offset along the annotation line from
+ /// its midpoint, with a positive value indicating offset to the right and a negative value indicating
+ /// offset to the left. The second value defines the vertical offset perpendicular to the annotation line,
+ /// with a positive value indicating a shift up and a negative value indicating a shift down.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfLineAnnotation SetCaptionOffset(float[] captionOffset) {
return SetCaptionOffset(new PdfArray(captionOffset));
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/annot/PdfMarkupAnnotation.cs b/itext/itext.kernel/itext/kernel/pdf/annot/PdfMarkupAnnotation.cs
index 40996719a0..d20f6cb612 100644
--- a/itext/itext.kernel/itext/kernel/pdf/annot/PdfMarkupAnnotation.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/annot/PdfMarkupAnnotation.cs
@@ -41,11 +41,24 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
+using iText.IO;
+using iText.IO.Log;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Annot {
+ ///
+ /// This is a super class for the annotations which are defined as markup annotations
+ /// because they are used primarily to mark up PDF documents.
+ ///
+ ///
+ /// This is a super class for the annotations which are defined as markup annotations
+ /// because they are used primarily to mark up PDF documents. These annotations have
+ /// text that appears as part of the annotation and may be displayed in other ways
+ /// by a conforming reader, such as in a Comments pane.
+ /// See also ISO-320001 12.5.6.2 "Markup Annotations".
+ ///
public abstract class PdfMarkupAnnotation : PdfAnnotation {
protected internal PdfAnnotation inReplyTo = null;
@@ -59,113 +72,573 @@ protected internal PdfMarkupAnnotation(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ ///
+ /// The text label that will be displayed in the title bar of the annotation's pop-up window
+ /// when open and active.
+ ///
+ ///
+ /// The text label that will be displayed in the title bar of the annotation's pop-up window
+ /// when open and active. This entry shall identify the user who added the annotation.
+ ///
+ ///
+ ///
+ ///
+ /// which value is an annotation text label content
+ /// or null if text is not specified.
+ ///
public virtual PdfString GetText() {
return GetPdfObject().GetAsString(PdfName.T);
}
+ ///
+ /// Sets the text label that will be displayed in the title bar of the annotation's pop-up window
+ /// when open and active.
+ ///
+ ///
+ /// Sets the text label that will be displayed in the title bar of the annotation's pop-up window
+ /// when open and active. This entry shall identify the user who added the annotation.
+ ///
+ ///
+ ///
+ ///
+ /// which value is an annotation text label content.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetText(PdfString text) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.T, text);
}
+ /// The constant opacity value that will be used in painting the annotation.
+ ///
+ /// The constant opacity value that will be used in painting the annotation.
+ /// This value is applied to all visible elements of the annotation in its closed state
+ /// (including its background and border) but not to the pop-up window that appears when
+ /// the annotation is opened. Default value: 1.0.
+ ///
+ ///
+ /// a
+ ///
+ /// which value is in range between 0 and 1, which specifies the
+ /// level of opacity. This method returns null if opacity is not specified; in this case default
+ /// value is used, which is 1.
+ ///
public virtual PdfNumber GetOpacity() {
return GetPdfObject().GetAsNumber(PdfName.CA);
}
+ /// Sets the constant opacity value that will be used in painting the annotation.
+ ///
+ /// a
+ ///
+ /// which value is in range between 0 and 1, which specifies the
+ /// level of opacity.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetOpacity(PdfNumber ca) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.CA, ca);
}
+ ///
+ /// A rich text string (see ISO-320001 12.7.3.4, “Rich Text Strings”) that
+ /// shall be displayed in the pop-up window when the annotation is opened.
+ ///
+ ///
+ /// text string or text stream that specifies rich text or null if
+ /// rich text is not specified.
+ ///
public virtual PdfObject GetRichText() {
- return GetPdfObject().GetAsDictionary(PdfName.RC);
- }
-
+ return GetPdfObject().Get(PdfName.RC);
+ }
+
+ ///
+ /// Sets a rich text string (see ISO-320001 12.7.3.4, “Rich Text Strings”) that
+ /// shall be displayed in the pop-up window when the annotation is opened.
+ ///
+ /// text string or text stream that specifies rich text.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetRichText(PdfObject richText) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.RC, richText);
}
+ /// The date and time when the annotation was created.
+ ///
+ /// a
+ ///
+ /// which value should be in the date format specified in (ISO-320001 7.9.4, “Dates”).
+ ///
public virtual PdfString GetCreationDate() {
return GetPdfObject().GetAsString(PdfName.CreationDate);
}
+ /// Sets the date and time when the annotation was created.
+ ///
+ ///
+ ///
+ /// which value should be in the date format
+ /// specified in (ISO-320001 7.9.4, “Dates”).
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetCreationDate(PdfString creationDate) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.CreationDate, creationDate);
}
+ ///
+ /// An annotation object that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ ///
+ ///
+ /// An annotation object that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ /// The relationship between the two annotations shall be specified by the RT entry
+ /// (see
+ ///
+ /// ).
+ ///
+ ///
+ /// a
+ ///
+ /// that represents an annotation that this annotation is “in reply to.”
+ ///
public virtual PdfDictionary GetInReplyToObject() {
return GetPdfObject().GetAsDictionary(PdfName.IRT);
}
+ ///
+ /// An annotation that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ ///
+ ///
+ /// An annotation that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ /// The relationship between the two annotations shall be specified by the RT entry
+ /// (see
+ ///
+ /// ).
+ ///
+ ///
+ /// a
+ ///
+ /// that this annotation is “in reply to.”
+ ///
public virtual PdfAnnotation GetInReplyTo() {
+ if (inReplyTo == null) {
+ inReplyTo = MakeAnnotation(GetInReplyToObject());
+ }
return inReplyTo;
}
+ ///
+ /// Sets an annotation that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ ///
+ ///
+ /// Sets an annotation that this annotation is “in reply to.”
+ /// Both annotations shall be on the same page of the document.
+ /// The relationship between the two annotations shall be specified by the RT entry
+ /// (see
+ ///
+ /// ).
+ ///
+ ///
+ /// a
+ ///
+ /// that this annotation is “in reply to.”
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetInReplyTo(PdfAnnotation inReplyTo) {
this.inReplyTo = inReplyTo;
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.IRT, inReplyTo.GetPdfObject());
}
+ /// Sets a pop-up annotation for entering or editing the text associated with this annotation.
+ ///
+ /// Sets a pop-up annotation for entering or editing the text associated with this annotation.
+ /// Pop-up annotation defines an associated with this annotation pop-up window that may contain text.
+ /// The Contents (see
+ ///
+ /// ) entry of the annotation that has
+ /// an associated popup specifies the text that shall be displayed when the pop-up window is opened.
+ ///
+ ///
+ /// an
+ ///
+ /// that will be associated with this annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetPopup(PdfPopupAnnotation popup) {
this.popup = popup;
- popup.Put(PdfName.Parent, GetPdfObject());
+ popup.SetParent(this);
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.Popup, popup.GetPdfObject());
}
+ /// An associated pop-up annotation object.
+ ///
+ /// An associated pop-up annotation object. See
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// that represents an associated pop-up annotation,
+ /// or null if popup annotation is not specified.
+ ///
public virtual PdfDictionary GetPopupObject() {
return GetPdfObject().GetAsDictionary(PdfName.Popup);
}
+ /// An associated pop-up annotation for entering or editing the text associated with this annotation.
+ ///
+ ///
+ /// An associated pop-up annotation for entering or editing the text associated with this annotation.
+ /// Pop-up annotation defines an associated with this annotation pop-up window that may contain text.
+ /// The Contents (see
+ ///
+ /// ) entry of the annotation that has
+ /// an associated popup specifies the text that shall be displayed when the pop-up window is opened.
+ ///
+ ///
+ /// an
+ ///
+ /// that is associated with this annotation, or null if there is none.
+ ///
public virtual PdfPopupAnnotation GetPopup() {
+ if (popup == null) {
+ PdfAnnotation annotation = MakeAnnotation(GetPopupObject());
+ if (!(annotation is PdfPopupAnnotation)) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.Annot.PdfMarkupAnnotation));
+ logger.Warn(LogMessageConstant.POPUP_ENTRY_IS_NOT_POPUP_ANNOTATION);
+ return null;
+ }
+ popup = (PdfPopupAnnotation)annotation;
+ }
return popup;
}
+ /// Text representing a short description of the subject being addressed by the annotation.
+ ///
+ /// a
+ ///
+ /// which value is a annotation subject.
+ ///
public virtual PdfString GetSubject() {
return GetPdfObject().GetAsString(PdfName.Subj);
}
+ /// Sets the text representing a short description of the subject being addressed by the annotation.
+ ///
+ /// a
+ ///
+ /// which value is a annotation subject.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetSubject(PdfString subject) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.Subj, subject);
}
+ ///
+ /// A name specifying the relationship (the “reply type”) between this annotation and one specified by IRT entry
+ /// (see
+ ///
+ /// ). Valid values are:
+ ///
+ ///
+ ///
+ /// - The annotation shall be considered a reply to the annotation specified by IRT.
+ /// Conforming readers shall not display replies to an annotation individually but together in the form of
+ /// threaded comments.
+ ///
+ ///
+ /// - The annotation shall be grouped with the annotation specified by IRT.
+ ///
+ ///
+ ///
+ /// a
+ ///
+ /// specifying relationship with the specified by the IRT entry; or null if reply
+ /// type is not specified, in this case the default value is
+ ///
+ /// .
+ ///
public virtual PdfName GetReplyType() {
return GetPdfObject().GetAsName(PdfName.RT);
}
+ ///
+ /// Sets the relationship (the “reply type”) between this annotation and one specified by IRT entry
+ /// (see
+ ///
+ /// ). For valid values see
+ ///
+ /// .
+ ///
+ ///
+ /// a
+ ///
+ /// specifying relationship with the specified by the IRT entry.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetReplyType(PdfName replyType) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.RT, replyType);
}
+ /// A name describing the intent of the markup annotation.
+ ///
+ /// A name describing the intent of the markup annotation.
+ /// See
+ ///
+ /// for more info.
+ ///
+ ///
+ /// a
+ ///
+ /// describing the intent of the markup annotation, or null if not specified.
+ ///
public virtual PdfName GetIntent() {
return GetPdfObject().GetAsName(PdfName.IT);
}
+ /// Sets a name describing the intent of the markup annotation.
+ ///
+ /// Sets a name describing the intent of the markup annotation.
+ /// Intents allow conforming readers to distinguish between different uses and behaviors
+ /// of a single markup annotation type. If this entry is not present or its value is the same as the annotation type,
+ /// the annotation shall have no explicit intent and should behave in a generic manner in a conforming reader.
+ ///
+ /// See ISO-320001, free text annotations (Table 174), line annotations (Table 175), polygon annotations (Table 178),
+ /// and polyline annotations (Table 178) for the specific intent values for those types.
+ ///
+ ///
+ ///
+ /// a
+ ///
+ /// describing the intent of the markup annotation.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetIntent(PdfName intent) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.IT, intent);
}
+ /// An external data dictionary specifying data that shall be associated with the annotation.
+ ///
+ /// An external data dictionary specifying data that shall be associated with the annotation.
+ /// This dictionary contains the following entries:
+ ///
+ ///
+ ///
+ /// - (optional) If present, shall be
+ ///
+ /// .
+ ///
+ ///
+ /// - (required) a name specifying the type of data that the markup annotation
+ /// shall be associated with. The only defined value is
+ ///
+ /// . Table 298 (ISO-320001)
+ /// lists the values that correspond to a subtype of Markup3D (See also
+ ///
+ /// ).
+ ///
+ ///
+ ///
+ /// An external data
+ ///
+ /// , or null if not specified.
+ ///
public virtual PdfDictionary GetExternalData() {
return GetPdfObject().GetAsDictionary(PdfName.ExData);
}
+ /// Sets an external data dictionary specifying data that shall be associated with the annotation.
+ ///
+ /// Sets an external data dictionary specifying data that shall be associated with the annotation.
+ /// This dictionary should contain the following entries:
+ ///
+ ///
+ ///
+ /// - (optional) If present, shall be
+ ///
+ /// .
+ ///
+ ///
+ /// - (required) a name specifying the type of data that the markup annotation
+ /// shall be associated with. The only defined value is
+ ///
+ /// . Table 298 (ISO-320001)
+ /// lists the values that correspond to a subtype of Markup3D (See also
+ ///
+ /// ).
+ ///
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetExternalData(PdfName exData) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.ExData, exData);
}
+ ///
+ /// A set of four numbers describing the numerical differences between two rectangles:
+ /// the Rect entry of the annotation and another rectangle within that one, which
+ /// meaning depends on the type of the annotation:
+ ///
+ ///
for
+ ///
+ /// the inner rectangle is where the annotation's text should be displayed;
+ ///
+ /// for
+ ///
+ /// and
+ ///
+ /// the inner rectangle is the actual boundaries
+ /// of the underlying square or circle;
+ ///
+ ///
for
+ ///
+ /// the inner rectangle is the actual boundaries of the underlying caret.
+ ///
+ ///
+ ///
+ /// a
+ ///
+ /// with four numbers which correspond to the differences in default user space between
+ /// the left, top, right, and bottom coordinates of Rect and those of the inner rectangle, respectively.
+ /// Each value shall be greater than or equal to 0. The sum of the top and bottom differences shall be
+ /// less than the height of Rect, and the sum of the left and right differences shall be less than
+ /// the width of Rect.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetRectangleDifferences(PdfArray rect) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.RD, rect);
}
+ ///
+ /// A set of four numbers describing the numerical differences between two rectangles:
+ /// the Rect entry of the annotation and another rectangle within that one, which
+ /// meaning depends on the type of the annotation (see
+ ///
+ /// ).
+ ///
+ ///
+ /// null if not specified, otherwise a
+ ///
+ /// with four numbers which correspond to the
+ /// differences in default user space between the left, top, right, and bottom coordinates of Rect and those
+ /// of the inner rectangle, respectively.
+ ///
public virtual PdfArray GetRectangleDifferences() {
return GetPdfObject().GetAsArray(PdfName.RD);
}
- public virtual PdfDictionary GetBorderEffect() {
- return GetPdfObject().GetAsDictionary(PdfName.BE);
- }
-
+ ///
+ /// Some annotations types (
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// and
+ ///
+ /// ) may have a
+ ///
+ /// entry, which is a border effect dictionary that specifies
+ /// an effect that shall be applied to the border of the annotations.
+ ///
+ ///
+ /// a
+ ///
+ /// which contents shall be specified in accordance to ISO-320001, Table 167.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetBorderEffect(PdfDictionary borderEffect) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.BE, borderEffect);
}
+ /// A border effect dictionary that specifies an effect that shall be applied to the border of the annotations.
+ ///
+ ///
+ /// a
+ ///
+ /// , which is a border effect dictionary (see ISO-320001, Table 167).
+ ///
+ public virtual PdfDictionary GetBorderEffect() {
+ return GetPdfObject().GetAsDictionary(PdfName.BE);
+ }
+
+ /// The interior color which is used to fill areas specific for different types of annotation.
+ ///
+ /// The interior color which is used to fill areas specific for different types of annotation. For
+ ///
+ /// and polyline annotation (
+ ///
+ /// - the annotation's line endings, for
+ ///
+ /// and
+ ///
+ /// - the annotation's rectangle or ellipse, for
+ ///
+ /// - the redacted
+ /// region after the affected content has been removed.
+ ///
+ ///
+ ///
+ ///
+ /// of either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// type which defines
+ /// interior color of the annotation, or null if interior color is not specified.
+ ///
public virtual Color GetInteriorColor() {
PdfArray color = GetPdfObject().GetAsArray(PdfName.IC);
if (color == null) {
@@ -192,35 +665,170 @@ public virtual Color GetInteriorColor() {
}
}
+ ///
+ /// An array of numbers in the range 0.0 to 1.0 specifying the interior color which is used to fill areas specific
+ /// for different types of annotation.
+ ///
+ ///
+ /// An array of numbers in the range 0.0 to 1.0 specifying the interior color which is used to fill areas specific
+ /// for different types of annotation. For
+ ///
+ /// and polyline annotation (
+ ///
+ /// -
+ /// the annotation's line endings, for
+ ///
+ /// and
+ ///
+ /// - the annotation's
+ /// rectangle or ellipse, for
+ ///
+ /// - the redacted region after the affected content has been removed.
+ ///
+ ///
+ /// a
+ ///
+ /// of numbers in the range 0.0 to 1.0. The number of array elements determines
+ /// the colour space in which the colour is defined: 0 - No colour, transparent; 1 - DeviceGray,
+ /// 3 - DeviceRGB, 4 - DeviceCMYK. For the
+ ///
+ /// number of elements shall be
+ /// equal to 3 (which defines DeviceRGB colour space).
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetInteriorColor(PdfArray interiorColor) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.IC, interiorColor);
}
+ ///
+ /// An array of numbers in the range 0.0 to 1.0 specifying the interior color which is used to fill areas specific
+ /// for different types of annotation.
+ ///
+ ///
+ /// An array of numbers in the range 0.0 to 1.0 specifying the interior color which is used to fill areas specific
+ /// for different types of annotation. See
+ ///
+ /// for more info.
+ ///
+ /// an array of floats in the range 0.0 to 1.0.
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetInteriorColor(float[] interiorColor) {
return SetInteriorColor(new PdfArray(interiorColor));
}
+ /// The name of an icon that is used in displaying the annotation.
+ ///
+ /// The name of an icon that is used in displaying the annotation. Possible values are different for different
+ /// annotation types. See
+ ///
+ /// .
+ ///
+ ///
+ /// a
+ ///
+ /// that specifies the icon for displaying annotation, or null if icon name is not specified.
+ ///
public virtual PdfName GetIconName() {
return GetPdfObject().GetAsName(PdfName.Name);
}
+ /// The name of an icon that is used in displaying the annotation.
+ ///
+ /// a
+ ///
+ /// that specifies the icon for displaying annotation. Possible values are different
+ /// for different annotation types:
+ ///
+ ///
+ /// - GraphPushPin, PaperclipTag. Additional names may be supported as well.
+ ///
+ ///
+ /// - Speaker and Mic. Additional names may be supported as well.
+ ///
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetIconName(PdfName name) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.Name, name);
}
+ /// The default appearance string that shall be used in formatting the text.
+ /// The default appearance string that shall be used in formatting the text. See ISO-32001 12.7.3.3, “Variable Text”.
+ ///
+ ///
+ /// a
+ ///
+ /// that specifies the default appearance.
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetDefaultAppearance(PdfString appearanceString) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.DA, appearanceString);
}
+ /// The default appearance string that shall be used in formatting the text.
+ /// The default appearance string that shall be used in formatting the text. See ISO-32001 12.7.3.3, “Variable Text”.
+ ///
+ ///
+ /// a
+ ///
+ /// that specifies the default appearance, or null if default appereance is not specified.
+ ///
public virtual PdfString GetDefaultAppearance() {
return GetPdfObject().GetAsString(PdfName.DA);
}
+ ///
+ /// A code specifying the form of quadding (justification) that is used in displaying the annotation's text:
+ /// 0 - Left-justified, 1 - Centered, 2 - Right-justified.
+ ///
+ ///
+ /// A code specifying the form of quadding (justification) that is used in displaying the annotation's text:
+ /// 0 - Left-justified, 1 - Centered, 2 - Right-justified. Default value: 0 (left-justified).
+ ///
+ /// a code specifying the form of quadding (justification), returns the default value if not explicitly specified.
+ ///
public virtual int GetJustification() {
PdfNumber q = GetPdfObject().GetAsNumber(PdfName.Q);
return q == null ? 0 : q.IntValue();
}
+ ///
+ /// A code specifying the form of quadding (justification) that is used in displaying the annotation's text:
+ /// 0 - Left-justified, 1 - Centered, 2 - Right-justified.
+ ///
+ ///
+ /// A code specifying the form of quadding (justification) that is used in displaying the annotation's text:
+ /// 0 - Left-justified, 1 - Centered, 2 - Right-justified. Default value: 0 (left-justified).
+ ///
+ /// a code specifying the form of quadding (justification).
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
public virtual iText.Kernel.Pdf.Annot.PdfMarkupAnnotation SetJustification(int justification) {
return (iText.Kernel.Pdf.Annot.PdfMarkupAnnotation)Put(PdfName.Q, new PdfNumber(justification));
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/annot/PdfPopupAnnotation.cs b/itext/itext.kernel/itext/kernel/pdf/annot/PdfPopupAnnotation.cs
index 7f991519c0..55eaf302c9 100644
--- a/itext/itext.kernel/itext/kernel/pdf/annot/PdfPopupAnnotation.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/annot/PdfPopupAnnotation.cs
@@ -65,6 +65,9 @@ public virtual PdfDictionary GetParentObject() {
}
public virtual PdfAnnotation GetParent() {
+ if (parent == null) {
+ parent = MakeAnnotation(GetParentObject());
+ }
return parent;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/annot/PdfTextMarkupAnnotation.cs b/itext/itext.kernel/itext/kernel/pdf/annot/PdfTextMarkupAnnotation.cs
index 84436c0ee6..35b7016023 100644
--- a/itext/itext.kernel/itext/kernel/pdf/annot/PdfTextMarkupAnnotation.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/annot/PdfTextMarkupAnnotation.cs
@@ -65,21 +65,129 @@ public PdfTextMarkupAnnotation(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ /// Creates a text markup annotation of highlight style subtype.
+ ///
+ /// Creates a text markup annotation of highlight style subtype.
+ ///
+ /// IMPORTANT NOTE on quadPoints argument:
+ /// According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// the annotation rectangle, defining the location of the annotation on the page
+ /// in default user space units.
+ ///
+ ///
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ /// Each quadrilateral shall encompasses a word or group of contiguous words in the text underlying
+ /// the annotation. The text is oriented with respect to the edge connecting first two vertices.
+ ///
+ ///
+ /// created
+ ///
+ /// of Highlight type.
+ ///
public static iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation CreateHighLight(Rectangle rect, float[] quadPoints
) {
return new iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation(rect, MarkupHighlight, quadPoints);
}
+ /// Creates a text markup annotation of underline style subtype.
+ ///
+ /// Creates a text markup annotation of underline style subtype.
+ ///
+ /// IMPORTANT NOTE on quadPoints argument:
+ /// According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// the annotation rectangle, defining the location of the annotation on the page
+ /// in default user space units.
+ ///
+ ///
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ /// Each quadrilateral shall encompasses a word or group of contiguous words in the text underlying
+ /// the annotation. The text is oriented with respect to the edge connecting first two vertices.
+ ///
+ ///
+ /// created
+ ///
+ /// of Underline type.
+ ///
public static iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation CreateUnderline(Rectangle rect, float[] quadPoints
) {
return new iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation(rect, MarkupUnderline, quadPoints);
}
+ /// Creates a text markup annotation of strikeout style subtype.
+ ///
+ /// Creates a text markup annotation of strikeout style subtype.
+ ///
+ /// IMPORTANT NOTE on quadPoints argument:
+ /// According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// the annotation rectangle, defining the location of the annotation on the page
+ /// in default user space units.
+ ///
+ ///
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ /// Each quadrilateral shall encompasses a word or group of contiguous words in the text underlying
+ /// the annotation. The text is oriented with respect to the edge connecting first two vertices.
+ ///
+ ///
+ /// created
+ ///
+ /// of Strikeout type.
+ ///
public static iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation CreateStrikeout(Rectangle rect, float[] quadPoints
) {
return new iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation(rect, MarkupStrikeout, quadPoints);
}
+ /// Creates a text markup annotation of squiggly-underline type.
+ ///
+ /// Creates a text markup annotation of squiggly-underline type.
+ ///
+ /// IMPORTANT NOTE on quadPoints argument:
+ /// According to Table 179 in ISO 32000-1, the QuadPoints array lists the vertices in counterclockwise
+ /// order and the text orientation is defined by the first and second vertex. This basically means QuadPoints is
+ /// specified as lower-left, lower-right, top-right, top-left. HOWEVER, Adobe's interpretation
+ /// (tested at least with Acrobat 10, Acrobat 11, Reader 11) is top-left, top-right, lower-left, lower-right (Z-shaped order).
+ /// This means that if the QuadPoints array is specified according to the standard, the rendering is not as expected.
+ /// Other viewers seem to follow Adobe's interpretation. Hence we recommend to use and expect QuadPoints array in Z-order,
+ /// just as Acrobat and probably most other viewers expect.
+ ///
+ ///
+ /// the annotation rectangle, defining the location of the annotation on the page
+ /// in default user space units.
+ ///
+ ///
+ /// An array of 8 × n numbers specifying the coordinates of n quadrilaterals in default user space.
+ /// Each quadrilateral shall encompasses a word or group of contiguous words in the text underlying
+ /// the annotation. The text is oriented with respect to the edge connecting first two vertices.
+ ///
+ ///
+ /// created
+ ///
+ /// of squiggly-underline type.
+ ///
public static iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation CreateSquiggly(Rectangle rect, float[] quadPoints
) {
return new iText.Kernel.Pdf.Annot.PdfTextMarkupAnnotation(rect, MarkupSquiggly, quadPoints);
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/PdfCanvas.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/PdfCanvas.cs
index eb56f93807..ba19bccffd 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/PdfCanvas.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/PdfCanvas.cs
@@ -362,6 +362,33 @@ public virtual iText.Kernel.Pdf.Canvas.PdfCanvas ConcatMatrix(double a, double b
return this;
}
+ ///
+ /// Concatenates the 2x3 affine transformation matrix to the current matrix
+ /// in the content stream managed by this Canvas.
+ ///
+ ///
+ /// Concatenates the 2x3 affine transformation matrix to the current matrix
+ /// in the content stream managed by this Canvas.
+ /// If an array not containing the 6 values of the matrix is passed,
+ /// The current canvas is returned unchanged.
+ ///
+ /// affine transformation stored as a PdfArray with 6 values
+ /// current canvas
+ public virtual iText.Kernel.Pdf.Canvas.PdfCanvas ConcatMatrix(PdfArray array) {
+ if (array.Size() != 6) {
+ //Throw exception or warning here
+ return this;
+ }
+ for (int i = 0; i < array.Size(); i++) {
+ if (!array.Get(i).IsNumber()) {
+ return this;
+ }
+ }
+ return ConcatMatrix(array.GetAsNumber(0).DoubleValue(), array.GetAsNumber(1).DoubleValue(), array.GetAsNumber
+ (2).DoubleValue(), array.GetAsNumber(3).DoubleValue(), array.GetAsNumber(4).DoubleValue(), array.GetAsNumber
+ (5).DoubleValue());
+ }
+
///
/// Concatenates the affine transformation matrix to the current matrix
/// in the content stream managed by this Canvas.
@@ -411,7 +438,7 @@ public virtual iText.Kernel.Pdf.Canvas.PdfCanvas EndVariableText() {
/// current canvas.
public virtual iText.Kernel.Pdf.Canvas.PdfCanvas SetFontAndSize(PdfFont font, float size) {
if (size < 0.0001f && size > -0.0001f) {
- throw new PdfException(PdfException.FontSizeTooSmall, size);
+ throw new PdfException(PdfException.FontSizeIsTooSmall, size);
}
currentGs.SetFontSize(size);
font.MakeIndirect(document);
@@ -620,8 +647,38 @@ public virtual iText.Kernel.Pdf.Canvas.PdfCanvas ShowText(GlyphLine text) {
float xPlacement = float.NaN;
float yPlacement = float.NaN;
if (glyph.HasPlacement()) {
- xPlacement = -GetSubrangeWidth(text, i + glyph.GetAnchorDelta(), i) + glyph.GetXPlacement() * fontSize;
- yPlacement = glyph.GetYAdvance() * fontSize;
+ {
+ float xPlacementAddition = 0;
+ int currentGlyphIndex = i;
+ Glyph currentGlyph = text.Get(i);
+ while (currentGlyph != null && currentGlyph.GetXPlacement() != 0) {
+ xPlacementAddition += currentGlyph.GetXPlacement();
+ if (currentGlyph.GetAnchorDelta() == 0) {
+ break;
+ }
+ else {
+ currentGlyphIndex += currentGlyph.GetAnchorDelta();
+ currentGlyph = text.Get(currentGlyphIndex);
+ }
+ }
+ xPlacement = -GetSubrangeWidth(text, currentGlyphIndex, i) + xPlacementAddition * fontSize;
+ }
+ {
+ float yPlacementAddition = 0;
+ int currentGlyphIndex = i;
+ Glyph currentGlyph = text.Get(i);
+ while (currentGlyph != null && currentGlyph.GetYPlacement() != 0) {
+ yPlacementAddition += currentGlyph.GetYPlacement();
+ if (currentGlyph.GetAnchorDelta() == 0) {
+ break;
+ }
+ else {
+ currentGlyph = text.Get(currentGlyphIndex + currentGlyph.GetAnchorDelta());
+ currentGlyphIndex += currentGlyph.GetAnchorDelta();
+ }
+ }
+ yPlacement = glyph.GetYAdvance() * fontSize + yPlacementAddition * fontSize;
+ }
contentStream.GetOutputStream().WriteFloat(xPlacement, true).WriteSpace().WriteFloat(yPlacement, true).WriteSpace
().WriteBytes(Td);
}
@@ -1570,7 +1627,6 @@ public virtual PdfXObject AddImage(ImageData image, float a, float b, float c, f
///
/// true if to add image as in-line.
/// created XObject or null in case of in-line image (asInline = true).
- ///
public virtual PdfXObject AddImage(ImageData image, iText.Kernel.Geom.Rectangle rect, bool asInline) {
return AddImage(image, rect.GetWidth(), 0, 0, rect.GetHeight(), rect.GetX(), rect.GetY(), asInline);
}
@@ -1581,7 +1637,6 @@ public virtual PdfXObject AddImage(ImageData image, iText.Kernel.Geom.Rectangle
///
/// true if to add image as in-line.
/// created XObject or null in case of in-line image (asInline = true).
- ///
public virtual PdfXObject AddImage(ImageData image, float x, float y, bool asInline) {
if (image.GetOriginalType() == ImageType.WMF) {
WmfImageHelper wmf = new WmfImageHelper(image);
@@ -1640,7 +1695,6 @@ public virtual PdfXObject AddImage(ImageData image, float x, float y, float widt
/// true if to add image as in-line.
///
/// created XObject or null in case of in-line image (asInline = true).
- ///
public virtual PdfXObject AddImage(ImageData image, float x, float y, float height, bool asInline, bool dummy
) {
return AddImage(image, height / image.GetHeight() * image.GetWidth(), 0, 0, height, x, y, asInline);
@@ -2001,7 +2055,6 @@ private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, float a,
///
///
/// current canvas.
- ///
private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, float x, float y) {
return AddForm(form, 1, 0, 0, 1, x, y);
}
@@ -2014,7 +2067,6 @@ private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, float x,
///
///
/// current canvas.
- ///
private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, iText.Kernel.Geom.Rectangle rect) {
return AddForm(form, rect.GetWidth(), 0, 0, rect.GetHeight(), rect.GetX(), rect.GetY());
}
@@ -2029,7 +2081,6 @@ private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, iText.Ker
///
///
/// current canvas.
- ///
private iText.Kernel.Pdf.Canvas.PdfCanvas AddForm(PdfFormXObject form, float x, float y, float width) {
PdfArray bbox = form.GetPdfObject().GetAsArray(PdfName.BBox);
if (bbox == null) {
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DashedLine.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DashedLine.cs
index 01a00b83ab..7a9bf8de3a 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DashedLine.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DashedLine.cs
@@ -72,8 +72,8 @@ public DashedLine(float lineWidth) {
public virtual void Draw(PdfCanvas canvas, Rectangle drawArea) {
canvas.SaveState().SetLineWidth(lineWidth).SetStrokeColor(color).SetLineDash(2, 2).MoveTo(drawArea.GetX(),
- drawArea.GetY() + drawArea.GetHeight() / 2).LineTo(drawArea.GetX() + drawArea.GetWidth(), drawArea.GetY
- () + drawArea.GetHeight() / 2).Stroke().RestoreState();
+ drawArea.GetY() + lineWidth / 2).LineTo(drawArea.GetX() + drawArea.GetWidth(), drawArea.GetY() + lineWidth
+ / 2).Stroke().RestoreState();
}
/// Gets line width in points
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DottedLine.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DottedLine.cs
index 399bdf5677..9b45b4b920 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DottedLine.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/DottedLine.cs
@@ -83,8 +83,8 @@ public DottedLine(float lineWidth) {
public virtual void Draw(PdfCanvas canvas, Rectangle drawArea) {
canvas.SaveState().SetLineWidth(lineWidth).SetStrokeColor(color).SetLineDash(0, gap, gap / 2).SetLineCapStyle
- (PdfCanvasConstants.LineCapStyle.ROUND).MoveTo(drawArea.GetX(), drawArea.GetY()).LineTo(drawArea.GetX(
- ) + drawArea.GetWidth(), drawArea.GetY()).Stroke().RestoreState();
+ (PdfCanvasConstants.LineCapStyle.ROUND).MoveTo(drawArea.GetX(), drawArea.GetY() + lineWidth / 2).LineTo
+ (drawArea.GetX() + drawArea.GetWidth(), drawArea.GetY() + lineWidth / 2).Stroke().RestoreState();
}
/// Getter for the gap between the center of the dots of the dotted line.
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/SolidLine.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/SolidLine.cs
index 65202a2cb1..10eac8bf22 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/draw/SolidLine.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/draw/SolidLine.cs
@@ -68,8 +68,9 @@ public SolidLine(float lineWidth) {
}
public virtual void Draw(PdfCanvas canvas, Rectangle drawArea) {
- canvas.SaveState().SetStrokeColor(color).MoveTo(drawArea.GetX(), drawArea.GetY()).LineTo(drawArea.GetX() +
- drawArea.GetWidth(), drawArea.GetY()).Stroke().RestoreState();
+ canvas.SaveState().SetStrokeColor(color).SetLineWidth(lineWidth).MoveTo(drawArea.GetX(), drawArea.GetY() +
+ lineWidth / 2).LineTo(drawArea.GetX() + drawArea.GetWidth(), drawArea.GetY() + lineWidth / 2).Stroke(
+ ).RestoreState();
}
/// Gets line width in points
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfCanvasProcessor.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfCanvasProcessor.cs
index ba9b629c03..1b7c1a3483 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfCanvasProcessor.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfCanvasProcessor.cs
@@ -113,7 +113,7 @@ public class PdfCanvasProcessor {
private Stack markedContentStack = new Stack();
///
- /// Creates a new PDF Content Stream Processor that will send it's output to the
+ /// Creates a new PDF Content Stream Processor that will send its output to the
/// designated render listener.
///
///
@@ -131,6 +131,34 @@ public PdfCanvasProcessor(IEventListener eventListener) {
Reset();
}
+ ///
+ /// Creates a new PDF Content Stream Processor that will send its output to the
+ /// designated render listener.
+ ///
+ ///
+ /// Creates a new PDF Content Stream Processor that will send its output to the
+ /// designated render listener.
+ /// Also allows registration of custom IContentOperators that can influence
+ /// how (and whether or not) the PDF instructions will be parsed.
+ ///
+ ///
+ /// the
+ ///
+ /// that will receive rendering notifications
+ ///
+ ///
+ /// an optional map of custom
+ ///
+ /// s for rendering instructions
+ ///
+ public PdfCanvasProcessor(IEventListener eventListener, IDictionary additionalContentOperators
+ )
+ : this(eventListener) {
+ foreach (KeyValuePair entry in additionalContentOperators) {
+ RegisterContentOperator(entry.Key, entry.Value);
+ }
+ }
+
/// Registers a Do handler that will be called when Do for the provided XObject subtype is encountered during content processing.
///
///
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfDocumentContentParser.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfDocumentContentParser.cs
index d95120c092..93ae300ef2 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfDocumentContentParser.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfDocumentContentParser.cs
@@ -62,7 +62,8 @@ public PdfDocumentContentParser(PdfDocument pdfDocument) {
/// Processes content from the specified page number using the specified listener.
///
/// Processes content from the specified page number using the specified listener.
- /// Also allows registration of custom ContentOperators
+ /// Also allows registration of custom IContentOperators that can influence
+ /// how (and whether or not) the PDF instructions will be parsed.
///
///
/// the page number to process
@@ -73,10 +74,7 @@ public PdfDocumentContentParser(PdfDocument pdfDocument) {
public virtual E ProcessContent(int pageNumber, E renderListener, IDictionary
additionalContentOperators)
where E : IEventListener {
- PdfCanvasProcessor processor = new PdfCanvasProcessor(renderListener);
- foreach (KeyValuePair entry in additionalContentOperators) {
- processor.RegisterContentOperator(entry.Key, entry.Value);
- }
+ PdfCanvasProcessor processor = new PdfCanvasProcessor(renderListener, additionalContentOperators);
processor.ProcessPageContent(pdfDocument.GetPage(pageNumber));
return renderListener;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfTextExtractor.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfTextExtractor.cs
index 960f3bcd7b..dbf2c42572 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfTextExtractor.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/PdfTextExtractor.cs
@@ -42,6 +42,7 @@ source product.
address: sales@itextpdf.com
*/
using System;
+using System.Collections.Generic;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
@@ -51,15 +52,34 @@ private PdfTextExtractor() {
}
/// Extract text from a specified page using an extraction strategy.
+ ///
+ /// Extract text from a specified page using an extraction strategy.
+ /// Also allows registration of custom IContentOperators that can influence
+ /// how (and whether or not) the PDF instructions will be parsed.
+ ///
/// the page for the text to be extracted from
/// the strategy to use for extracting text
+ ///
+ /// an optional map of custom
+ ///
+ /// s for rendering instructions
+ ///
/// the extracted text
- public static String GetTextFromPage(PdfPage page, ITextExtractionStrategy strategy) {
- PdfCanvasProcessor parser = new PdfCanvasProcessor(strategy);
+ public static String GetTextFromPage(PdfPage page, ITextExtractionStrategy strategy, IDictionary additionalContentOperators) {
+ PdfCanvasProcessor parser = new PdfCanvasProcessor(strategy, additionalContentOperators);
parser.ProcessPageContent(page);
return strategy.GetResultantText();
}
+ /// Extract text from a specified page using an extraction strategy.
+ /// the page for the text to be extracted from
+ /// the strategy to use for extracting text
+ /// the extracted text
+ public static String GetTextFromPage(PdfPage page, ITextExtractionStrategy strategy) {
+ return GetTextFromPage(page, strategy, new Dictionary());
+ }
+
/// Extract text from a specified page using the default strategy.
///
/// Extract text from a specified page using the default strategy.
@@ -71,7 +91,6 @@ public static String GetTextFromPage(PdfPage page, ITextExtractionStrategy strat
///
/// the page for the text to be extracted from
/// the extracted text
- ///
public static String GetTextFromPage(PdfPage page) {
return GetTextFromPage(page, new LocationTextExtractionStrategy());
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/clipperlib/ClipperBridge.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/clipperlib/ClipperBridge.cs
index 618fdf8b6e..c38e0e9c10 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/clipperlib/ClipperBridge.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/clipperlib/ClipperBridge.cs
@@ -272,7 +272,7 @@ public static PolyFillType GetFillType(int fillingRule) {
return fillType;
}
- [Obsolete]
+ [System.ObsoleteAttribute(@"close will be boolean . Visibility will be changed to internal.")]
public static void AddContour(Path path, IList contour, bool? close) {
IList floatContour = ConvertToFloatPoints(contour);
Point point = floatContour[0];
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/data/TextRenderInfo.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/data/TextRenderInfo.cs
index 32f4abbe0f..c6ba00829b 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/data/TextRenderInfo.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/data/TextRenderInfo.cs
@@ -198,8 +198,7 @@ public virtual LineSegment GetUnscaledBaseline() {
///
/// the ascentline line segment
public virtual LineSegment GetAscentLine() {
- float ascent = gs.GetFont().GetFontProgram().GetFontMetrics().GetTypoAscender() * gs.GetFontSize() / 1000f;
- return GetUnscaledBaselineWithOffset(ascent + gs.GetTextRise()).TransformBy(textToUserSpaceTransformMatrix
+ return GetUnscaledBaselineWithOffset(GetAscentDescent()[0] + gs.GetTextRise()).TransformBy(textToUserSpaceTransformMatrix
);
}
@@ -212,9 +211,7 @@ public virtual LineSegment GetAscentLine() {
///
/// the descentline line segment
public virtual LineSegment GetDescentLine() {
- // per getFontDescription() API, descent is returned as a negative number, so we apply that as a normal vertical offset
- float descent = gs.GetFont().GetFontProgram().GetFontMetrics().GetTypoDescender() * gs.GetFontSize() / 1000f;
- return GetUnscaledBaselineWithOffset(descent + gs.GetTextRise()).TransformBy(textToUserSpaceTransformMatrix
+ return GetUnscaledBaselineWithOffset(GetAscentDescent()[1] + gs.GetTextRise()).TransformBy(textToUserSpaceTransformMatrix
);
}
@@ -476,5 +473,18 @@ private PdfString[] SplitString(PdfString @string) {
}
return strings.ToArray(new PdfString[strings.Count]);
}
+
+ private float[] GetAscentDescent() {
+ float ascent = gs.GetFont().GetFontProgram().GetFontMetrics().GetTypoAscender();
+ float descent = gs.GetFont().GetFontProgram().GetFontMetrics().GetTypoDescender();
+ // If descent is positive, we consider it a bug and fix it
+ if (descent > 0) {
+ descent = -descent;
+ }
+ float scale = ascent - descent < 700 ? ascent - descent : 1000;
+ descent = descent / scale * gs.GetFontSize();
+ ascent = ascent / scale * gs.GetFontSize();
+ return new float[] { ascent, descent };
+ }
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/LocationTextExtractionStrategy.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/LocationTextExtractionStrategy.cs
index b74f434507..8b7768718a 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/LocationTextExtractionStrategy.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/LocationTextExtractionStrategy.cs
@@ -314,7 +314,7 @@ internal virtual bool SameLine(LocationTextExtractionStrategy.TextChunk lastChun
}
}
- private class TextChunkLocationDefaultImp : LocationTextExtractionStrategy.ITextChunkLocation {
+ public class TextChunkLocationDefaultImp : LocationTextExtractionStrategy.ITextChunkLocation {
/// the starting location of the chunk
private readonly Vector startLocation;
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/TextMarginFinder.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/TextMarginFinder.cs
index 855a495a83..d57a05dff0 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/TextMarginFinder.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/listener/TextMarginFinder.cs
@@ -58,12 +58,12 @@ public virtual void EventOccurred(IEventData data, EventType type) {
if (type == EventType.RENDER_TEXT) {
TextRenderInfo info = (TextRenderInfo)data;
if (textRectangle == null) {
- textRectangle = info.GetDescentLine().GetBoundingRectange();
+ textRectangle = info.GetDescentLine().GetBoundingRectangle();
}
else {
- textRectangle = Rectangle.GetCommonRectangle(textRectangle, info.GetDescentLine().GetBoundingRectange());
+ textRectangle = Rectangle.GetCommonRectangle(textRectangle, info.GetDescentLine().GetBoundingRectangle());
}
- textRectangle = Rectangle.GetCommonRectangle(textRectangle, info.GetAscentLine().GetBoundingRectange());
+ textRectangle = Rectangle.GetCommonRectangle(textRectangle, info.GetAscentLine().GetBoundingRectangle());
}
else {
throw new InvalidOperationException(String.Format("Event type not supported: {0}", type));
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/util/PdfCanvasParser.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/util/PdfCanvasParser.cs
index d3de559299..63311740d7 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/parser/util/PdfCanvasParser.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/parser/util/PdfCanvasParser.cs
@@ -160,7 +160,8 @@ public virtual PdfArray ReadArray() {
if (tokeniser.GetTokenType() == PdfTokenizer.TokenType.EndArray) {
break;
}
- if (tokeniser.GetTokenType() == PdfTokenizer.TokenType.EndDic) {
+ if (tokeniser.GetTokenType() == PdfTokenizer.TokenType.EndDic && obj.GetObjectType() != PdfObject.DICTIONARY
+ ) {
tokeniser.ThrowError(PdfException.UnexpectedGtGt);
}
array.Add(obj);
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageData.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageData.cs
index 14c907beee..5c33f3e640 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageData.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageData.cs
@@ -65,7 +65,7 @@ public WmfImageData(Uri url)
: base(url, ImageType.WMF) {
byte[] imageType = ReadImageType(url);
if (!ImageTypeIs(imageType, wmf)) {
- throw new PdfException(PdfException.IsNotWmfImage);
+ throw new PdfException(PdfException.NotAWmfImage);
}
}
@@ -75,7 +75,7 @@ public WmfImageData(byte[] bytes)
: base(bytes, ImageType.WMF) {
byte[] imageType = ReadImageType(url);
if (!ImageTypeIs(imageType, wmf)) {
- throw new PdfException(PdfException.IsNotWmfImage);
+ throw new PdfException(PdfException.NotAWmfImage);
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageHelper.cs b/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageHelper.cs
index 7ff5658b20..3afbab4a98 100644
--- a/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageHelper.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/canvas/wmf/WmfImageHelper.cs
@@ -83,7 +83,6 @@ public WmfImageHelper(ImageData wmf) {
}
/// This method checks if the image is a valid WMF and processes some parameters.
- ///
private void ProcessParameters() {
Stream @is = null;
try {
diff --git a/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionField.cs b/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionField.cs
index c790de38d6..594d527a93 100644
--- a/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionField.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionField.cs
@@ -220,7 +220,7 @@ public virtual PdfObject GetValue(String value) {
return new PdfNumber(System.Double.Parse(value.Trim(), System.Globalization.CultureInfo.InvariantCulture));
}
}
- throw new PdfException(PdfException.IsNotAnAcceptableValueForTheField).SetMessageParams(value, GetPdfObject
+ throw new PdfException(PdfException._1IsNotAnAcceptableValueForTheField2).SetMessageParams(value, GetPdfObject
().GetAsName(PdfName.N).GetValue());
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionSort.cs b/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionSort.cs
index 17dc703d5a..4b3e691763 100644
--- a/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionSort.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/collection/PdfCollectionSort.cs
@@ -86,7 +86,7 @@ public virtual iText.Kernel.Pdf.Collection.PdfCollectionSort SetSortOrder(bool[]
PdfObject obj = GetPdfObject().Get(PdfName.S);
if (obj.IsArray()) {
if (((PdfArray)obj).Size() != ascending.Length) {
- throw new PdfException(PdfException.TheNumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields);
+ throw new PdfException(PdfException.NumberOfBooleansInTheArrayDoesntCorrespondWithTheNumberOfFields);
}
GetPdfObject().Put(PdfName.A, new PdfArray(ascending));
return this;
diff --git a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfCieBasedCs.cs b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfCieBasedCs.cs
index 681d6e06ff..8d08ffb732 100644
--- a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfCieBasedCs.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfCieBasedCs.cs
@@ -49,6 +49,21 @@ source product.
namespace iText.Kernel.Pdf.Colorspace {
public abstract class PdfCieBasedCs : PdfColorSpace {
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfColorSpace.cs b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfColorSpace.cs
index 151e33172a..0124d77149 100644
--- a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfColorSpace.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfColorSpace.cs
@@ -45,6 +45,7 @@ source product.
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Colorspace {
+ /// Represents the most common properties of color spaces.
public abstract class PdfColorSpace : PdfObjectWrapper {
public static readonly ICollection directColorSpaces = new HashSet(iText.IO.Util.JavaUtil.ArraysAsList
(PdfName.DeviceGray, PdfName.DeviceRGB, PdfName.DeviceCMYK, PdfName.Pattern));
diff --git a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfPattern.cs b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfPattern.cs
index c3cf9f5c77..0f0e24b199 100644
--- a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfPattern.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfPattern.cs
@@ -73,6 +73,21 @@ public virtual void SetMatrix(PdfArray matrix) {
SetModified();
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfShading.cs b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfShading.cs
index 8d6b7222be..df6c62cf4e 100644
--- a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfShading.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfShading.cs
@@ -47,26 +47,61 @@ source product.
using iText.Kernel.Pdf.Function;
namespace iText.Kernel.Pdf.Colorspace {
+ /// The abstract PdfShading class that represents the Shading Dictionary PDF object.
public abstract class PdfShading : PdfObjectWrapper {
+ ///
+ /// constants of shading type
+ /// ISO-320001 Table 78
+ ///
+ ///
private class ShadingType {
+ /// The int value of function-based shading type
public const int FUNCTION_BASED = 1;
+ /// The int value of axial shading type
public const int AXIAL = 2;
+ /// The int value of radial shading type
public const int RADIAL = 3;
+ /// The int value of free-form Gouraud-shaded triangle mesh shading type
public const int FREE_FORM_GOURAUD_SHADED_TRIANGLE_MESH = 4;
+ /// The int value of lattice-form Gouraud-shaded triangle mesh shading type
public const int LATTICE_FORM_GOURAUD_SHADED_TRIANGLE_MESH = 5;
+ /// The int value of coons patch meshes shading type
public const int COONS_PATCH_MESH = 6;
+ /// The int value of tensor-product patch meshes shading type
public const int TENSOR_PRODUCT_PATCH_MESH = 7;
}
+ ///
+ /// Creates the
+ ///
+ /// object from the existing
+ ///
+ /// with corresponding type.
+ ///
+ ///
+ ///
+ ///
+ /// from which the
+ ///
+ /// object will be created.
+ ///
+ ///
+ /// Created
+ ///
+ /// object.
+ ///
public static PdfShading MakeShading(PdfDictionary shadingDictionary) {
if (!shadingDictionary.ContainsKey(PdfName.ShadingType)) {
- throw new PdfException(PdfException.UnexpectedShadingType);
+ throw new PdfException(PdfException.ShadingTypeNotFound);
+ }
+ if (!shadingDictionary.ContainsKey(PdfName.ColorSpace)) {
+ throw new PdfException(PdfException.ColorSpaceNotFound);
}
PdfShading shading;
switch (shadingDictionary.GetAsNumber(PdfName.ShadingType).IntValue()) {
@@ -128,29 +163,78 @@ protected internal PdfShading(PdfDictionary pdfObject)
: base(pdfObject) {
}
+ [System.ObsoleteAttribute(@"Use PdfShading(iText.Kernel.Pdf.PdfDictionary, int, PdfColorSpace) instead.")]
protected internal PdfShading(PdfDictionary pdfObject, int type, PdfObject colorSpace)
: base(pdfObject) {
GetPdfObject().Put(PdfName.ShadingType, new PdfNumber(type));
GetPdfObject().Put(PdfName.ColorSpace, colorSpace);
}
+ protected internal PdfShading(PdfDictionary pdfObject, int type, PdfColorSpace colorSpace)
+ : base(pdfObject) {
+ GetPdfObject().Put(PdfName.ShadingType, new PdfNumber(type));
+ if (colorSpace is PdfSpecialCs.Pattern) {
+ throw new ArgumentException("colorSpace");
+ }
+ GetPdfObject().Put(PdfName.ColorSpace, colorSpace.GetPdfObject());
+ }
+
+ /// Gets the shading type.
+ ///
+ /// int value of
+ ///
+ /// .
+ ///
public virtual int GetShadingType() {
return (int)GetPdfObject().GetAsInt(PdfName.ShadingType);
}
+ /// Gets the color space in which colour values shall be expressed.
+ ///
+ ///
+ ///
+ /// Color space
+ ///
public virtual PdfObject GetColorSpace() {
return GetPdfObject().Get(PdfName.ColorSpace);
}
+ ///
+ /// Gets the function PdfObject that represents color transitions
+ /// across the shading geometry.
+ ///
+ ///
+ ///
+ ///
+ /// Function
+ ///
public virtual PdfObject GetFunction() {
return GetPdfObject().Get(PdfName.Function);
}
+ ///
+ /// Sets the function that represents color transitions
+ /// across the shading geometry as one object.
+ ///
+ ///
+ /// The
+ ///
+ /// to set.
+ ///
public virtual void SetFunction(PdfFunction function) {
GetPdfObject().Put(PdfName.Function, function.GetPdfObject());
SetModified();
}
+ ///
+ /// Sets the function object that represents color transitions
+ /// across the shading geometry as an array of functions.
+ ///
+ ///
+ /// The array of
+ ///
+ /// to be set.
+ ///
public virtual void SetFunction(PdfFunction[] functions) {
PdfArray arr = new PdfArray();
foreach (PdfFunction func in functions) {
@@ -160,38 +244,135 @@ public virtual void SetFunction(PdfFunction[] functions) {
SetModified();
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with function-based type,
+ /// that defines color at every point in the domain by a specified mathematical function.
+ ///
public class FunctionBased : PdfShading {
- public FunctionBased(PdfDictionary pdfObject)
- : base(pdfObject) {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
+ public FunctionBased(PdfDictionary pdfDictionary)
+ : base(pdfDictionary) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ ///
+ ///
+ /// the
+ ///
+ /// , that is used to calculate color transitions.
+ ///
public FunctionBased(PdfColorSpace colorSpace, PdfFunction function)
: this(colorSpace.GetPdfObject(), function) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// , that represents color space in which colour values shall be expressed.
+ ///
+ ///
+ /// the
+ ///
+ /// , that is used to calculate color transitions.
+ ///
public FunctionBased(PdfObject colorSpace, PdfFunction function)
- : base(new PdfDictionary(), PdfShading.ShadingType.FUNCTION_BASED, colorSpace) {
+ : base(new PdfDictionary(), PdfShading.ShadingType.FUNCTION_BASED, PdfColorSpace.MakeColorSpace(colorSpace
+ )) {
SetFunction(function);
}
+ ///
+ /// Gets the
+ ///
+ /// domain rectangle object that establishes an internal coordinate space
+ /// for the shading that is independent of the target coordinate space in which it shall be painted.
+ ///
+ ///
+ ///
+ ///
+ /// domain rectangle.
+ ///
public virtual PdfArray GetDomain() {
return GetPdfObject().GetAsArray(PdfName.Domain);
}
+ ///
+ /// Sets the
+ ///
+ /// domain rectangle object that establishes an internal coordinate space
+ /// for the shading that is independent of the target coordinate space in which it shall be painted.
+ ///
+ /// the Xmin coordinate of rectangle.
+ /// the Xmax coordinate of rectangle.
+ /// the Ymin coordinate of rectangle.
+ /// the Ymax coordinate of rectangle.
public virtual void SetDomain(float xmin, float xmax, float ymin, float ymax) {
GetPdfObject().Put(PdfName.Domain, new PdfArray(new float[] { xmin, xmax, ymin, ymax }));
SetModified();
}
+ ///
+ /// Sets the
+ ///
+ /// domain rectangle object that establishes an internal coordinate space
+ /// for the shading that is independent of the target coordinate space in which it shall be painted.
+ ///
+ ///
+ /// the
+ ///
+ /// domain rectangle object to be set.
+ ///
public virtual void SetDomain(PdfArray domain) {
GetPdfObject().Put(PdfName.Domain, domain);
SetModified();
}
+ ///
+ /// Gets the array of floats that represents the transformation matrix that maps the domain rectangle
+ /// into a corresponding figure in the target coordinate space.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of transformation matrix (identical matrix by default).
+ ///
public virtual float[] GetMatrix() {
PdfArray matrix = GetPdfObject().GetAsArray(PdfName.Matrix);
if (matrix == null) {
@@ -204,59 +385,197 @@ public virtual float[] GetMatrix() {
return result;
}
+ ///
+ /// Sets the array of floats that represents the transformation matrix that maps the domain rectangle
+ /// into a corresponding figure in the target coordinate space.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of transformation matrix to be set.
+ ///
public virtual void SetMatrix(float[] matrix) {
SetMatrix(new PdfArray(matrix));
}
+ ///
+ /// Sets the array of floats that represents the transformation matrix that maps the domain rectangle
+ /// into a corresponding figure in the target coordinate space.
+ ///
+ ///
+ /// the
+ ///
+ /// transformation matrix object to be set.
+ ///
public virtual void SetMatrix(PdfArray matrix) {
GetPdfObject().Put(PdfName.Matrix, matrix);
SetModified();
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with axial type,
+ /// that define a colour blend that varies along a linear axis between two endpoints
+ /// and extends indefinitely perpendicular to that axis.
+ ///
public class Axial : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public Axial(PdfDictionary pdfDictionary)
: base(pdfDictionary) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ /// the start coordinate of X axis expressed in the shading's target coordinate space.
+ /// the start coordinate of Y axis expressed in the shading's target coordinate space.
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the start point.
+ ///
+ /// the end coordinate of X axis expressed in the shading's target coordinate space.
+ /// the end coordinate of Y axis expressed in the shading's target coordinate space.
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the end point.
+ ///
public Axial(PdfColorSpace cs, float x0, float y0, float[] color0, float x1, float y1, float[] color1)
- : base(new PdfDictionary(), PdfShading.ShadingType.AXIAL, cs.GetPdfObject()) {
- if (cs is PdfSpecialCs.Pattern) {
- throw new ArgumentException("colorSpace");
- }
+ : base(new PdfDictionary(), PdfShading.ShadingType.AXIAL, cs) {
SetCoords(x0, y0, x1, y1);
PdfFunction func = new PdfFunction.Type2(new PdfArray(new float[] { 0, 1 }), null, new PdfArray(color0), new
PdfArray(color1), new PdfNumber(1));
SetFunction(func);
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ /// the start coordinate of X axis expressed in the shading's target coordinate space.
+ /// the start coordinate of Y axis expressed in the shading's target coordinate space.
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the start point.
+ ///
+ /// the end coordinate of X axis expressed in the shading's target coordinate space.
+ /// the end coordinate of Y axis expressed in the shading's target coordinate space.
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the end point.
+ ///
+ ///
+ /// the array of two booleans that specified whether to extend the shading
+ /// beyond the starting and ending points of the axis, respectively.
+ ///
public Axial(PdfColorSpace cs, float x0, float y0, float[] color0, float x1, float y1, float[] color1, bool
[] extend)
: this(cs, x0, y0, color0, x1, y1, color1) {
- if (extend != null) {
- SetExtend(extend[0], extend[1]);
+ if (extend == null || extend.Length != 2) {
+ throw new ArgumentException("extend");
}
- }
-
+ SetExtend(extend[0], extend[1]);
+ }
+
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the
+ ///
+ /// of four number four numbers [x0 y0 x1 y1] that specified the starting
+ /// and the endings coordinates of thew axis, expressed in the shading's target coordinate space.
+ ///
+ ///
+ /// the
+ ///
+ /// object, that is used to calculate color transitions.
+ ///
public Axial(PdfColorSpace cs, PdfArray coords, PdfFunction function)
- : base(new PdfDictionary(), PdfShading.ShadingType.AXIAL, cs.GetPdfObject()) {
+ : base(new PdfDictionary(), PdfShading.ShadingType.AXIAL, cs) {
SetCoords(coords);
SetFunction(function);
}
+ ///
+ /// Gets the Coords object - a
+ ///
+ /// of four numbers [x0 y0 x1 y1] that specified the starting
+ /// and the endings coordinates of thew axis, expressed in the shading's target coordinate space.
+ ///
+ ///
+ /// the
+ ///
+ /// Coords object.
+ ///
public virtual PdfArray GetCoords() {
return GetPdfObject().GetAsArray(PdfName.Coords);
}
+ /// Sets the Choords object with the four params expressed in the shading's target coordinate space.
+ /// the start coordinate of X axis to be set.
+ /// the start coordinate of Y axis to be set.
+ /// the end coordinate of X axis to be set.
+ /// the end coordinate of Y axis to be set.
public virtual void SetCoords(float x0, float y0, float x1, float y1) {
SetCoords(new PdfArray(new float[] { x0, y0, x1, y1 }));
}
+ ///
+ /// Sets the Choords object with the
+ ///
+ /// of four numbers [x0 y0 x1 y1],
+ /// that specified the starting and the endings coordinates of thew axis,
+ /// expressed in the shading's target coordinate space.
+ ///
+ ///
+ /// the Chords
+ ///
+ /// to be set.
+ ///
public virtual void SetCoords(PdfArray coords) {
GetPdfObject().Put(PdfName.Coords, coords);
SetModified();
}
+ ///
+ /// Gets the array of two
+ /// float
+ /// [t0, t1] that represent the limiting values of a parametric
+ /// variable t, that becomes an input of color function(s).
+ ///
+ ///
+ ///
+ /// float[]
+ /// of Domain object ([0.0 1.0] by default)
+ ///
public virtual float[] GetDomain() {
PdfArray domain = GetPdfObject().GetAsArray(PdfName.Domain);
if (domain == null) {
@@ -265,66 +584,270 @@ public virtual float[] GetDomain() {
return new float[] { domain.GetAsNumber(0).FloatValue(), domain.GetAsNumber(1).FloatValue() };
}
+ ///
+ /// Sets the Domain with the array of two
+ /// float
+ /// [t0, t1] that represent the limiting values
+ /// of a parametric variable t, that becomes an input of color function(s).
+ ///
+ /// first limit of variable t
+ /// second limit of variable t
public virtual void SetDomain(float t0, float t1) {
GetPdfObject().Put(PdfName.Domain, new PdfArray(new float[] { t0, t1 }));
SetModified();
}
+ ///
+ /// Gets the array of two
+ /// boolean
+ /// that specified whether to extend the shading
+ /// beyond the starting and ending points of the axis, respectively.
+ ///
+ ///
+ ///
+ /// boolean[]
+ /// of Extended object ([false false] by default)
+ ///
public virtual bool[] GetExtend() {
PdfArray extend = GetPdfObject().GetAsArray(PdfName.Extend);
if (extend == null) {
- return new bool[] { true, true };
+ return new bool[] { false, false };
}
return new bool[] { extend.GetAsBoolean(0).GetValue(), extend.GetAsBoolean(1).GetValue() };
}
+ ///
+ /// Sets the Extend object with the two
+ /// boolean
+ /// value.
+ ///
+ /// if true will extend shading beyond the starting point of Coords
+ /// if true will extend shading beyond the ending point of Coords
public virtual void SetExtend(bool extendStart, bool extendEnd) {
GetPdfObject().Put(PdfName.Extend, new PdfArray(new bool[] { extendStart, extendEnd }));
SetModified();
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with radial type,
+ /// that define a colour blend that varies between two circles.
+ /// This type of shading shall not be used with an Indexed colour space
+ ///
public class Radial : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ /// -
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public Radial(PdfDictionary pdfDictionary)
: base(pdfDictionary) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The Indexed color space isn't excepted.
+ ///
+ /// the X coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of starting circle's centre, should be greater or equal to 0.
+ /// If 0 then starting circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the start circle.
+ ///
+ /// the X coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of ending circle's centre, should be greater or equal to 0.
+ /// If 0 then ending circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the end circle.
+ ///
public Radial(PdfColorSpace cs, float x0, float y0, float r0, float[] color0, float x1, float y1, float r1
, float[] color1)
- : base(new PdfDictionary(), PdfShading.ShadingType.RADIAL, cs.GetPdfObject()) {
+ : base(new PdfDictionary(), PdfShading.ShadingType.RADIAL, cs) {
SetCoords(x0, y0, r0, x1, y1, r1);
PdfFunction func = new PdfFunction.Type2(new PdfArray(new float[] { 0, 1 }), null, new PdfArray(color0), new
PdfArray(color1), new PdfNumber(1));
SetFunction(func);
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The Indexed color space isn't excepted.
+ ///
+ /// the X coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of starting circle's centre, should be greater or equal to 0.
+ /// If 0 then starting circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the start circle.
+ ///
+ /// the X coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of ending circle's centre, should be greater or equal to 0.
+ /// If 0 then ending circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// that represents the color in the end circle.
+ ///
+ ///
+ /// the array of two
+ /// boolean
+ /// that specified whether to extend the shading
+ /// beyond the starting and ending points of the axis, respectively.
+ ///
public Radial(PdfColorSpace cs, float x0, float y0, float r0, float[] color0, float x1, float y1, float r1
, float[] color1, bool[] extend)
: this(cs, x0, y0, r0, color0, x1, y1, r1, color1) {
- if (extend != null) {
- SetExtend(extend[0], extend[1]);
+ if (extend == null || extend.Length != 2) {
+ throw new ArgumentException("extend");
}
- }
-
+ SetExtend(extend[0], extend[1]);
+ }
+
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The Indexed color space isn't excepted.
+ ///
+ ///
+ /// the
+ ///
+ /// of of six numbers [x0 y0 r0 x1 y1 r1],
+ /// specifying the centres and radii of the starting and ending circles,
+ /// expressed in the shading’s target coordinate space.
+ /// The radii r0 and r1 shall both be greater than or equal to 0.
+ /// If one radius is 0, the corresponding circle shall be treated as a point;
+ /// if both are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ ///
+ /// object, that is used to calculate color transitions.
+ ///
public Radial(PdfColorSpace cs, PdfArray coords, PdfFunction function)
- : base(new PdfDictionary(), PdfShading.ShadingType.RADIAL, cs.GetPdfObject()) {
+ : base(new PdfDictionary(), PdfShading.ShadingType.RADIAL, cs) {
SetCoords(coords);
SetFunction(function);
}
+ ///
+ /// Gets the coords
+ ///
+ /// object - an array of six numbers [x0 y0 r0 x1 y1 r1],
+ /// specifying the centres and radii of the starting and ending circles,
+ /// expressed in the shading’s target coordinate space.
+ /// The radii r0 and r1 shall both be greater than or equal to 0.
+ /// If one radius is 0, the corresponding circle shall be treated as a point;
+ /// if both are 0, nothing shall be painted.
+ ///
+ ///
+ /// the
+ ///
+ /// coords object.
+ ///
public virtual PdfArray GetCoords() {
return GetPdfObject().GetAsArray(PdfName.Coords);
}
+ /// Sets the coords object.
+ /// the X coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of starting circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of starting circle's centre, should be greater or equal to 0.
+ /// If 0 then starting circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
+ /// the X coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ /// the Y coordinate of ending circle's centre, expressed in in the shading’s target coordinate space.
+ ///
+ ///
+ /// the radius of ending circle's centre, should be greater or equal to 0.
+ /// If 0 then ending circle is treated as point.
+ /// If both radii are 0, nothing shall be painted.
+ ///
public virtual void SetCoords(float x0, float y0, float r0, float x1, float y1, float r1) {
SetCoords(new PdfArray(new float[] { x0, y0, r0, x1, y1, r1 }));
}
+ ///
+ /// Sets the coords
+ ///
+ /// object - an array of six numbers [x0 y0 r0 x1 y1 r1],
+ /// specifying the centres and radii of the starting and ending circles,
+ /// expressed in the shading’s target coordinate space.
+ /// The radii r0 and r1 shall both be greater than or equal to 0.
+ /// If one radius is 0, the corresponding circle shall be treated as a point;
+ /// if both are 0, nothing shall be painted.
+ ///
+ ///
+ /// -
+ ///
+ /// choords object to be set.
+ ///
public virtual void SetCoords(PdfArray coords) {
GetPdfObject().Put(PdfName.Coords, coords);
SetModified();
}
+ ///
+ /// Gets the array of two
+ /// float
+ /// [t0, t1] that represent the limiting values of a parametric
+ /// variable t, that becomes an input of color function(s).
+ ///
+ ///
+ ///
+ /// float[]
+ /// of Domain object ([0.0 1.0] by default)
+ ///
public virtual float[] GetDomain() {
PdfArray domain = GetPdfObject().GetAsArray(PdfName.Domain);
if (domain == null) {
@@ -333,257 +856,864 @@ public virtual float[] GetDomain() {
return new float[] { domain.GetAsNumber(0).FloatValue(), domain.GetAsNumber(1).FloatValue() };
}
+ ///
+ /// Sets the Domain with the array of two
+ /// float
+ /// [t0, t1] that represent the limiting values
+ /// of a parametric variable t, that becomes an input of color function(s).
+ ///
+ /// first limit of variable t
+ /// second limit of variable t
public virtual void SetDomain(float t0, float t1) {
GetPdfObject().Put(PdfName.Domain, new PdfArray(new float[] { t0, t1 }));
SetModified();
}
+ ///
+ /// Gets the array of two
+ /// boolean
+ /// that specified whether to extend the shading
+ /// beyond the starting and ending circles of the axis, respectively.
+ ///
+ ///
+ ///
+ /// boolean[]
+ /// of Extended object ([false false] by default)
+ ///
public virtual bool[] GetExtend() {
PdfArray extend = GetPdfObject().GetAsArray(PdfName.Extend);
if (extend == null) {
- return new bool[] { true, true };
+ return new bool[] { false, false };
}
return new bool[] { extend.GetAsBoolean(0).GetValue(), extend.GetAsBoolean(1).GetValue() };
}
+ ///
+ /// Sets the Extend object with the two
+ /// boolean
+ /// value.
+ ///
+ /// if true will extend shading beyond the starting circle of Coords.
+ /// if true will extend shading beyond the ending circle of Coords.
public virtual void SetExtend(bool extendStart, bool extendEnd) {
GetPdfObject().Put(PdfName.Extend, new PdfArray(new bool[] { extendStart, extendEnd }));
SetModified();
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with
+ /// free-form Gouraud-shaded triangle mesh type.
+ /// The area to be shaded is defined by a path composed entirely of triangles.
+ /// The colour at each vertex of the triangles is specified,
+ /// and a technique known as Gouraud interpolation is used to colour the interiors.
+ /// The object shall be represented as stream containing a sequence of vertex data.
+ /// Each vertex is specified by the following values, in the order shown:
+ /// f x y c1 … cn where:
+ /// f - the vertex’s edge flag, that determines the vertex is connected to other vertices of the triangle mesh.
+ /// For full description
+ /// ISO-320001 Paragph 8.7.4.5.5
+ /// x, y - vertex’s horizontal and vertical coordinates, expressed in the shading’s target coordinate space.
+ /// c1…cn - vertex’s colour components.
+ /// If the shading dictionary includes a Function entry, only a single parametric value, t,
+ /// shall be specified for each vertex in place of the colour components c1…cn.
+ ///
public class FreeFormGouraudShadedTriangleMesh : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public FreeFormGouraudShadedTriangleMesh(PdfStream pdfStream)
: base(pdfStream) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, or 2.
+ ///
+ ///
+ /// the
+ /// int[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public FreeFormGouraudShadedTriangleMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int
bitsPerFlag, float[] decode)
: this(cs, bitsPerCoordinate, bitsPerComponent, bitsPerFlag, new PdfArray(decode)) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, or 2.
+ ///
+ ///
+ /// the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public FreeFormGouraudShadedTriangleMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int
bitsPerFlag, PdfArray decode)
- : base(new PdfStream(), PdfShading.ShadingType.FREE_FORM_GOURAUD_SHADED_TRIANGLE_MESH, cs.GetPdfObject()) {
+ : base(new PdfStream(), PdfShading.ShadingType.FREE_FORM_GOURAUD_SHADED_TRIANGLE_MESH, cs) {
SetBitsPerCoordinate(bitsPerCoordinate);
SetBitsPerComponent(bitsPerComponent);
SetBitsPerFlag(bitsPerFlag);
SetDecode(decode);
}
+ /// Gets the number of bits used to represent each vertex coordinate.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual int GetBitsPerCoordinate() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerCoordinate);
}
+ /// Sets the number of bits used to represent each vertex coordinate.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual void SetBitsPerCoordinate(int bitsPerCoordinate) {
GetPdfObject().Put(PdfName.BitsPerCoordinate, new PdfNumber(bitsPerCoordinate));
SetModified();
}
+ /// Gets the number of bits used to represent each colour component.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, or 16.
public virtual int GetBitsPerComponent() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerComponent);
}
+ /// Sets the number of bits used to represent each colour component.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, or 16.
public virtual void SetBitsPerComponent(int bitsPerComponent) {
GetPdfObject().Put(PdfName.BitsPerComponent, new PdfNumber(bitsPerComponent));
SetModified();
}
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1 or 2.
+ ///
+ /// the number of bits. Can be 2, 4 or 8.
public virtual int GetBitsPerFlag() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerFlag);
}
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1 or 2.
+ ///
+ /// the number of bits to be set. Shall be 2, 4 or 8.
public virtual void SetBitsPerFlag(int bitsPerFlag) {
GetPdfObject().Put(PdfName.BitsPerFlag, new PdfNumber(bitsPerFlag));
SetModified();
}
+ ///
+ /// Gets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object.
+ ///
public virtual PdfArray GetDecode() {
return GetPdfObject().GetAsArray(PdfName.Decode);
}
+ ///
+ /// Sets the
+ /// float[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of Decode object to set.
+ ///
public virtual void SetDecode(float[] decode) {
GetPdfObject().Put(PdfName.Decode, new PdfArray(decode));
}
+ ///
+ /// Sets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object to set.
+ ///
public virtual void SetDecode(PdfArray decode) {
GetPdfObject().Put(PdfName.Decode, decode);
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with
+ /// lattice-form Gouraud-shaded triangle mesh type.
+ /// This type is similar to
+ ///
+ /// but instead of using free-form geometry,
+ /// the vertices are arranged in a pseudorectangular lattice,
+ /// which is topologically equivalent to a rectangular grid.
+ /// The vertices are organized into rows, which need not be geometrically linear.
+ /// The verticals data in stream is similar to
+ ///
+ /// ,
+ /// except there is no edge flag.
+ ///
public class LatticeFormGouraudShadedTriangleMesh : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public LatticeFormGouraudShadedTriangleMesh(PdfStream pdfStream)
: base(pdfStream) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of vertices in each row of the lattice (shall be > 1).
+ /// The number of rows need not be specified.
+ ///
+ ///
+ /// the
+ /// int[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public LatticeFormGouraudShadedTriangleMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent,
int verticesPerRow, float[] decode)
: this(cs, bitsPerCoordinate, bitsPerComponent, verticesPerRow, new PdfArray(decode)) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of vertices in each row of the lattice (shall be > 1).
+ /// The number of rows need not be specified.
+ ///
+ ///
+ /// the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public LatticeFormGouraudShadedTriangleMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent,
int verticesPerRow, PdfArray decode)
- : base(new PdfStream(), PdfShading.ShadingType.LATTICE_FORM_GOURAUD_SHADED_TRIANGLE_MESH, cs.GetPdfObject(
- )) {
+ : base(new PdfStream(), PdfShading.ShadingType.LATTICE_FORM_GOURAUD_SHADED_TRIANGLE_MESH, cs) {
SetBitsPerCoordinate(bitsPerCoordinate);
SetBitsPerComponent(bitsPerComponent);
SetVerticesPerRow(verticesPerRow);
SetDecode(decode);
}
+ /// Gets the number of bits used to represent each vertex coordinate.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual int GetBitsPerCoordinate() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerCoordinate);
}
+ /// Sets the number of bits used to represent each vertex coordinate.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual void SetBitsPerCoordinate(int bitsPerCoordinate) {
GetPdfObject().Put(PdfName.BitsPerCoordinate, new PdfNumber(bitsPerCoordinate));
SetModified();
}
+ /// Gets the number of bits used to represent each colour component.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, or 16.
public virtual int GetBitsPerComponent() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerComponent);
}
+ /// Sets the number of bits used to represent each colour component.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, or 16.
public virtual void SetBitsPerComponent(int bitsPerComponent) {
GetPdfObject().Put(PdfName.BitsPerComponent, new PdfNumber(bitsPerComponent));
SetModified();
}
+ /// Gets the number of vertices in each row of the lattice.
+ /// the number of vertices. Can only be greater than 1.
public virtual int GetVerticesPerRow() {
return (int)GetPdfObject().GetAsInt(PdfName.VerticesPerRow);
}
+ /// Sets the number of vertices in each row of the lattice.
+ ///
+ /// Sets the number of vertices in each row of the lattice.
+ /// The number of rows need not be specified.
+ ///
+ /// the number of vertices to be set. Shall be greater than 1.
public virtual void SetVerticesPerRow(int verticesPerRow) {
GetPdfObject().Put(PdfName.VerticesPerRow, new PdfNumber(verticesPerRow));
SetModified();
}
+ ///
+ /// Gets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object.
+ ///
public virtual PdfArray GetDecode() {
return GetPdfObject().GetAsArray(PdfName.Decode);
}
+ ///
+ /// Sets the
+ /// float[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of Decode object to set.
+ ///
public virtual void SetDecode(float[] decode) {
GetPdfObject().Put(PdfName.Decode, new PdfArray(decode));
}
+ ///
+ /// Sets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object to set.
+ ///
public virtual void SetDecode(PdfArray decode) {
GetPdfObject().Put(PdfName.Decode, decode);
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with
+ /// Coons Patch mesh type.
+ /// This type of shading is constructed from one or more colour patches, each bounded by four cubic Bézier curves.
+ /// Degenerate Bézier curves are allowed and are useful for certain graphical effects.
+ /// At least one complete patch shall be specified.
+ /// The shape of patch is defined by 12 control points.
+ /// Colours are specified for each corner of the unit square,
+ /// and bilinear interpolation is used to fill in colours over the entire unit square.
+ /// Coordinates are mapped from the unit square into a four-sided patch whose sides are not necessarily linear.
+ /// The mapping is continuous: the corners of the unit square map to corners of the patch
+ /// and the sides of the unit square map to sides of the patch.
+ /// For the format of data stream, that defines patches
+ /// ISO-320001 Table 85
+ /// .
+ /// If the shading dictionary contains a Function entry, the colour data for each corner of a patch
+ /// shall be specified by a single parametric value t rather than by n separate colour components c1…cn.
+ ///
public class CoonsPatchMesh : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public CoonsPatchMesh(PdfStream pdfStream)
: base(pdfStream) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, 2 or 3.
+ ///
+ ///
+ /// the
+ /// int[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public CoonsPatchMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int bitsPerFlag, float
[] decode)
: this(cs, bitsPerCoordinate, bitsPerComponent, bitsPerFlag, new PdfArray(decode)) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, 2 or 3.
+ ///
+ ///
+ /// the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public CoonsPatchMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int bitsPerFlag, PdfArray
decode)
- : base(new PdfStream(), PdfShading.ShadingType.COONS_PATCH_MESH, cs.GetPdfObject()) {
+ : base(new PdfStream(), PdfShading.ShadingType.COONS_PATCH_MESH, cs) {
SetBitsPerCoordinate(bitsPerCoordinate);
SetBitsPerComponent(bitsPerComponent);
SetBitsPerFlag(bitsPerFlag);
SetDecode(decode);
}
+ /// Gets the number of bits used to represent each vertex coordinate.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual int GetBitsPerCoordinate() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerCoordinate);
}
+ /// Sets the number of bits used to represent each vertex coordinate.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual void SetBitsPerCoordinate(int bitsPerCoordinate) {
GetPdfObject().Put(PdfName.BitsPerCoordinate, new PdfNumber(bitsPerCoordinate));
SetModified();
}
+ /// Gets the number of bits used to represent each colour component.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, or 16.
public virtual int GetBitsPerComponent() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerComponent);
}
+ /// Sets the number of bits used to represent each colour component.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, or 16.
public virtual void SetBitsPerComponent(int bitsPerComponent) {
GetPdfObject().Put(PdfName.BitsPerComponent, new PdfNumber(bitsPerComponent));
SetModified();
}
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1, 2 or 3.
+ ///
+ /// the number of bits. Can be 2, 4 or 8.
public virtual int GetBitsPerFlag() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerFlag);
}
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1, 2 or 3.
+ ///
+ /// the number of bits to be set. Shall be 2, 4 or 8.
public virtual void SetBitsPerFlag(int bitsPerFlag) {
GetPdfObject().Put(PdfName.BitsPerFlag, new PdfNumber(bitsPerFlag));
SetModified();
}
+ ///
+ /// Gets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object.
+ ///
public virtual PdfArray GetDecode() {
return GetPdfObject().GetAsArray(PdfName.Decode);
}
+ ///
+ /// Sets the
+ /// float[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of Decode object to set.
+ ///
public virtual void SetDecode(float[] decode) {
GetPdfObject().Put(PdfName.Decode, new PdfArray(decode));
}
+ ///
+ /// Sets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object to set.
+ ///
public virtual void SetDecode(PdfArray decode) {
GetPdfObject().Put(PdfName.Decode, decode);
}
}
+ ///
+ /// The class that extends
+ ///
+ /// class and is in charge of Shading Dictionary with
+ /// Tensor-Product Patch mesh type.
+ /// This type of shading is identical to
+ ///
+ /// , except that it's based on a
+ /// bicubic tensor-product patch defined by 16 control points.
+ /// For the format of data stream, that defines patches
+ /// ISO-320001 Table 86
+ /// .
+ ///
public class TensorProductPatchMesh : PdfShading {
+ ///
+ /// Creates the new instance of the class from the existing
+ ///
+ /// object.
+ ///
+ ///
+ ///
+ ///
+ /// from which the instance is created.
+ ///
+ [System.ObsoleteAttribute(@"Intended only for private use. You should use PdfShading.MakeShading(iText.Kernel.Pdf.PdfDictionary) instead."
+ )]
public TensorProductPatchMesh(PdfStream pdfStream)
: base(pdfStream) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, 2 or 3.
+ ///
+ ///
+ /// the
+ /// int[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public TensorProductPatchMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int bitsPerFlag
, float[] decode)
: this(cs, bitsPerCoordinate, bitsPerComponent, bitsPerFlag, new PdfArray(decode)) {
}
+ /// Creates the new instance of the class.
+ ///
+ /// the
+ ///
+ /// object in which colour values shall be expressed.
+ /// The special Pattern space isn't excepted.
+ ///
+ ///
+ /// the number of bits used to represent each vertex coordinate.
+ /// The value shall be 1, 2, 4, 8, 12, 16, 24, or 32.
+ ///
+ ///
+ /// the number of bits used to represent each colour component.
+ /// The value shall be 1, 2, 4, 8, 12, or 16.
+ ///
+ ///
+ /// the number of bits used to represent the edge flag for each vertex.
+ /// The value of BitsPerFlag shall be 2, 4, or 8,
+ /// but only the least significant 2 bits in each flag value shall be used.
+ /// The value for the edge flag shall be 0, 1, 2 or 3.
+ ///
+ ///
+ /// the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
public TensorProductPatchMesh(PdfColorSpace cs, int bitsPerCoordinate, int bitsPerComponent, int bitsPerFlag
, PdfArray decode)
- : base(new PdfStream(), PdfShading.ShadingType.TENSOR_PRODUCT_PATCH_MESH, cs.GetPdfObject()) {
+ : base(new PdfStream(), PdfShading.ShadingType.TENSOR_PRODUCT_PATCH_MESH, cs) {
SetBitsPerCoordinate(bitsPerCoordinate);
SetBitsPerComponent(bitsPerComponent);
SetBitsPerFlag(bitsPerFlag);
SetDecode(decode);
}
+ /// Gets the number of bits used to represent each vertex coordinate.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual int GetBitsPerCoordinate() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerCoordinate);
}
+ /// Sets the number of bits used to represent each vertex coordinate.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, 16, 24, or 32.
public virtual void SetBitsPerCoordinate(int bitsPerCoordinate) {
GetPdfObject().Put(PdfName.BitsPerCoordinate, new PdfNumber(bitsPerCoordinate));
SetModified();
}
+ /// Gets the number of bits used to represent each colour component.
+ /// the number of bits. Can be 1, 2, 4, 8, 12, or 16.
public virtual int GetBitsPerComponent() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerComponent);
}
+ /// Sets the number of bits used to represent each colour component.
+ /// the number of bits to be set. Shall be 1, 2, 4, 8, 12, or 16.
public virtual void SetBitsPerComponent(int bitsPerComponent) {
GetPdfObject().Put(PdfName.BitsPerComponent, new PdfNumber(bitsPerComponent));
SetModified();
}
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Gets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1, 2 or 3.
+ ///
+ /// the number of bits. Can be 2, 4 or 8.
public virtual int GetBitsPerFlag() {
return (int)GetPdfObject().GetAsInt(PdfName.BitsPerFlag);
}
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ ///
+ /// Sets the number of bits used to represent the edge flag for each vertex.
+ /// But only the least significant 2 bits in each flag value shall be used.
+ /// The valid flag values are 0, 1, 2 or 3.
+ ///
+ /// the number of bits to be set. Shall be 2, 4 or 8.
public virtual void SetBitsPerFlag(int bitsPerFlag) {
GetPdfObject().Put(PdfName.BitsPerFlag, new PdfNumber(bitsPerFlag));
SetModified();
}
+ ///
+ /// Gets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object.
+ ///
public virtual PdfArray GetDecode() {
return GetPdfObject().GetAsArray(PdfName.Decode);
}
+ ///
+ /// Sets the
+ /// float[]
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ /// float[]
+ /// of Decode object to set.
+ ///
public virtual void SetDecode(float[] decode) {
GetPdfObject().Put(PdfName.Decode, new PdfArray(decode));
}
+ ///
+ /// Sets the
+ ///
+ /// of numbers specifying how to map vertex coordinates and colour components
+ /// into the appropriate ranges of values. The ranges shall be specified as follows:
+ /// [x_min x_max y_min y_max c1_min c1_max … cn_min cn_max].
+ /// Only one pair of color values shall be specified if a Function entry is present.
+ ///
+ ///
+ /// the
+ ///
+ /// Decode object to set.
+ ///
public virtual void SetDecode(PdfArray decode) {
GetPdfObject().Put(PdfName.Decode, decode);
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfSpecialCs.cs b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfSpecialCs.cs
index 7bce84ce70..465bed14e5 100644
--- a/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfSpecialCs.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/colorspace/PdfSpecialCs.cs
@@ -53,6 +53,21 @@ protected internal PdfSpecialCs(PdfArray pdfObject)
: base(pdfObject) {
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
@@ -212,6 +227,21 @@ public override int GetNumberOfComponents() {
}
public class UncoloredTilingPattern : PdfSpecialCs.Pattern {
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/extgstate/PdfExtGState.cs b/itext/itext.kernel/itext/kernel/pdf/extgstate/PdfExtGState.cs
index 2de6029cca..4d88460ec3 100644
--- a/itext/itext.kernel/itext/kernel/pdf/extgstate/PdfExtGState.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/extgstate/PdfExtGState.cs
@@ -41,278 +41,1093 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
+using System;
using iText.Kernel.Pdf;
namespace iText.Kernel.Pdf.Extgstate {
+ /// Graphics state parameter dictionary wrapper.
+ ///
+ /// Graphics state parameter dictionary wrapper.
+ /// See ISO-320001, 8.4.5 Graphics State Parameter Dictionaries.
+ ///
public class PdfExtGState : PdfObjectWrapper {
- /// Blend mode constants
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_NORMAL = PdfName.Normal;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_MULTIPLY = PdfName.Multiply;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_SCREEN = PdfName.Screen;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_OVERLAY = PdfName.Overlay;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_DARKEN = PdfName.Darken;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_LIGHTEN = PdfName.Lighten;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_COLOR_DODGE = PdfName.ColorDodge;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_COLOR_BURN = PdfName.ColorBurn;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_HARD_LIGHT = PdfName.HardLight;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_SOFT_LIGHT = PdfName.SoftLight;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_DIFFERENCE = PdfName.Difference;
+ /// Standard separable blend mode.
+ /// Standard separable blend mode. See ISO-320001, table 136
public static PdfName BM_EXCLUSION = PdfName.Exclusion;
+ /// Standard nonseparable blend mode.
+ /// Standard nonseparable blend mode. See ISO-320001, table 137
public static PdfName BM_HUE = PdfName.Hue;
+ /// Standard nonseparable blend mode.
+ /// Standard nonseparable blend mode. See ISO-320001, table 137
public static PdfName BM_SATURATION = PdfName.Saturation;
+ /// Standard nonseparable blend mode.
+ /// Standard nonseparable blend mode. See ISO-320001, table 137
public static PdfName BM_COLOR = PdfName.Color;
+ /// Standard nonseparable blend mode.
+ /// Standard nonseparable blend mode. See ISO-320001, table 137
public static PdfName BM_LUMINOSITY = PdfName.Luminosity;
+ ///
+ /// Create instance of graphics state parameter dictionary wrapper
+ /// by existed
+ /// PdfDictionary
+ /// object
+ ///
+ /// instance of graphics state parameter dictionary
public PdfExtGState(PdfDictionary pdfObject)
: base(pdfObject) {
- MarkObjectAsIndirect(GetPdfObject());
}
+ /// Create default instance of graphics state parameter dictionary
public PdfExtGState()
: this(new PdfDictionary()) {
}
+ ///
+ /// Gets line width value,
+ /// LW
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetLineWidth() {
return GetPdfObject().GetAsFloat(PdfName.LW);
}
+ ///
+ /// Sets line width value,
+ /// LW
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetLineWidth(float lineWidth) {
return Put(PdfName.LW, new PdfNumber(lineWidth));
}
+ ///
+ /// Gets line gap style value,
+ /// LC
+ /// key.
+ ///
+ /// 0 - butt cap, 1 - round cap, 2 - projecting square cap.
public virtual int? GetLineCapStyle() {
return GetPdfObject().GetAsInt(PdfName.LC);
}
+ ///
+ /// Sets line gap style value,
+ /// LC
+ /// key.
+ ///
+ /// 0 - butt cap, 1 - round cap, 2 - projecting square cap.
+ /// object itself.
+ [System.ObsoleteAttribute(@"Use SetLineCapStyle(int) instead.")]
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetLineCapStryle(int lineCapStyle) {
return Put(PdfName.LC, new PdfNumber(lineCapStyle));
}
+ ///
+ /// Sets line gap style value,
+ /// LC
+ /// key.
+ ///
+ /// 0 - butt cap, 1 - round cap, 2 - projecting square cap.
+ /// object itself.
+ public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetLineCapStyle(int lineCapStyle) {
+ return Put(PdfName.LC, new PdfNumber(lineCapStyle));
+ }
+
+ ///
+ /// Gets line join style value,
+ /// LJ
+ /// key.
+ ///
+ /// 0 - miter join (see also miter limit), 1 - round join, 2 - bevel join.
public virtual int? GetLineJoinStyle() {
return GetPdfObject().GetAsInt(PdfName.LJ);
}
+ ///
+ /// Sets line join style value,
+ /// LJ
+ /// key.
+ ///
+ /// 0 - miter join (see also miter limit), 1 - round join, 2 - bevel join.
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetLineJoinStyle(int lineJoinStyle) {
return Put(PdfName.LJ, new PdfNumber(lineJoinStyle));
}
+ ///
+ /// Gets miter limit value,
+ /// ML key
+ /// . See also line join style.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetMiterLimit() {
return GetPdfObject().GetAsFloat(PdfName.ML);
}
+ ///
+ /// Sets miter limit value,
+ /// ML key
+ /// . See also line join style.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetMiterLimit(float miterLimit) {
return Put(PdfName.ML, new PdfNumber(miterLimit));
}
+ ///
+ /// Gets line dash pattern value,
+ /// D
+ /// key.
+ ///
+ ///
+ /// a
+ /// PdfArray
+ /// , that represents line dash pattern.
+ ///
public virtual PdfArray GetDashPattern() {
return GetPdfObject().GetAsArray(PdfName.D);
}
+ ///
+ /// Sets line dash pattern value,
+ /// D
+ /// key.
+ ///
+ ///
+ /// a
+ /// PdfArray
+ /// , that represents line dash pattern.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetDashPattern(PdfArray dashPattern) {
return Put(PdfName.D, dashPattern);
}
+ ///
+ /// Gets rendering intent value,
+ /// RI
+ /// key.
+ /// Valid values are:
+ /// AbsoluteColorimetric
+ /// ,
+ /// RelativeColorimetric
+ /// ,
+ /// Saturation
+ /// ,
+ /// Perceptual
+ /// .
+ ///
+ ///
+ /// a
+ /// PdfName
+ /// instance.
+ ///
public virtual PdfName GetRenderingIntent() {
return GetPdfObject().GetAsName(PdfName.RI);
}
+ ///
+ /// Sets rendering intent value,
+ /// RI
+ /// key.
+ ///
+ ///
+ /// a
+ /// PdfName
+ /// instance, Valid values are:
+ /// AbsoluteColorimetric
+ /// ,
+ /// RelativeColorimetric
+ /// ,
+ /// Saturation
+ /// ,
+ /// Perceptual
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetRenderingIntent(PdfName renderingIntent) {
return Put(PdfName.RI, renderingIntent);
}
- public virtual int? GetOverprintMode() {
- return GetPdfObject().GetAsInt(PdfName.OPM);
+ ///
+ /// Get overprint flag value for stroking operations,
+ /// OP
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
+ public virtual bool? GetStrokeOverprintFlag() {
+ return GetPdfObject().GetAsBool(PdfName.OP);
}
- public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetOverprintMode(int overprintMode) {
- return Put(PdfName.OPM, new PdfNumber(overprintMode));
+ ///
+ /// Set overprint flag value for stroking operations,
+ /// OP
+ /// key.
+ ///
+ ///
+ ///
+ ///
+ /// , for applying overprint for stroking operations.
+ ///
+ /// object itself.
+ public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetStrokeOverPrintFlag(bool strokeOverPrintFlag) {
+ return Put(PdfName.OP, new PdfBoolean(strokeOverPrintFlag));
}
+ ///
+ /// Get overprint flag value for non-stroking operations,
+ /// op
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual bool? GetFillOverprintFlag() {
return GetPdfObject().GetAsBool(PdfName.op);
}
+ ///
+ /// Set overprint flag value for non-stroking operations,
+ /// op
+ /// key.
+ ///
+ ///
+ ///
+ ///
+ /// , for applying overprint for non-stroking operations.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetFillOverPrintFlag(bool fillOverprintFlag) {
return Put(PdfName.op, new PdfBoolean(fillOverprintFlag));
}
- public virtual bool? GetStrokeOverprintFlag() {
- return GetPdfObject().GetAsBool(PdfName.OP);
+ ///
+ /// Get overprint control mode,
+ /// OPM
+ /// key.
+ ///
+ ///
+ /// an
+ /// int
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
+ public virtual int? GetOverprintMode() {
+ return GetPdfObject().GetAsInt(PdfName.OPM);
}
- public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetStrokeOverPrintFlag(bool strokeOverPrintFlag) {
- return Put(PdfName.OP, new PdfBoolean(strokeOverPrintFlag));
+ ///
+ /// Set overprint control mode,
+ /// OPM
+ /// key.
+ ///
+ ///
+ /// an
+ /// int
+ /// value, see ISO-320001, 8.6.7 Overprint Control.
+ ///
+ /// object itself.
+ public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetOverprintMode(int overprintMode) {
+ return Put(PdfName.OPM, new PdfNumber(overprintMode));
}
+ ///
+ /// Gets font and size,
+ /// Font
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// of the form
+ /// [font size]
+ /// , where
+ /// font
+ /// shall be an indirect reference to a font dictionary and
+ /// size
+ /// shall be a number expressed in text space units.
+ ///
public virtual PdfArray GetFont() {
return GetPdfObject().GetAsArray(PdfName.Font);
}
+ ///
+ /// Sets font and size,
+ /// Font
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// of the form
+ /// [font size]
+ /// , where
+ ///
+ /// shall be an indirect reference to a font dictionary and
+ /// size
+ /// shall be a number expressed in text space units.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetFont(PdfArray font) {
return Put(PdfName.Font, font);
}
+ ///
+ /// Gets the black-generation function value,
+ /// BG
+ /// .
+ ///
+ ///
+ /// a
+ ///
+ /// , should be
+ ///
+ /// .
+ ///
public virtual PdfObject GetBlackGenerationFunction() {
return GetPdfObject().Get(PdfName.BG);
}
+ ///
+ /// Sets the black-generation function value,
+ /// BG
+ /// .
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetBlackGenerationFunction(PdfObject blackGenerationFunction
) {
return Put(PdfName.BG, blackGenerationFunction);
}
+ ///
+ /// Gets the black-generation function value or
+ /// Default
+ /// ,
+ /// BG2
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// value, should be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetBlackGenerationFunction2() {
return GetPdfObject().Get(PdfName.BG2);
}
+ ///
+ /// Sets the black-generation function value or
+ /// Default
+ /// ,
+ /// BG2
+ /// key.
+ /// Note, if both
+ /// BG
+ /// and
+ /// BG2
+ /// are present in the same graphics state parameter dictionary,
+ /// BG2
+ /// takes precedence.
+ ///
+ ///
+ /// a
+ ///
+ /// value, shall be either
+ ///
+ /// or
+ /// Default
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetBlackGenerationFunction2(PdfObject blackGenerationFunction2
) {
return Put(PdfName.BG2, blackGenerationFunction2);
}
+ ///
+ /// Gets the undercolor-removal function,
+ /// UCR
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be
+ ///
+ /// .
+ ///
public virtual PdfObject GetUndercolorRemovalFunction() {
return GetPdfObject().Get(PdfName.UCR);
}
+ ///
+ /// Sets the undercolor-removal function,
+ /// UCR
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetUndercolorRemovalFunction(PdfObject undercolorRemovalFunction
) {
return Put(PdfName.UCR, undercolorRemovalFunction);
}
+ ///
+ /// Gets the undercolor-removal function value or
+ /// Default
+ /// ,
+ /// UCR2
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// value, should be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetUndercolorRemovalFunction2() {
return GetPdfObject().Get(PdfName.UCR2);
}
+ ///
+ /// Sets the undercolor-removal function value or
+ /// Default
+ /// ,
+ /// UCR2
+ /// key.
+ /// Note, if both
+ /// UCR
+ /// and
+ /// UCR2
+ /// are present in the same graphics state parameter dictionary,
+ /// UCR2
+ /// takes precedence.
+ ///
+ ///
+ /// a
+ ///
+ /// value, shall be either
+ ///
+ /// or
+ /// Default
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetUndercolorRemovalFunction2(PdfObject undercolorRemovalFunction2
) {
return Put(PdfName.UCR2, undercolorRemovalFunction2);
}
+ ///
+ /// Gets the transfer function value,
+ /// TR
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetTransferFunction() {
return GetPdfObject().Get(PdfName.TR);
}
+ ///
+ /// Sets the transfer function value,
+ /// TR
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetTransferFunction(PdfObject transferFunction) {
return Put(PdfName.TR, transferFunction);
}
+ ///
+ /// Gets the transfer function value or
+ /// Default
+ /// ,
+ /// TR2
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetTransferFunction2() {
return GetPdfObject().Get(PdfName.TR2);
}
- public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetTransferFunction2(PdfObject transferFunction) {
- return Put(PdfName.TR2, transferFunction);
+ ///
+ /// Sets the transfer function value or
+ /// Default
+ /// ,
+ /// TR2
+ /// key.
+ /// Note, if both
+ /// TR
+ /// and
+ /// TR2
+ /// are present in the same graphics state parameter dictionary,
+ /// TR2
+ /// takes precedence.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be either
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// or
+ /// Default
+ /// .
+ ///
+ /// object itself.
+ public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetTransferFunction2(PdfObject transferFunction2) {
+ return Put(PdfName.TR2, transferFunction2);
}
+ ///
+ /// Gets the halftone dictionary, stream or
+ /// Default
+ /// ,
+ /// HT
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetHalftone() {
return GetPdfObject().Get(PdfName.HT);
}
+ ///
+ /// Sets the halftone or
+ /// Default
+ /// ,
+ /// HT
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be either
+ ///
+ /// ,
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetHalftone(PdfObject halftone) {
return Put(PdfName.HT, halftone);
}
+ ///
+ /// Gets
+ /// HTP
+ /// key.
+ ///
+ [Obsolete]
public virtual PdfObject GetHTP() {
return GetPdfObject().Get(PdfName.HTP);
}
+ ///
+ /// Sets
+ /// HTP
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// .
+ ///
+ /// object itself.
+ [Obsolete]
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetHTP(PdfObject htp) {
return Put(PdfName.HTP, htp);
}
+ ///
+ /// Gets the flatness tolerance value,
+ /// FL
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetFlatnessTolerance() {
- return GetPdfObject().GetAsFloat(PdfName.FT);
+ return GetPdfObject().GetAsFloat(PdfName.FL);
}
+ ///
+ /// Sets the flatness tolerance value,
+ /// FL
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetFlatnessTolerance(float flatnessTolerance) {
- return Put(PdfName.FT, new PdfNumber(flatnessTolerance));
+ return Put(PdfName.FL, new PdfNumber(flatnessTolerance));
}
+ ///
+ /// Gets the smoothness tolerance value,
+ /// SM
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetSmothnessTolerance() {
return GetPdfObject().GetAsFloat(PdfName.SM);
}
+ ///
+ /// Sets the smoothness tolerance value,
+ /// SM
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetSmoothnessTolerance(float smoothnessTolerance) {
return Put(PdfName.SM, new PdfNumber(smoothnessTolerance));
}
+ ///
+ /// Gets value of an automatic stroke adjustment flag,
+ /// SA
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual bool? GetAutomaticStrokeAdjustmentFlag() {
return GetPdfObject().GetAsBool(PdfName.SA);
}
+ ///
+ /// Sets value of an automatic stroke adjustment flag,
+ /// SA
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetAutomaticStrokeAdjustmentFlag(bool strokeAdjustment
) {
return Put(PdfName.SA, new PdfBoolean(strokeAdjustment));
}
+ ///
+ /// Gets the current blend mode for the transparent imaging model,
+ /// BM
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetBlendMode() {
return GetPdfObject().Get(PdfName.BM);
}
+ ///
+ /// Sets the current blend mode for the transparent imaging model,
+ /// BM
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetBlendMode(PdfObject blendMode) {
return Put(PdfName.BM, blendMode);
}
+ ///
+ /// Gets the current soft mask,
+ /// SMask
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , should be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
public virtual PdfObject GetSoftMask() {
return GetPdfObject().Get(PdfName.SMask);
}
+ ///
+ /// Sets the current soft mask,
+ /// SMask
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , shall be either
+ ///
+ /// or
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetSoftMask(PdfObject sMask) {
return Put(PdfName.SMask, sMask);
}
+ ///
+ /// Gets the current alpha constant, specifying the constant shape or constant opacity value
+ /// for stroking operations in the transparent imaging model,
+ /// CA
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetStrokeOpacity() {
return GetPdfObject().GetAsFloat(PdfName.CA);
}
+ ///
+ /// Sets the current alpha constant, specifying the constant shape or constant opacity value
+ /// for stroking operations in the transparent imaging model,
+ /// CA
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetStrokeOpacity(float strokingAlphaConstant) {
return Put(PdfName.CA, new PdfNumber(strokingAlphaConstant));
}
+ ///
+ /// Gets the current alpha constant, specifying the constant shape or constant opacity value
+ /// for non-stroking operations in the transparent imaging model,
+ /// ca
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual float? GetFillOpacity() {
return GetPdfObject().GetAsFloat(PdfName.ca);
}
+ ///
+ /// Sets the current alpha constant, specifying the constant shape or constant opacity value
+ /// for non-stroking operations in the transparent imaging model,
+ /// ca
+ /// key.
+ ///
+ ///
+ /// a
+ /// float
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetFillOpacity(float fillingAlphaConstant) {
return Put(PdfName.ca, new PdfNumber(fillingAlphaConstant));
}
+ ///
+ /// Gets the alpha source flag (“alpha is shape”), specifying whether the current soft mask and alpha constant
+ /// shall be interpreted as shape values (
+ ///
+ /// ) or opacity values (
+ ///
+ /// ),
+ /// AIS
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual bool? GetAlphaSourceFlag() {
return GetPdfObject().GetAsBool(PdfName.AIS);
}
+ ///
+ /// Sets the alpha source flag (“alpha is shape”), specifying whether the current soft mask and alpha constant
+ /// shall be interpreted as shape values (
+ ///
+ /// ) or opacity values (
+ ///
+ /// ),
+ /// AIS
+ /// key.
+ ///
+ ///
+ /// if
+ ///
+ /// - alpha as shape values, if
+ ///
+ /// — as opacity values.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetAlphaSourceFlag(bool alphaSourceFlag) {
return Put(PdfName.AIS, new PdfBoolean(alphaSourceFlag));
}
+ ///
+ /// Gets the text knockout flag, which determine the behaviour of overlapping glyphs
+ /// within a text object in the transparent imaging model,
+ /// TK
+ /// key.
+ ///
+ ///
+ /// a
+ /// boolean
+ /// value if exist, otherwise
+ ///
+ /// .
+ ///
public virtual bool? GetTextKnockoutFlag() {
return GetPdfObject().GetAsBool(PdfName.TK);
}
+ ///
+ /// Sets the text knockout flag, which determine the behaviour of overlapping glyphs
+ /// within a text object in the transparent imaging model,
+ /// TK
+ /// key.
+ ///
+ ///
+ ///
+ ///
+ /// if enabled.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState SetTextKnockoutFlag(bool textKnockoutFlag) {
return Put(PdfName.TK, new PdfBoolean(textKnockoutFlag));
}
+ /// Puts the value into Graphics state parameter dictionary and associates it with the specified key.
+ ///
+ ///
+ /// Puts the value into Graphics state parameter dictionary and associates it with the specified key.
+ /// If the key is already present, it will override the old value with the specified one.
+ ///
+ /// key to insert or to override
+ /// the value to associate with the specified key
+ /// object itself.
public virtual iText.Kernel.Pdf.Extgstate.PdfExtGState Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/filters/FilterHandlers.cs b/itext/itext.kernel/itext/kernel/pdf/filters/FilterHandlers.cs
index 40bd940e0c..78baed5b64 100644
--- a/itext/itext.kernel/itext/kernel/pdf/filters/FilterHandlers.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/filters/FilterHandlers.cs
@@ -66,7 +66,7 @@ static FilterHandlers() {
// it may also be better to split the sub-classes out into a separate package
IDictionary map = new Dictionary();
map[PdfName.FlateDecode] = new FlateDecodeFilter();
- map[PdfName.FL] = new FlateDecodeFilter();
+ map[PdfName.Fl] = new FlateDecodeFilter();
map[PdfName.ASCIIHexDecode] = new ASCIIHexDecodeFilter();
map[PdfName.AHx] = new ASCIIHexDecodeFilter();
map[PdfName.ASCII85Decode] = new ASCII85DecodeFilter();
diff --git a/itext/itext.kernel/itext/kernel/pdf/function/PdfFunction.cs b/itext/itext.kernel/itext/kernel/pdf/function/PdfFunction.cs
index 006902a218..f7a644f069 100644
--- a/itext/itext.kernel/itext/kernel/pdf/function/PdfFunction.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/function/PdfFunction.cs
@@ -68,6 +68,21 @@ public virtual int GetOutputSize() {
return range == null ? 0 : range.Size() / 2;
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
+ public override void Flush() {
+ base.Flush();
+ }
+
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayer.cs b/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayer.cs
index ccea712620..da581a8586 100644
--- a/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayer.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayer.cs
@@ -78,7 +78,6 @@ public class PdfLayer : PdfObjectWrapper, IPdfOCG {
/// Creates a new layer by existing dictionary, which must be an indirect object.
/// the layer dictionary, must have an indirect reference.
- ///
public PdfLayer(PdfDictionary layerDictionary)
: base(layerDictionary) {
EnsureObjectIsAddedToDocument(layerDictionary);
@@ -87,7 +86,6 @@ public PdfLayer(PdfDictionary layerDictionary)
/// Creates a new layer by its name and document.
/// the layer name
/// the PdfDocument which the layer belongs to
- ///
public PdfLayer(String name, PdfDocument document)
: this(document) {
SetName(name);
@@ -224,7 +222,6 @@ public virtual void SetOnPanel(bool onPanel) {
/// resultant colletion if no intents are currently specified.
///
/// the collection of intents.
- ///
public virtual ICollection GetIntents() {
PdfObject intent = GetPdfObject().Get(PdfName.Intent);
if (intent is PdfName) {
@@ -433,7 +430,6 @@ public virtual void SetPageElement(String pe) {
/// making it indirect first if necessary.
///
/// the indirect reference to the object representing the layer
- ///
public virtual PdfIndirectReference GetIndirectReference() {
GetPdfObject().MakeIndirect(GetDocument());
return GetPdfObject().GetIndirectReference();
@@ -467,7 +463,6 @@ protected internal virtual PdfDocument GetDocument() {
/// the title of the layer
/// the document this title layer belongs to
/// the created layer
- ///
protected internal static iText.Kernel.Pdf.Layer.PdfLayer CreateTitleSilent(String title, PdfDocument document
) {
if (title == null) {
@@ -480,7 +475,6 @@ protected internal static iText.Kernel.Pdf.Layer.PdfLayer CreateTitleSilent(Stri
/// Gets the /Usage dictionary, creating a new one if necessary.
/// the /Usage dictionary
- ///
protected internal virtual PdfDictionary GetUsage() {
PdfDictionary usage = GetPdfObject().GetAsDictionary(PdfName.Usage);
if (usage == null) {
diff --git a/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayerMembership.cs b/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayerMembership.cs
index 43c0b310aa..cd92966ae1 100644
--- a/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayerMembership.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/layer/PdfLayerMembership.cs
@@ -65,7 +65,6 @@ namespace iText.Kernel.Pdf.Layer {
///
public class PdfLayerMembership : PdfObjectWrapper, IPdfOCG {
/// Creates a new, empty membership layer.
- ///
public PdfLayerMembership(PdfDocument doc)
: base(new PdfDictionary()) {
MakeIndirect(doc);
@@ -75,7 +74,6 @@ public PdfLayerMembership(PdfDocument doc)
/// Creates a new PdfLayerMembership instance by its PdfDictionary, which must be an indirect object.
///
/// the membership dictionary, must have an indirect reference.
- ///
public PdfLayerMembership(PdfDictionary membershipDictionary)
: base(membershipDictionary) {
EnsureObjectIsAddedToDocument(membershipDictionary);
@@ -85,7 +83,6 @@ public PdfLayerMembership(PdfDictionary membershipDictionary)
}
/// Gets the collection of the layers this layer membership operates with.
- ///
public virtual ICollection GetLayers() {
PdfObject layers = GetPdfObject().Get(PdfName.OCGs);
if (layers is PdfDictionary) {
@@ -108,7 +105,6 @@ public virtual ICollection GetLayers() {
/// Adds a new layer to the current layer membership.
/// the layer to be added
- ///
public virtual void AddLayer(PdfLayer layer) {
PdfArray layers = GetPdfObject().GetAsArray(PdfName.OCGs);
if (layers == null) {
@@ -146,7 +142,6 @@ public virtual void SetVisibilityPolicy(PdfName visibilityPolicy) {
/// Gets the visibility policy for content belonging to this
/// optional content membership dictionary.
///
- ///
public virtual PdfName GetVisibilityPolicy() {
PdfName visibilityPolicy = GetPdfObject().GetAsName(PdfName.P);
if (visibilityPolicy == null || !visibilityPolicy.Equals(PdfName.AllOn) && !visibilityPolicy.Equals(PdfName
@@ -174,7 +169,6 @@ public virtual void SetVisibilityExpression(PdfVisibilityExpression visibilityEx
/// Gets the visibility expression for content belonging to this
/// optional content membership dictionary.
///
- ///
public virtual PdfVisibilityExpression GetVisibilityExpression() {
PdfArray ve = GetPdfObject().GetAsArray(PdfName.VE);
return ve != null ? new PdfVisibilityExpression(ve) : null;
diff --git a/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs b/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs
index ab30f8e33a..ebc2cad1ac 100644
--- a/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/layer/PdfOCProperties.cs
@@ -66,7 +66,6 @@ public class PdfOCProperties : PdfObjectWrapper {
/// Creates a new PdfOCProperties instance.
/// the document the optional content belongs to
- ///
public PdfOCProperties(PdfDocument document)
: this(((PdfDictionary)new PdfDictionary().MakeIndirect(document))) {
}
@@ -77,7 +76,6 @@ public PdfOCProperties(PdfDocument document)
///
/// the dictionary of optional content properties, must have an indirect reference.
///
- ///
public PdfOCProperties(PdfDictionary ocPropertiesDict)
: base(ocPropertiesDict) {
EnsureObjectIsAddedToDocument(ocPropertiesDict);
@@ -254,7 +252,6 @@ private static void GetOCGOrder(PdfArray order, PdfLayer layer) {
}
/// Populates the /AS entry in the /D dictionary.
- ///
private void AddASEvent(PdfName @event, PdfName category) {
PdfArray arr = new PdfArray();
foreach (PdfLayer layer in layers) {
@@ -284,7 +281,6 @@ private void AddASEvent(PdfName @event, PdfName category) {
}
/// Reads the layers from the document to be able to modify them in the future.
- ///
private void ReadLayersFromDictionary() {
PdfArray ocgs = GetPdfObject().GetAsArray(PdfName.OCGs);
if (ocgs == null || ocgs.IsEmpty()) {
@@ -303,13 +299,15 @@ private void ReadLayersFromDictionary() {
if (d != null && !d.IsEmpty()) {
PdfArray off = d.GetAsArray(PdfName.OFF);
if (off != null) {
- foreach (PdfObject offLayer in off) {
+ for (int i = 0; i < off.Size(); i++) {
+ PdfObject offLayer = off.Get(i, false);
layerMap.Get((PdfIndirectReference)offLayer).on = false;
}
}
PdfArray locked = d.GetAsArray(PdfName.Locked);
if (locked != null) {
- foreach (PdfObject lockedLayer in locked) {
+ for (int i = 0; i < locked.Size(); i++) {
+ PdfObject lockedLayer = locked.Get(i, false);
layerMap.Get((PdfIndirectReference)lockedLayer).locked = true;
}
}
@@ -327,7 +325,6 @@ private void ReadLayersFromDictionary() {
}
/// Reads the /Order in the /D entry and initialized the parent-child hierarchy.
- ///
private void ReadOrderFromDictionary(PdfLayer parent, PdfArray orderArray, IDictionary layerMap) {
for (int i = 0; i < orderArray.Size(); i++) {
diff --git a/itext/itext.kernel/itext/kernel/pdf/layer/PdfVisibilityExpression.cs b/itext/itext.kernel/itext/kernel/pdf/layer/PdfVisibilityExpression.cs
index ccfc7cb6db..b35e880220 100644
--- a/itext/itext.kernel/itext/kernel/pdf/layer/PdfVisibilityExpression.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/layer/PdfVisibilityExpression.cs
@@ -52,7 +52,6 @@ namespace iText.Kernel.Pdf.Layer {
public class PdfVisibilityExpression : PdfObjectWrapper {
/// Constructs a new PdfVisibilityExpression instance by its raw PdfArray.
/// the array representing the visibility expression
- ///
public PdfVisibilityExpression(PdfArray visibilityExpressionArray)
: base(visibilityExpressionArray) {
PdfName @operator = visibilityExpressionArray.GetAsName(0);
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagging/ParentTreeHandler.cs b/itext/itext.kernel/itext/kernel/pdf/tagging/ParentTreeHandler.cs
index 5b35d52a4b..7f96b30c96 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagging/ParentTreeHandler.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagging/ParentTreeHandler.cs
@@ -42,6 +42,8 @@ source product.
address: sales@itextpdf.com
*/
using System.Collections.Generic;
+using iText.IO;
+using iText.IO.Log;
using iText.Kernel;
using iText.Kernel.Pdf;
@@ -138,10 +140,16 @@ public virtual PdfDictionary BuildParentTree() {
}
public virtual void RegisterMcr(PdfMcr mcr) {
- SortedDictionary pageMcrs = pageToPageMcrs.Get(mcr.GetPageObject().GetIndirectReference());
+ PdfDictionary mcrPageObject = mcr.GetPageObject();
+ if (mcrPageObject == null || (!(mcr is PdfObjRef) && mcr.GetMcid() < 0)) {
+ ILogger logger = LoggerFactory.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
+ logger.Error(LogMessageConstant.ENCOUNTERED_INVALID_MCR);
+ return;
+ }
+ SortedDictionary pageMcrs = pageToPageMcrs.Get(mcrPageObject.GetIndirectReference());
if (pageMcrs == null) {
pageMcrs = new SortedDictionary();
- pageToPageMcrs[mcr.GetPageObject().GetIndirectReference()] = pageMcrs;
+ pageToPageMcrs[mcrPageObject.GetIndirectReference()] = pageMcrs;
}
if (mcr is PdfObjRef) {
PdfDictionary obj = ((PdfDictionary)mcr.GetPdfObject()).GetAsDictionary(PdfName.Obj);
@@ -164,6 +172,10 @@ public virtual void RegisterMcr(PdfMcr mcr) {
public virtual void UnregisterMcr(PdfMcr mcrToUnregister) {
PdfDictionary pageDict = mcrToUnregister.GetPageObject();
+ if (pageDict == null) {
+ // invalid mcr, ignore
+ return;
+ }
if (pageDict.IsFlushed()) {
throw new PdfException(PdfException.CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed);
}
@@ -259,6 +271,7 @@ private void UpdateStructParentTreeEntries(int? pageStructParentIndex, IDictiona
if (parentsOfPageMcrs.Size() > 0) {
parentsOfPageMcrs.MakeIndirect(structTreeRoot.GetDocument());
parentTree.AddEntry(pageStructParentIndex, parentsOfPageMcrs);
+ structTreeRoot.GetDocument().CheckIsoConformance(parentsOfPageMcrs, IsoKey.TAG_STRUCTURE_ELEMENT);
parentsOfPageMcrs.Flush();
}
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfMcrDictionary.cs b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfMcrDictionary.cs
index 4e2ac794af..157c1f9636 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfMcrDictionary.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfMcrDictionary.cs
@@ -58,7 +58,8 @@ public PdfMcrDictionary(PdfPage page, PdfStructElem parent)
}
public override int GetMcid() {
- return ((PdfDictionary)GetPdfObject()).GetAsNumber(PdfName.MCID).IntValue();
+ PdfNumber mcidNumber = ((PdfDictionary)GetPdfObject()).GetAsNumber(PdfName.MCID);
+ return mcidNumber != null ? mcidNumber.IntValue() : -1;
}
public override PdfDictionary GetPageObject() {
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructElem.cs b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructElem.cs
index f8c19667e8..ac51ac4e1d 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructElem.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructElem.cs
@@ -144,7 +144,7 @@ public PdfStructElem(PdfDocument document, PdfName role, PdfPage page)
public PdfStructElem(PdfDocument document, PdfName role, PdfAnnotation annot)
: this(document, role) {
if (annot.GetPage() == null) {
- throw new PdfException(PdfException.AnnotShallHaveReferenceToPage);
+ throw new PdfException(PdfException.AnnotationShallHaveReferenceToPage);
}
GetPdfObject().Put(PdfName.Pg, annot.GetPage().GetPdfObject());
}
@@ -172,7 +172,6 @@ public static bool IsStructElem(PdfDictionary dictionary) {
/// The attributes dictionary will be stored inside element.
///
/// attributes dictionary.
- ///
public virtual PdfObject GetAttributes(bool createNewIfNull) {
PdfObject attributes = GetPdfObject().Get(PdfName.A);
if (attributes == null && createNewIfNull) {
@@ -369,7 +368,7 @@ public virtual iText.Kernel.Pdf.Tagging.PdfStructElem Put(PdfName key, PdfObject
}
public override void Flush() {
- //TODO log that to prevent undefined behaviour, use StructTreeRoot#flushStructElem method
+ GetDocument().CheckIsoConformance(GetPdfObject(), IsoKey.TAG_STRUCTURE_ELEMENT);
base.Flush();
}
@@ -431,9 +430,6 @@ private void AddKidObjectToStructElemList(PdfObject k, IList lis
}
private IPdfStructElem ConvertPdfObjectToIPdfStructElem(PdfObject obj) {
- if (obj.IsIndirectReference()) {
- obj = ((PdfIndirectReference)obj).GetRefersTo();
- }
IPdfStructElem elem = null;
switch (obj.GetObjectType()) {
case PdfObject.DICTIONARY: {
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructTreeRoot.cs b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructTreeRoot.cs
index 46824c491d..8875b2f240 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructTreeRoot.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagging/PdfStructTreeRoot.cs
@@ -195,7 +195,6 @@ public override void Flush() {
///
/// document to copy structure to. Shall not be current document.
/// association between original page and copied page.
- ///
public virtual void CopyTo(PdfDocument destDocument, IDictionary page2page) {
StructureTreeCopier.CopyTo(destDocument, page2page, GetDocument());
}
@@ -213,7 +212,6 @@ public virtual void CopyTo(PdfDocument destDocument, IDictionarydocument to copy structure to.
/// indicates where the structure to be inserted.
/// association between original page and copied page.
- ///
public virtual void CopyTo(PdfDocument destDocument, int insertBeforePage, IDictionary page2page
) {
StructureTreeCopier.CopyTo(destDocument, insertBeforePage, page2page, GetDocument());
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagging/StructureTreeCopier.cs b/itext/itext.kernel/itext/kernel/pdf/tagging/StructureTreeCopier.cs
index e4f2334e24..f7ba4a3a72 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagging/StructureTreeCopier.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagging/StructureTreeCopier.cs
@@ -73,7 +73,6 @@ static StructureTreeCopier() {
///
/// document to copy structure to. Shall not be current document.
/// association between original page and copied page.
- ///
public static void CopyTo(PdfDocument destDocument, IDictionary page2page, PdfDocument callingDocument
) {
if (!destDocument.IsTagged()) {
@@ -98,7 +97,6 @@ public static void CopyTo(PdfDocument destDocument, IDictionarydocument to copy structure to.
/// indicates where the structure to be inserted.
/// association between original page and copied page.
- ///
public static void CopyTo(PdfDocument destDocument, int insertBeforePage, IDictionary page2page
, PdfDocument callingDocument) {
if (!destDocument.IsTagged()) {
@@ -161,7 +159,6 @@ public static void CopyTo(PdfDocument destDocument, int insertBeforePage, IDicti
///
/// .
///
- ///
private static void CopyTo(PdfDocument destDocument, IDictionary page2page, PdfDocument
callingDocument, bool copyFromDestDocument) {
CopyTo(destDocument, page2page, callingDocument, copyFromDestDocument, -1);
@@ -273,7 +270,7 @@ private static PdfObject CopyObjectKid(PdfObject kid, PdfDictionary copiedParent
return kid;
}
else {
- // TODO do we always copy numbers?
+ // TODO do we always copy numbers? don't we need to check if it is supposed to be copied like objs in objectsToCopy?
if (kid.IsDictionary()) {
PdfDictionary kidAsDict = (PdfDictionary)kid;
if (objectsToCopy.Contains(kidAsDict)) {
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagutils/TagStructureContext.cs b/itext/itext.kernel/itext/kernel/pdf/tagutils/TagStructureContext.cs
index a5de70cce7..55c993b93c 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagutils/TagStructureContext.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagutils/TagStructureContext.cs
@@ -522,7 +522,7 @@ private void FlushParentIfBelongsToPage(PdfStructElem parent, PdfPage currentPag
else {
if (kid is PdfStructElem) {
// If kid is structElem and was already flushed then in kids list there will be null for it instead of
- // PdfStructElem. And therefore if we get into this if clause it means that some StructElem wasn't flushed.
+ // PdfStructElem. And therefore if we get into this if-clause it means that some StructElem wasn't flushed.
allKidsBelongToPage = false;
break;
}
diff --git a/itext/itext.kernel/itext/kernel/pdf/tagutils/TagTreePointer.cs b/itext/itext.kernel/itext/kernel/pdf/tagutils/TagTreePointer.cs
index 675ca936d6..0b03ee8d11 100644
--- a/itext/itext.kernel/itext/kernel/pdf/tagutils/TagTreePointer.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/tagutils/TagTreePointer.cs
@@ -55,6 +55,7 @@ namespace iText.Kernel.Pdf.Tagutils {
/// it's role and properties, etc. Also, using instance of this class, you can change tag position in the tag structure,
/// you can flush current tag or remove it.
///
+ ///
/// There could be any number of the instances of this class, simultaneously pointing to different (or the same) parts of
/// the tag structure. Because of this, you can for example remove the tag at which another instance is currently pointing.
/// In this case, this another instance becomes invalid, and invocation of any method on it will result in exception. To make
@@ -137,7 +138,7 @@ public TagTreePointer(iText.Kernel.Pdf.Tagutils.TagTreePointer tagPointer) {
///
public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer SetPageForTagging(PdfPage page) {
if (page.IsFlushed()) {
- throw new PdfException(PdfException.PageWasAlreadyFlushed);
+ throw new PdfException(PdfException.PageAlreadyFlushed);
}
this.currentPage = page;
return this;
@@ -337,6 +338,7 @@ public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer AddTag(int index, IAcces
/// TagTreePointer
/// instance would move to connected kid instead of creating tag twice.
/// But if it is added to some other parent, then connection will be removed.
+ ///
///
/// This call is equivalent of calling sequentially
///
@@ -707,6 +709,7 @@ public virtual iText.Kernel.Pdf.Tagutils.TagTreePointer MoveToKid(int n, PdfName
/// Moves this
/// TagTreePointer
/// instance to a tag, which is connected with the given accessible element.
+ ///
///
/// The connection between the tag and the accessible element instance is used as a sign that tag is not yet finished
/// and therefore should not be flushed or removed if page tags are flushed or removed. Also, any
@@ -764,6 +767,7 @@ public virtual IList GetKidsRoles() {
/// This method call moves this
/// TagTreePointer
/// to the current tag parent.
+ ///
///
/// If some of the tags to be flushed are still connected to the accessible elements, then these tags are considered
/// as not yet finished ones, and they won't be flushed immediately, but they will be flushed, when the connection
diff --git a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs
index d85d3cabef..312da52930 100644
--- a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs
@@ -47,9 +47,13 @@ source product.
using iText.Kernel.Pdf.Canvas.Wmf;
namespace iText.Kernel.Pdf.Xobject {
+ /// A wrapper for Form XObject.
+ /// A wrapper for Form XObject. ISO 32000-1, 8.10 FormXObjects.
public class PdfFormXObject : PdfXObject {
private PdfResources resources = null;
+ /// Creates a new instance of Form XObject.
+ /// the form XObject’s bounding box.
public PdfFormXObject(Rectangle bBox)
: base(new PdfStream()) {
GetPdfObject().Put(PdfName.Type, PdfName.XObject);
@@ -59,8 +63,22 @@ public PdfFormXObject(Rectangle bBox)
}
}
- public PdfFormXObject(PdfStream pdfObject)
- : base(pdfObject) {
+ ///
+ /// Create
+ ///
+ /// instance by
+ ///
+ /// .
+ /// Note, this constructor doesn't perform any additional checks
+ ///
+ ///
+ ///
+ ///
+ /// with Form XObject.
+ ///
+ ///
+ public PdfFormXObject(PdfStream pdfStream)
+ : base(pdfStream) {
}
/// Creates form XObject from page content.
@@ -68,7 +86,10 @@ public PdfFormXObject(PdfStream pdfObject)
/// Creates form XObject from page content.
/// The page shall be from the document, to which FormXObject will be added.
///
- ///
+ ///
+ /// an instance of
+ ///
+ ///
public PdfFormXObject(PdfPage page)
: this(page.GetCropBox()) {
GetPdfObject().GetOutputStream().WriteBytes(page.GetContentBytes());
@@ -94,6 +115,17 @@ public PdfFormXObject(WmfImageData image, PdfDocument pdfDocument)
: this(new WmfImageHelper(image).CreatePdfForm(pdfDocument).GetPdfObject()) {
}
+ ///
+ /// Gets
+ ///
+ /// of the Form XObject.
+ /// Note, if there is no resources, a new instance will be created.
+ ///
+ ///
+ /// not null instance of
+ ///
+ /// .
+ ///
public virtual PdfResources GetResources() {
if (this.resources == null) {
PdfDictionary resourcesDict = GetPdfObject().GetAsDictionary(PdfName.Resources);
@@ -106,6 +138,83 @@ public virtual PdfResources GetResources() {
return resources;
}
+ ///
+ /// Gets Form XObject's BBox,
+ ///
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , that represents
+ ///
+ /// .
+ ///
+ public virtual PdfArray GetBBox() {
+ return GetPdfObject().GetAsArray(PdfName.BBox);
+ }
+
+ ///
+ /// Sets Form XObject's BBox,
+ ///
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// , that represents
+ ///
+ /// .
+ ///
+ /// object itself.
+ public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetBBox(PdfArray bBox) {
+ return Put(PdfName.BBox, bBox);
+ }
+
+ ///
+ /// Sets a group attributes dictionary indicating that the contents of the form XObject
+ /// shall be treated as a group and specifying the attributes of that group.
+ ///
+ ///
+ /// Sets a group attributes dictionary indicating that the contents of the form XObject
+ /// shall be treated as a group and specifying the attributes of that group.
+ ///
+ /// key.
+ ///
+ ///
+ /// instance of
+ ///
+ /// .
+ ///
+ /// object itself.
+ ///
+ public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetGroup(PdfTransparencyGroup transparency) {
+ return Put(PdfName.Group, transparency.GetPdfObject());
+ }
+
+ /// Gets width based on XObject's BBox.
+ /// float value.
+ public override float GetWidth() {
+ return GetBBox() == null ? 0 : GetBBox().GetAsNumber(2).FloatValue();
+ }
+
+ /// Gets height based on XObject's BBox.
+ /// float value.
+ public override float GetHeight() {
+ return GetBBox() == null ? 0 : GetBBox().GetAsNumber(3).FloatValue();
+ }
+
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note that not every wrapper require this, only those that have such warning in documentation.
+ ///
public override void Flush() {
resources = null;
if (GetPdfObject().Get(PdfName.BBox) == null) {
@@ -114,68 +223,182 @@ public override void Flush() {
base.Flush();
}
- //Additional entries in form dictionary for Trap Network annotation
+ //-----Additional entries in form dictionary for Trap Network annotation
+ ///
+ /// Sets process color model for trap network appearance,
+ ///
+ /// key.
+ ///
+ ///
+ /// shall be one of the valid values:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// , and
+ ///
+ /// .
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetProcessColorModel(PdfName model) {
return Put(PdfName.PCM, model);
}
+ ///
+ /// Gets process color model of trap network appearance,
+ ///
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// instance, possible values:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// , and
+ ///
+ /// .
+ ///
public virtual PdfName GetProcessColorModel() {
return GetPdfObject().GetAsName(PdfName.PCM);
}
+ ///
+ /// Sets separation color names for the trap network appearance,
+ ///
+ /// key.
+ ///
+ ///
+ /// an array of names identifying the colorants that were assumed
+ /// when the trap network appearance was created.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetSeparationColorNames(PdfArray colorNames) {
return Put(PdfName.SeparationColorNames, colorNames);
}
+ ///
+ /// Gets separation color names of trap network appearance,
+ ///
+ /// key.
+ ///
+ ///
+ /// an
+ ///
+ /// of names identifying the colorants.
+ ///
public virtual PdfArray GetSeparationColorNames() {
return GetPdfObject().GetAsArray(PdfName.SeparationColorNames);
}
+ ///
+ /// Sets an array of TrapRegion objects defining the page’s trapping zones
+ /// and the associated trapping parameters, as described in Adobe Technical Note #5620,
+ /// Portable Job Ticket Format.
+ ///
+ ///
+ /// Sets an array of TrapRegion objects defining the page’s trapping zones
+ /// and the associated trapping parameters, as described in Adobe Technical Note #5620,
+ /// Portable Job Ticket Format.
+ ///
+ /// key.
+ ///
+ ///
+ /// A
+ ///
+ /// of indirect references to TrapRegion objects.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetTrapRegions(PdfArray regions) {
return Put(PdfName.TrapRegions, regions);
}
+ ///
+ /// Gets an array of TrapRegion objects defining the page’s trapping zones
+ /// and the associated trapping parameters, as described in Adobe Technical Note #5620,
+ /// Portable Job Ticket Format.
+ ///
+ ///
+ /// Gets an array of TrapRegion objects defining the page’s trapping zones
+ /// and the associated trapping parameters, as described in Adobe Technical Note #5620,
+ /// Portable Job Ticket Format.
+ ///
+ /// key.
+ ///
+ ///
+ /// A
+ ///
+ /// of indirect references to TrapRegion objects.
+ ///
public virtual PdfArray GetTrapRegions() {
return GetPdfObject().GetAsArray(PdfName.TrapRegions);
}
+ /// Sets a human-readable text string that described this trap network to the user.
+ ///
+ /// Sets a human-readable text string that described this trap network to the user.
+ ///
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// value.
+ ///
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetTrapStyles(PdfString trapStyles) {
return Put(PdfName.TrapStyles, trapStyles);
}
+ /// Gets a human-readable text string that described this trap network to the user.
+ ///
+ /// Gets a human-readable text string that described this trap network to the user.
+ ///
+ /// key.
+ ///
+ ///
+ /// a
+ ///
+ /// value.
+ ///
public virtual PdfString GetTrapStyles() {
return GetPdfObject().GetAsString(PdfName.TrapStyles);
}
- //Additional entries in form dictionary for Printer Mark annotation
+ //-----Additional entries in form dictionary for Printer Mark annotation
+ /// Sets a text string representing the printer’s mark in human-readable form.
+ /// a string value.
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetMarkStyle(PdfString markStyle) {
return Put(PdfName.MarkStyle, markStyle);
}
+ /// Gets a text string representing the printer’s mark in human-readable form.
+ /// a string value.
public virtual PdfString GetMarkStyle() {
return GetPdfObject().GetAsString(PdfName.MarkStyle);
}
- public virtual PdfArray GetBBox() {
- return GetPdfObject().GetAsArray(PdfName.BBox);
- }
-
- public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetBBox(PdfArray bBox) {
- return Put(PdfName.BBox, bBox);
- }
-
- public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject SetGroup(PdfTransparencyGroup transparency) {
- return Put(PdfName.Group, transparency.GetPdfObject());
- }
-
- public override float GetWidth() {
- return GetBBox() == null ? 0 : GetBBox().GetAsNumber(2).FloatValue();
- }
-
- public override float GetHeight() {
- return GetBBox() == null ? 0 : GetBBox().GetAsNumber(3).FloatValue();
- }
-
+ /// Puts the value into Image XObject dictionary and associates it with the specified key.
+ ///
+ /// Puts the value into Image XObject dictionary and associates it with the specified key.
+ /// If the key is already present, it will override the old value with the specified one.
+ ///
+ /// key to insert or to override
+ /// the value to associate with the specified key
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
diff --git a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfImageXObject.cs b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfImageXObject.cs
index 9b7227cc0b..8615e492bd 100644
--- a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfImageXObject.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfImageXObject.cs
@@ -52,6 +52,8 @@ source product.
using iText.Kernel.Pdf.Filters;
namespace iText.Kernel.Pdf.Xobject {
+ /// A wrapper for Image XObject.
+ /// A wrapper for Image XObject. ISO 32000-1, 8.9 Images.
public class PdfImageXObject : PdfXObject {
private float width;
@@ -73,20 +75,57 @@ public class PdfImageXObject : PdfXObject {
private int stride;
+ /// Creates Image XObject by image.
+ ///
+ ///
+ ///
+ /// with actual image data.
+ ///
public PdfImageXObject(ImageData image)
: this(image, null) {
}
+ /// Creates Image XObject by image.
+ ///
+ ///
+ ///
+ /// with actual image data.
+ ///
+ ///
+ ///
+ ///
+ /// with image mask.
+ ///
public PdfImageXObject(ImageData image, iText.Kernel.Pdf.Xobject.PdfImageXObject imageMask)
: this(CreatePdfStream(CheckImageType(image), imageMask)) {
mask = image.IsMask();
softMask = image.IsSoftMask();
}
- public PdfImageXObject(PdfStream pdfObject)
- : base(pdfObject) {
+ ///
+ /// Create
+ ///
+ /// instance by
+ ///
+ /// .
+ /// Note, this constructor doesn't perform any additional checks
+ ///
+ ///
+ ///
+ ///
+ /// with Image XObject.
+ ///
+ ///
+ public PdfImageXObject(PdfStream pdfStream)
+ : base(pdfStream) {
}
+ ///
+ /// Gets width of image,
+ /// Width
+ /// key.
+ ///
+ /// float value.
public override float GetWidth() {
if (!IsFlushed()) {
return GetPdfObject().GetAsNumber(PdfName.Width).FloatValue();
@@ -96,6 +135,12 @@ public override float GetWidth() {
}
}
+ ///
+ /// Gets height of image,
+ /// Height
+ /// key.
+ ///
+ /// float value.
public override float GetHeight() {
if (!IsFlushed()) {
return GetPdfObject().GetAsNumber(PdfName.Height).FloatValue();
@@ -105,6 +150,17 @@ public override float GetHeight() {
}
}
+ ///
+ /// To manually flush a
+ /// PdfObject
+ /// behind this wrapper, you have to ensure
+ /// that this object is added to the document, i.e. it has an indirect reference.
+ /// Basically this means that before flushing you need to explicitly call
+ ///
+ /// .
+ /// For example: wrapperInstance.makeIndirect(document).flush();
+ /// Note, that not every wrapper require this, only those that have such warning in documentation.
+ ///
public override void Flush() {
if (!IsFlushed()) {
width = GetPdfObject().GetAsNumber(PdfName.Width).FloatValue();
@@ -113,6 +169,13 @@ public override void Flush() {
}
}
+ /// Copy Image XObject to the specified document.
+ /// target document
+ ///
+ /// just created instance of
+ ///
+ /// .
+ ///
public virtual iText.Kernel.Pdf.Xobject.PdfImageXObject CopyTo(PdfDocument document) {
iText.Kernel.Pdf.Xobject.PdfImageXObject image = new iText.Kernel.Pdf.Xobject.PdfImageXObject(((PdfStream)
GetPdfObject().CopyTo(document)));
@@ -123,10 +186,29 @@ public virtual iText.Kernel.Pdf.Xobject.PdfImageXObject CopyTo(PdfDocument docum
return image;
}
+ /// Gets decoded image bytes.
+ /// byte array.
public virtual byte[] GetImageBytes() {
return GetImageBytes(true);
}
+ /// Gets image bytes.
+ ///
+ /// Gets image bytes.
+ /// Note,
+ ///
+ /// ,
+ ///
+ /// and
+ ///
+ /// filters will be ignored.
+ ///
+ ///
+ /// if
+ ///
+ /// , decodes stream bytes.
+ ///
+ /// byte array.
public virtual byte[] GetImageBytes(bool decoded) {
byte[] bytes;
bytes = GetPdfObject().GetBytes(false);
@@ -150,11 +232,126 @@ public virtual byte[] GetImageBytes(bool decoded) {
return bytes;
}
+ ///
+ /// Identifies the type of the image that is stored in the bytes of this
+ ///
+ /// .
+ /// Note that this has nothing to do with the original type of the image. For instance, the return value
+ /// of this method will never be
+ ///
+ /// as we loose this information when converting a
+ /// PNG image into something that can be put into a PDF file.
+ /// The possible values are:
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ /// ,
+ ///
+ ///
+ /// the identified type of image
+ public virtual ImageType IdentifyImageType() {
+ PdfObject filter = GetPdfObject().Get(PdfName.Filter);
+ PdfArray filters = new PdfArray();
+ if (filter != null) {
+ if (filter.GetObjectType() == PdfObject.NAME) {
+ filters.Add(filter);
+ }
+ else {
+ if (filter.GetObjectType() == PdfObject.ARRAY) {
+ filters = ((PdfArray)filter);
+ }
+ }
+ }
+ for (int i = filters.Size() - 1; i >= 0; i--) {
+ PdfName filterName = (PdfName)filters.Get(i);
+ if (PdfName.DCTDecode.Equals(filterName)) {
+ return ImageType.JPEG;
+ }
+ else {
+ if (PdfName.JBIG2Decode.Equals(filterName)) {
+ return ImageType.JBIG2;
+ }
+ else {
+ if (PdfName.JPXDecode.Equals(filterName)) {
+ return ImageType.JPEG2000;
+ }
+ }
+ }
+ }
+ // None of the previous types match
+ PdfObject colorspace = GetPdfObject().Get(PdfName.ColorSpace);
+ PrepareAndFindColorspace(colorspace);
+ if (pngColorType < 0) {
+ return ImageType.TIFF;
+ }
+ else {
+ return ImageType.PNG;
+ }
+ }
+
+ ///
+ /// Identifies recommended file extension to store the bytes of this
+ ///
+ /// .
+ /// Possible values are: 'png', 'jpg', 'jp2', 'tif', 'jbig2'.
+ /// This extension can later be used together with the result of
+ ///
+ /// .
+ ///
+ ///
+ /// a
+ ///
+ /// with recommended file extension
+ ///
+ ///
+ public virtual String IdentifyImageFileExtension() {
+ ImageType bytesType = IdentifyImageType();
+ switch (bytesType) {
+ case ImageType.PNG: {
+ return "png";
+ }
+
+ case ImageType.JPEG: {
+ return "jpg";
+ }
+
+ case ImageType.JPEG2000: {
+ return "jp2";
+ }
+
+ case ImageType.TIFF: {
+ return "tif";
+ }
+
+ case ImageType.JBIG2: {
+ return "jbig2";
+ }
+
+ default: {
+ throw new InvalidOperationException("Should have never happened. This type of image is not allowed for ImageXObject"
+ );
+ }
+ }
+ }
+
+ /// Puts the value into Image XObject dictionary and associates it with the specified key.
+ ///
+ /// Puts the value into Image XObject dictionary and associates it with the specified key.
+ /// If the key is already present, it will override the old value with the specified one.
+ ///
+ /// key to insert or to override
+ /// the value to associate with the specified key
+ /// object itself.
public virtual iText.Kernel.Pdf.Xobject.PdfImageXObject Put(PdfName key, PdfObject value) {
GetPdfObject().Put(key, value);
return this;
}
+ [Obsolete]
protected internal static PdfStream CreatePdfStream(ImageData image, iText.Kernel.Pdf.Xobject.PdfImageXObject
imageMask) {
PdfStream stream;
@@ -336,8 +533,13 @@ private static PdfArray CreateArray(PdfStream stream, Object[] objects) {
array.Add(new PdfNumber((float)obj));
}
else {
- //TODO instance of was removed due to autoport
- array.Add(CreateDictionaryFromMap(stream, (IDictionary)obj));
+ if (obj is Object[]) {
+ array.Add(CreateArray(stream, (Object[])obj));
+ }
+ else {
+ //TODO instance of was removed due to autoport
+ array.Add(CreateDictionaryFromMap(stream, (IDictionary)obj));
+ }
}
}
}
@@ -345,19 +547,22 @@ private static PdfArray CreateArray(PdfStream stream, Object[] objects) {
return array;
}
- ///
- private byte[] DecodeTiffAndPngBytes(byte[] imageBytes) {
+ private void PrepareAndFindColorspace(PdfObject colorspace) {
pngColorType = -1;
- PdfArray decode = GetPdfObject().GetAsArray(PdfName.Decode);
width = GetPdfObject().GetAsNumber(PdfName.Width).IntValue();
height = GetPdfObject().GetAsNumber(PdfName.Height).IntValue();
bpc = GetPdfObject().GetAsNumber(PdfName.BitsPerComponent).IntValue();
pngBitDepth = bpc;
- PdfObject colorspace = GetPdfObject().Get(PdfName.ColorSpace);
palette = null;
icc = null;
stride = 0;
FindColorspace(colorspace, true);
+ }
+
+ ///
+ private byte[] DecodeTiffAndPngBytes(byte[] imageBytes) {
+ PdfObject colorspace = GetPdfObject().Get(PdfName.ColorSpace);
+ PrepareAndFindColorspace(colorspace);
MemoryStream ms = new MemoryStream();
if (pngColorType < 0) {
if (bpc != 8) {
@@ -413,6 +618,7 @@ private byte[] DecodeTiffAndPngBytes(byte[] imageBytes) {
}
else {
PngWriter png = new PngWriter(ms);
+ PdfArray decode = GetPdfObject().GetAsArray(PdfName.Decode);
if (decode != null) {
if (pngBitDepth == 1) {
// if the decode array is 1,0, then we need to invert the image
diff --git a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfXObject.cs b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfXObject.cs
index 1bb90160fc..5a7b4c5df0 100644
--- a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfXObject.cs
+++ b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfXObject.cs
@@ -42,42 +42,84 @@ source product.
address: sales@itextpdf.com
*/
using System;
+using iText.Kernel;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Layer;
namespace iText.Kernel.Pdf.Xobject {
+ /// An abstract wrapper for supported types of XObject.
+ ///
+ ///
public class PdfXObject : PdfObjectWrapper {
+ [Obsolete]
public PdfXObject()
: this(new PdfStream()) {
}
+ [Obsolete]
public PdfXObject(PdfStream pdfObject)
: base(pdfObject) {
}
+ ///
+ /// Create
+ ///
+ /// or
+ ///
+ /// by
+ ///
+ /// .
+ ///
+ ///
+ ///
+ ///
+ /// with either
+ ///
+ /// or
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// either
+ ///
+ /// or
+ ///
+ /// .
+ ///
public static iText.Kernel.Pdf.Xobject.PdfXObject MakeXObject(PdfStream stream) {
- if (PdfName.Form.Equals(stream.GetAsName(PdfName.Subtype)) || stream.ContainsKey(PdfName.BBox)) {
+ if (PdfName.Form.Equals(stream.GetAsName(PdfName.Subtype))) {
return new PdfFormXObject(stream);
}
else {
- return new PdfImageXObject(stream);
+ if (PdfName.Image.Equals(stream.GetAsName(PdfName.Subtype))) {
+ return new PdfImageXObject(stream);
+ }
+ else {
+ throw new NotSupportedException(PdfException.UnsupportedXObjectType);
+ }
}
}
/// Sets the layer this XObject belongs to.
- /// the layer this XObject belongs to
+ /// the layer this XObject belongs to.
public virtual void SetLayer(IPdfOCG layer) {
GetPdfObject().Put(PdfName.OC, layer.GetIndirectReference());
}
+ /// Gets width of XObject.
+ /// float value.
public virtual float GetWidth() {
throw new NotSupportedException();
}
+ /// Gets height of XObject.
+ /// float value.
public virtual float GetHeight() {
throw new NotSupportedException();
}
+ ///
protected internal override bool IsWrappedObjectMustBeIndirect() {
return true;
}
diff --git a/itext/itext.kernel/itext/kernel/utils/CompareTool.cs b/itext/itext.kernel/itext/kernel/utils/CompareTool.cs
index f5023659a1..9fb4caed73 100644
--- a/itext/itext.kernel/itext/kernel/utils/CompareTool.cs
+++ b/itext/itext.kernel/itext/kernel/utils/CompareTool.cs
@@ -41,2165 +41,2312 @@ source product.
For more information, please contact iText Software Corp. at this
address: sales@itextpdf.com
*/
-
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Text;
using System.Xml;
-using System.Xml.Linq;
using iText.IO.Font;
-using iText.IO.Source;
using iText.IO.Util;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Annot;
+using iText.Kernel.Pdf.Canvas;
using iText.Kernel.XMP;
using iText.Kernel.XMP.Options;
-using Path = System.IO.Path;
-namespace iText.Kernel.Utils
-{
- public class CompareTool
- {
- private const String cannotOpenOutputDirectory = "Cannot open output directory for .";
+namespace iText.Kernel.Utils {
+ ///
+ /// This class provides means to compare two PDF files both by content and visually
+ /// and gives the report of their differences.
+ ///
+ ///
+ /// This class provides means to compare two PDF files both by content and visually
+ /// and gives the report of their differences.
+ ///
+ /// For visual comparison it uses external tools: Ghostscript and ImageMagick, which
+ /// should be installed on your machine. To allow CompareTool to use them, you need
+ /// to pass either java properties or environment variables with names "gsExec" and
+ /// "compareExec", which would contain the paths to the executables of correspondingly
+ /// Ghostscript and ImageMagick tools.
+ ///
+ /// CompareTool class was mainly designed for the testing purposes of iText in order to
+ /// ensure that the same code produces the same PDF document. For this reason you will
+ /// often encounter such parameter names as "outDoc" and "cmpDoc" which stand for output
+ /// document and document-for-comparison. The first one is viewed as the current result,
+ /// and the second one is referred as normal or ideal result. OutDoc is compared to the
+ /// ideal cmpDoc. Therefore all reports of the comparison are in the form: "Expected ...,
+ /// but was ...". This should be interpreted in the following way: "expected" part stands
+ /// for the content of the cmpDoc and "but was" part stands for the content of the outDoc.
+ ///
+ public class CompareTool {
+ private const String cannotOpenOutputDirectory = "Cannot open output directory for .";
+
+ private const String gsFailed = "GhostScript failed for .";
+
+ private const String unexpectedNumberOfPages = "Unexpected number of pages for .";
+
+ private const String differentPages = "File differs on page .";
+
+ private const String undefinedGsPath = "Path to GhostScript is not specified. Please use -DgsExec= (e.g. -DgsExec=\"C:/Program Files/gs/gs9.14/bin/gswin32c.exe\")";
+
+ private const String ignoredAreasPrefix = "ignored_areas_";
+
+ private const String gsParams = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=";
+
+ private const String compareParams = " \"\" \"\" \"\"";
+
+ private String gsExec;
+
+ private String compareExec;
+
+ private String cmpPdf;
+
+ private String cmpPdfName;
+
+ private String cmpImage;
+
+ private String outPdf;
+
+ private String outPdfName;
+
+ private String outImage;
+
+ private ReaderProperties outProps;
+
+ private ReaderProperties cmpProps;
+
+ private IList outPagesRef;
+
+ private IList cmpPagesRef;
+
+ private int compareByContentErrorsLimit = 1;
+
+ private bool generateCompareByContentXmlReport = false;
+
+ private bool encryptionCompareEnabled = false;
+
+ private bool useCachedPagesForComparison = true;
+
+ /// Creates an instance of the CompareTool.
+ public CompareTool() {
+ gsExec = iText.IO.Util.SystemUtil.GetEnvironmentVariable("gsExec");
+ compareExec = iText.IO.Util.SystemUtil.GetEnvironmentVariable("compareExec");
+ }
+
+ ///
+ /// Compares two PDF documents by content starting from Catalog dictionary and then recursively comparing
+ /// corresponding objects which are referenced from it.
+ ///
+ ///
+ /// Compares two PDF documents by content starting from Catalog dictionary and then recursively comparing
+ /// corresponding objects which are referenced from it. You can roughly imagine it as depth-first traversal
+ /// of the two trees that represent pdf objects structure of the documents.
+ ///
+ /// The main difference between this method and the
+ ///
+ /// methods is the return value. This method returns a
+ ///
+ /// class instance, which could be used
+ /// in code, however compareByContent methods in case of the differences simply return String value, which could
+ /// only be printed. Also, keep in mind that this method doesn't perform visual comparison of the documents.
+ ///
+ /// For more explanations about what is outDoc and cmpDoc see last paragraph of the
+ ///
+ /// class description.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ ///
+ /// the report of comparison of two files in the form of the custom class instance.
+ /// See
+ ///
+ /// for more info.
+ ///
+ ///
+ public virtual CompareTool.CompareResult CompareByCatalog(PdfDocument outDocument, PdfDocument cmpDocument
+ ) {
+ CompareTool.CompareResult compareResult = null;
+ compareResult = new CompareTool.CompareResult(this, compareByContentErrorsLimit);
+ CompareTool.ObjectPath catalogPath = new CompareTool.ObjectPath(cmpDocument.GetCatalog().GetPdfObject().GetIndirectReference
+ (), outDocument.GetCatalog().GetPdfObject().GetIndirectReference());
+ ICollection ignoredCatalogEntries = new LinkedHashSet(iText.IO.Util.JavaUtil.ArraysAsList
+ (PdfName.Metadata));
+ CompareDictionariesExtended(outDocument.GetCatalog().GetPdfObject(), cmpDocument.GetCatalog().GetPdfObject
+ (), catalogPath, compareResult, ignoredCatalogEntries);
+ return compareResult;
+ }
+
+ /// Disables the default logic of pages comparison.
+ ///
+ /// Disables the default logic of pages comparison.
+ /// This option makes sense only for
+ ///
+ /// method.
+ ///
+ /// By default, pages are treated as special objects and if they are met in the process of comparison, then they are
+ /// not checked as objects, but rather simply checked that they has same page numbers in both documents.
+ /// This behaviour is intended for the
+ ///
+ /// set of methods, because in them documents are compared in page by page basis. Thus, we don't need to check if pages
+ /// are of the same content when they are met in comparison process, we are sure that we will compare their content or
+ /// we have already compared them.
+ ///
+ /// However, if you would use
+ ///
+ /// with default behaviour
+ /// of pages comparison, pages won't be checked at all, every time when reference to the page dictionary is met,
+ /// only page numbers will be compared for both documents. You can say that in this case, comparison will be performed
+ /// for all document's catalog entries except /Pages (However in fact, document's page tree structures will be compared,
+ /// but pages themselves - won't).
+ ///
+ ///
+ /// this
+ ///
+ /// instance.
+ ///
+ public virtual iText.Kernel.Utils.CompareTool DisableCachedPagesComparison() {
+ this.useCachedPagesForComparison = false;
+ return this;
+ }
+
+ /// Sets the maximum errors count which will be returned as the result of the comparison.
+ /// the errors count.
+ /// this CompareTool instance.
+ public virtual iText.Kernel.Utils.CompareTool SetCompareByContentErrorsLimit(int compareByContentMaxErrorCount
+ ) {
+ this.compareByContentErrorsLimit = compareByContentMaxErrorCount;
+ return this;
+ }
+
+ /// Enables or disables the generation of the comparison report in the form of the xml document.
+ ///
+ /// Enables or disables the generation of the comparison report in the form of the xml document.
+ ///
+ /// IMPORTANT NOTE: this flag affect only the comparison made by compareByContent methods!
+ ///
+ /// true to enable xml report generation, false - to disable.
+ /// this CompareTool instance.
+ public virtual iText.Kernel.Utils.CompareTool SetGenerateCompareByContentXmlReport(bool generateCompareByContentXmlReport
+ ) {
+ this.generateCompareByContentXmlReport = generateCompareByContentXmlReport;
+ return this;
+ }
+
+ /// Enables the comparison of the encryption properties of the documents.
+ ///
+ /// Enables the comparison of the encryption properties of the documents. Encryption properties comparison
+ /// results are returned along with all other comparison results.
+ ///
+ /// IMPORTANT NOTE: this flag affect only the comparison made by compareByContent methods!
+ ///
+ /// this CompareTool instance.
+ public virtual iText.Kernel.Utils.CompareTool EnableEncryptionCompare() {
+ this.encryptionCompareEnabled = true;
+ return this;
+ }
+
+ /// Documents for comparison are opened in reader mode.
+ ///
+ /// Documents for comparison are opened in reader mode. This method is intended to alter
+ ///
+ /// which are used to open output document. This is particularly useful for comparison of encrypted documents.
+ ///
+ /// For more explanations about what is outDoc and cmpDoc see last paragraph of the
+ ///
+ /// class description.
+ ///
+ ///
+ ///
+ ///
+ /// instance which will be later passed to the output document
+ ///
+ /// .
+ ///
+ public virtual ReaderProperties GetOutReaderProperties() {
+ if (outProps == null) {
+ outProps = new ReaderProperties();
+ }
+ return outProps;
+ }
+
+ /// Documents for comparison are opened in reader mode.
+ ///
+ /// Documents for comparison are opened in reader mode. This method is intended to alter
+ ///
+ /// which are used to open cmp document. This is particularly useful for comparison of encrypted documents.
+ ///
+ /// For more explanations about what is outDoc and cmpDoc see last paragraph of the
+ ///
+ /// class description.
+ ///
+ ///
+ ///
+ ///
+ /// instance which will be later passed to the cmp document
+ ///
+ /// .
+ ///
+ public virtual ReaderProperties GetCmpReaderProperties() {
+ if (cmpProps == null) {
+ cmpProps = new ReaderProperties();
+ }
+ return cmpProps;
+ }
+
+ /// Compares two documents visually.
+ ///
+ /// Compares two documents visually. For the comparison two external tools are used: Ghostscript and ImageMagick.
+ /// For more info about needed configuration for visual comparison process see
+ ///
+ /// class description.
+ ///
+ /// During comparison for every page of two documents an image file will be created in the folder specified by
+ /// outPath absolute path. Then those page images will be compared and if there are any differences for some pages,
+ /// another image file will be created with marked differences on it.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked differences if there is any.
+ ///
+ /// string containing list of the pages that are visually different, or null if there are no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareVisually(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ ) {
+ return CompareVisually(outPdf, cmpPdf, outPath, differenceImagePrefix, null);
+ }
+
+ /// Compares two documents visually.
+ ///
+ /// Compares two documents visually. For the comparison two external tools are used: Ghostscript and ImageMagick.
+ /// For more info about needed configuration for visual comparison process see
+ ///
+ /// class description.
+ ///
+ /// During comparison for every page of two documents an image file will be created in the folder specified by
+ /// outPath absolute path. Then those page images will be compared and if there are any differences for some pages,
+ /// another image file will be created with marked differences on it.
+ ///
+ /// It is possible to ignore certain areas of the document pages during visual comparison. This is useful for example
+ /// in case if documents should be the same except certain page area with date on it. In this case, in the folder
+ /// specified by the outPath, new pdf documents will be created with the black rectangles at the specified ignored
+ /// areas, and visual comparison will be performed on these new documents.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked differences if there is any.
+ ///
+ /// a map with one-based page numbers as keys and lists of ignored rectangles as values.
+ ///
+ /// string containing list of the pages that are visually different, or null if there are no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareVisually(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ , IDictionary> ignoredAreas) {
+ Init(outPdf, cmpPdf);
+ return CompareVisually(outPath, differenceImagePrefix, ignoredAreas);
+ }
+
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them.
+ ///
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them. You can roughly imagine it as depth-first traversal
+ /// of the two trees that represent pdf objects structure of the documents.
+ ///
+ /// Unlike
+ ///
+ /// this method performs content comparison page by page
+ /// and doesn't compare the tag structure, acroforms and all other things that doesn't belong to specific pages.
+ ///
+ /// When comparison by content is finished, if any differences were found, visual comparison is automatically started.
+ /// For more info see
+ ///
+ /// .
+ ///
+ /// For more explanations about what is outPdf and cmpPdf see last paragraph of the
+ ///
+ /// class description.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked visual differences if there is any.
+ ///
+ ///
+ /// string containing text report of the encountered content differences and also list of the pages that are
+ /// visually different, or null if there are no content and therefore no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ ) {
+ return CompareByContent(outPdf, cmpPdf, outPath, differenceImagePrefix, null, null, null);
+ }
+
+ /// This method overload is used to compare two encrypted PDF documents.
+ ///
+ /// This method overload is used to compare two encrypted PDF documents. Document passwords are passed with
+ /// outPass and cmpPass parameters.
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them. You can roughly imagine it as depth-first traversal
+ /// of the two trees that represent pdf objects structure of the documents.
+ ///
+ /// Unlike
+ ///
+ /// this method performs content comparison page by page
+ /// and doesn't compare the tag structure, acroforms and all other things that doesn't belong to specific pages.
+ ///
+ /// When comparison by content is finished, if any differences were found, visual comparison is automatically started.
+ /// For more info see
+ ///
+ /// .
+ ///
+ /// For more explanations about what is outPdf and cmpPdf see last paragraph of the
+ ///
+ /// class description.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked visual differences if there is any.
+ ///
+ /// password for the encrypted document specified by the outPdf absolute path.
+ /// password for the encrypted document specified by the cmpPdf absolute path.
+ ///
+ /// string containing text report of the encountered content differences and also list of the pages that are
+ /// visually different, or null if there are no content and therefore no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ , byte[] outPass, byte[] cmpPass) {
+ return CompareByContent(outPdf, cmpPdf, outPath, differenceImagePrefix, null, outPass, cmpPass);
+ }
+
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them.
+ ///
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them. You can roughly imagine it as depth-first traversal
+ /// of the two trees that represent pdf objects structure of the documents.
+ ///
+ /// Unlike
+ ///
+ /// this method performs content comparison page by page
+ /// and doesn't compare the tag structure, acroforms and all other things that doesn't belong to specific pages.
+ ///
+ /// When comparison by content is finished, if any differences were found, visual comparison is automatically started.
+ /// For more info see
+ ///
+ /// .
+ ///
+ /// For more explanations about what is outPdf and cmpPdf see last paragraph of the
+ ///
+ /// class description.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked visual differences if there is any.
+ ///
+ /// a map with one-based page numbers as keys and lists of ignored rectangles as values.
+ ///
+ ///
+ /// string containing text report of the encountered content differences and also list of the pages that are
+ /// visually different, or null if there are no content and therefore no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ , IDictionary> ignoredAreas) {
+ Init(outPdf, cmpPdf);
+ return CompareByContent(outPath, differenceImagePrefix, ignoredAreas);
+ }
+
+ /// This method overload is used to compare two encrypted PDF documents.
+ ///
+ /// This method overload is used to compare two encrypted PDF documents. Document passwords are passed with
+ /// outPass and cmpPass parameters.
+ ///
+ /// Compares two PDF documents by content starting from page dictionaries and then recursively comparing
+ /// corresponding objects which are referenced from them. You can roughly imagine it as depth-first traversal
+ /// of the two trees that represent pdf objects structure of the documents.
+ ///
+ /// Unlike
+ ///
+ /// this method performs content comparison page by page
+ /// and doesn't compare the tag structure, acroforms and all other things that doesn't belong to specific pages.
+ ///
+ /// When comparison by content is finished, if any differences were found, visual comparison is automatically started.
+ /// For more info see
+ ///
+ /// .
+ ///
+ /// For more explanations about what is outPdf and cmpPdf see last paragraph of the
+ ///
+ /// class description.
+ ///
+ /// the absolute path to the output file, which is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which is to be compared to output file.
+ /// the absolute path to the folder, which will be used to store image files for visual comparison.
+ ///
+ /// file name prefix for image files with marked visual differences if there is any.
+ ///
+ /// a map with one-based page numbers as keys and lists of ignored rectangles as values.
+ ///
+ /// password for the encrypted document specified by the outPdf absolute path.
+ /// password for the encrypted document specified by the cmpPdf absolute path.
+ ///
+ /// string containing text report of the encountered content differences and also list of the pages that are
+ /// visually different, or null if there are no content and therefore no visual differences.
+ ///
+ ///
+ ///
+ public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath, String differenceImagePrefix
+ , IDictionary> ignoredAreas, byte[] outPass, byte[] cmpPass) {
+ Init(outPdf, cmpPdf);
+ SetPassword(outPass, cmpPass);
+ return CompareByContent(outPath, differenceImagePrefix, ignoredAreas);
+ }
+
+ /// Simple method that compares two given PdfDictionaries by content.
+ ///
+ /// Simple method that compares two given PdfDictionaries by content. This is "deep" comparing, which means that all
+ /// nested objects are also compared by content.
+ ///
+ /// dictionary to compare.
+ /// dictionary to compare.
+ /// true if dictionaries are equal by content, otherwise false.
+ ///
+ public virtual bool CompareDictionaries(PdfDictionary outDict, PdfDictionary cmpDict) {
+ return CompareDictionariesExtended(outDict, cmpDict, null, null);
+ }
+
+ /// Simple method that compares two given PdfStreams by content.
+ ///
+ /// Simple method that compares two given PdfStreams by content. This is "deep" comparing, which means that all
+ /// nested objects are also compared by content.
+ ///
+ /// stream to compare.
+ /// stream to compare.
+ /// true if stream are equal by content, otherwise false.
+ ///
+ public virtual bool CompareStreams(PdfStream outStream, PdfStream cmpStream) {
+ return CompareStreamsExtended(outStream, cmpStream, null, null);
+ }
+
+ /// Simple method that compares two given PdfArrays by content.
+ ///
+ /// Simple method that compares two given PdfArrays by content. This is "deep" comparing, which means that all
+ /// nested objects are also compared by content.
+ ///
+ /// array to compare.
+ /// array to compare.
+ /// true if arrays are equal by content, otherwise false.
+ ///
+ public virtual bool CompareArrays(PdfArray outArray, PdfArray cmpArray) {
+ return CompareArraysExtended(outArray, cmpArray, null, null);
+ }
+
+ /// Simple method that compares two given PdfNames.
+ /// name to compare.
+ /// name to compare.
+ /// true if names are equal, otherwise false.
+ public virtual bool CompareNames(PdfName outName, PdfName cmpName) {
+ return cmpName.Equals(outName);
+ }
+
+ /// Simple method that compares two given PdfNumbers.
+ /// number to compare.
+ /// number to compare.
+ /// true if numbers are equal, otherwise false.
+ public virtual bool CompareNumbers(PdfNumber outNumber, PdfNumber cmpNumber) {
+ return cmpNumber.GetValue() == outNumber.GetValue();
+ }
- private const String gsFailed = "GhostScript failed for .";
+ /// Simple method that compares two given PdfStrings.
+ /// string to compare.
+ /// string to compare.
+ /// true if strings are equal, otherwise false.
+ public virtual bool CompareStrings(PdfString outString, PdfString cmpString) {
+ return cmpString.GetValue().Equals(outString.GetValue());
+ }
- private const String unexpectedNumberOfPages = "Unexpected number of pages for .";
+ /// Simple method that compares two given PdfBooleans.
+ /// boolean to compare.
+ /// boolean to compare.
+ /// true if booleans are equal, otherwise false.
+ public virtual bool CompareBooleans(PdfBoolean outBoolean, PdfBoolean cmpBoolean) {
+ return cmpBoolean.GetValue() == outBoolean.GetValue();
+ }
- private const String differentPages = "File differs on page .";
+ /// Compares xmp metadata of the two given PDF documents.
+ /// the absolute path to the output file, which xmp is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which xmp is to be compared to output file.
+ /// text report of the xmp differences, or null if there are no differences.
+ public virtual String CompareXmp(String outPdf, String cmpPdf) {
+ return CompareXmp(outPdf, cmpPdf, false);
+ }
- private const String undefinedGsPath = "Path to GhostScript is not specified. Please use -DgsExec= (e.g. -DgsExec=\"C:/Program Files/gs/gs9.14/bin/gswin32c.exe\")";
+ /// Compares xmp metadata of the two given PDF documents.
+ /// the absolute path to the output file, which xmp is to be compared to cmp-file.
+ /// the absolute path to the cmp-file, which xmp is to be compared to output file.
+ ///
+ /// true, if to ignore differences in date or producer xmp metadata
+ /// properties.
+ ///
+ /// text report of the xmp differences, or null if there are no differences.
+ public virtual String CompareXmp(String outPdf, String cmpPdf, bool ignoreDateAndProducerProperties) {
+ Init(outPdf, cmpPdf);
+ PdfDocument cmpDocument = null;
+ PdfDocument outDocument = null;
+ try {
+ cmpDocument = new PdfDocument(new PdfReader(this.cmpPdf));
+ outDocument = new PdfDocument(new PdfReader(this.outPdf));
+ byte[] cmpBytes = cmpDocument.GetXmpMetadata();
+ byte[] outBytes = outDocument.GetXmpMetadata();
+ if (ignoreDateAndProducerProperties) {
+ XMPMeta xmpMeta = XMPMetaFactory.ParseFromBuffer(cmpBytes);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.CreateDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.ModifyDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.MetadataDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_PDF, PdfConst.Producer, true, true);
+ cmpBytes = XMPMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions.SORT));
+ xmpMeta = XMPMetaFactory.ParseFromBuffer(outBytes);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.CreateDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.ModifyDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.MetadataDate, true, true);
+ XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_PDF, PdfConst.Producer, true, true);
+ outBytes = XMPMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions.SORT));
+ }
+ if (!CompareXmls(cmpBytes, outBytes)) {
+ return "The XMP packages different!";
+ }
+ }
+ catch (Exception) {
+ return "XMP parsing failure!";
+ }
+ finally {
+ if (cmpDocument != null) {
+ cmpDocument.Close();
+ }
+ if (outDocument != null) {
+ outDocument.Close();
+ }
+ }
+ return null;
+ }
- private const String ignoredAreasPrefix = "ignored_areas_";
+ /// Utility method that provides simple comparison of the two xml files stored in byte arrays.
+ /// first xml file data to compare.
+ /// second xml file data to compare.
+ /// true if xml structures are identical, false otherwise.
+ ///
+ ///
+ ///
+ public virtual bool CompareXmls(byte[] xml1, byte[] xml2) {
+ return XmlUtils.CompareXmls(new MemoryStream(xml1), new MemoryStream(xml2));
+ }
- private const String gsParams = " -dNOPAUSE -dBATCH -sDEVICE=png16m -r150 -sOutputFile=";
+ /// Utility method that provides simple comparison of the two xml files.
+ /// absolute path to the first xml file to compare.
+ /// absolute path to the second xml file to compare.
+ /// true if xml structures are identical, false otherwise.
+ ///
+ ///
+ ///
+ public virtual bool CompareXmls(String xmlFilePath1, String xmlFilePath2) {
+ return XmlUtils.CompareXmls(new FileStream(xmlFilePath1, FileMode.Open, FileAccess.Read), new FileStream(xmlFilePath2
+ , FileMode.Open, FileAccess.Read));
+ }
- private const String compareParams = " \"\" \"\" \"\"";
+ /// This method overload is used to compare two encrypted PDF documents.
+ ///
+ /// This method overload is used to compare two encrypted PDF documents. Document passwords are passed with
+ /// outPass and cmpPass parameters.
+ ///
+ /// Compares document info dictionaries of two pdf documents.
+ ///
+ /// the absolute path to the output file, which info is to be compared to cmp-file info.
+ /// the absolute path to the cmp-file, which info is to be compared to output file info.
+ /// password for the encrypted document specified by the outPdf absolute path.
+ /// password for the encrypted document specified by the cmpPdf absolute path.
+ /// text report of the differences in documents infos.
+ ///
+ public virtual String CompareDocumentInfo(String outPdf, String cmpPdf, byte[] outPass, byte[] cmpPass) {
+ System.Console.Out.Write("[itext] INFO Comparing document info.......");
+ String message = null;
+ SetPassword(outPass, cmpPass);
+ PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf, GetOutReaderProperties()));
+ PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf, GetCmpReaderProperties()));
+ String[] cmpInfo = ConvertInfo(cmpDocument.GetDocumentInfo());
+ String[] outInfo = ConvertInfo(outDocument.GetDocumentInfo());
+ for (int i = 0; i < cmpInfo.Length; ++i) {
+ if (!cmpInfo[i].Equals(outInfo[i])) {
+ message = "Document info fail";
+ break;
+ }
+ }
+ outDocument.Close();
+ cmpDocument.Close();
+ if (message == null) {
+ System.Console.Out.WriteLine("OK");
+ }
+ else {
+ System.Console.Out.WriteLine("Fail");
+ }
+ System.Console.Out.Flush();
+ return message;
+ }
- private String gsExec;
+ /// Compares document info dictionaries of two pdf documents.
+ /// the absolute path to the output file, which info is to be compared to cmp-file info.
+ /// the absolute path to the cmp-file, which info is to be compared to output file info.
+ /// text report of the differences in documents infos.
+ ///
+ public virtual String CompareDocumentInfo(String outPdf, String cmpPdf) {
+ return CompareDocumentInfo(outPdf, cmpPdf, null, null);
+ }
- private String compareExec;
+ /// Compares if two documents has identical link annotations on corresponding pages.
+ /// the absolute path to the output file, which links are to be compared to cmp-file links.
+ ///
+ /// the absolute path to the cmp-file, which links are to be compared to output file links.
+ ///
+ /// text report of the differences in documents links.
+ ///
+ public virtual String CompareLinkAnnotations(String outPdf, String cmpPdf) {
+ System.Console.Out.Write("[itext] INFO Comparing link annotations....");
+ String message = null;
+ PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf));
+ PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf));
+ for (int i = 0; i < outDocument.GetNumberOfPages() && i < cmpDocument.GetNumberOfPages(); i++) {
+ IList outLinks = GetLinkAnnotations(i + 1, outDocument);
+ IList cmpLinks = GetLinkAnnotations(i + 1, cmpDocument);
+ if (cmpLinks.Count != outLinks.Count) {
+ message = String.Format("Different number of links on page {0}.", i + 1);
+ break;
+ }
+ for (int j = 0; j < cmpLinks.Count; j++) {
+ if (!CompareLinkAnnotations(cmpLinks[j], outLinks[j], cmpDocument, outDocument)) {
+ message = String.Format("Different links on page {0}.\n{1}\n{2}", i + 1, cmpLinks[j].ToString(), outLinks[
+ j].ToString());
+ break;
+ }
+ }
+ }
+ outDocument.Close();
+ cmpDocument.Close();
+ if (message == null) {
+ System.Console.Out.WriteLine("OK");
+ }
+ else {
+ System.Console.Out.WriteLine("Fail");
+ }
+ System.Console.Out.Flush();
+ return message;
+ }
- private String cmpPdf;
-
- private String cmpPdfName;
+ /// Compares tag structures of the two PDF documents.
+ ///
+ /// Compares tag structures of the two PDF documents.
+ ///
+ /// This method creates xml files in the same folder with outPdf file. These xml files contain documents tag structures
+ /// converted into the xml structure. These xml files are compared if they are equal.
+ ///
+ /// the absolute path to the output file, which tags are to be compared to cmp-file tags.
+ ///
+ /// the absolute path to the cmp-file, which tags are to be compared to output file tags.
+ ///
+ /// text report of the differences in documents tags.
+ ///
+ ///
+ ///
+ public virtual String CompareTagStructures(String outPdf, String cmpPdf) {
+ System.Console.Out.Write("[itext] INFO Comparing tag structures......");
+ String outXmlPath = outPdf.Replace(".pdf", ".xml");
+ String cmpXmlPath = outPdf.Replace(".pdf", ".cmp.xml");
+ String message = null;
+ PdfReader readerOut = new PdfReader(outPdf);
+ PdfDocument docOut = new PdfDocument(readerOut);
+ FileStream xmlOut = new FileStream(outXmlPath, FileMode.Create);
+ new TaggedPdfReaderTool(docOut).SetRootTag("root").ConvertToXml(xmlOut);
+ docOut.Close();
+ xmlOut.Close();
+ PdfReader readerCmp = new PdfReader(cmpPdf);
+ PdfDocument docCmp = new PdfDocument(readerCmp);
+ FileStream xmlCmp = new FileStream(cmpXmlPath, FileMode.Create);
+ new TaggedPdfReaderTool(docCmp).SetRootTag("root").ConvertToXml(xmlCmp);
+ docCmp.Close();
+ xmlCmp.Close();
+ if (!CompareXmls(outXmlPath, cmpXmlPath)) {
+ message = "The tag structures are different.";
+ }
+ if (message == null) {
+ System.Console.Out.WriteLine("OK");
+ }
+ else {
+ System.Console.Out.WriteLine("Fail");
+ }
+ System.Console.Out.Flush();
+ return message;
+ }
- private String cmpImage;
-
- private String outPdf;
-
- private String outPdfName;
-
- private String outImage;
-
- private IList outPagesRef;
-
- private IList cmpPagesRef;
-
- private int compareByContentErrorsLimit = 1;
-
- private bool generateCompareByContentXmlReport = false;
-
- private bool encryptionCompareEnabled = false;
-
- private bool useCachedPagesForComparison = true;
-
- public CompareTool()
- {
- gsExec = System.Environment.GetEnvironmentVariable("gsExec");
- compareExec = System.Environment.GetEnvironmentVariable("compareExec");
- }
-
- ///
- public virtual CompareTool.CompareResult CompareByCatalog(PdfDocument outDocument
- , PdfDocument cmpDocument)
- {
- CompareTool.CompareResult compareResult = null;
- compareResult = new CompareTool.CompareResult(this, compareByContentErrorsLimit);
- CompareTool.ObjectPath catalogPath = new CompareTool.ObjectPath(cmpDocument
- .GetCatalog().GetPdfObject().GetIndirectReference(), outDocument.GetCatalog().GetPdfObject
- ().GetIndirectReference());
- ICollection ignoredCatalogEntries = new LinkedHashSet(iText.IO.Util.JavaUtil.ArraysAsList
- (PdfName.Metadata));
- CompareDictionariesExtended(outDocument.GetCatalog().GetPdfObject(), cmpDocument.
- GetCatalog().GetPdfObject(), catalogPath, compareResult, ignoredCatalogEntries);
- return compareResult;
- }
-
- public virtual iText.Kernel.Utils.CompareTool DisableCachedPagesComparison()
- {
- this.useCachedPagesForComparison = false;
- return this;
- }
-
- /// Sets the maximum errors count which will be returned as the result of the comparison.
- ///
- /// the errors count.
- /// Returns this.
- public virtual iText.Kernel.Utils.CompareTool SetCompareByContentErrorsLimit
- (int compareByContentMaxErrorCount)
- {
- this.compareByContentErrorsLimit = compareByContentMaxErrorCount;
- return this;
- }
-
- public virtual iText.Kernel.Utils.CompareTool SetGenerateCompareByContentXmlReport
- (bool generateCompareByContentXmlReport)
- {
- this.generateCompareByContentXmlReport = generateCompareByContentXmlReport;
- return this;
- }
-
- public virtual iText.Kernel.Utils.CompareTool EnableEncryptionCompare()
- {
- this.encryptionCompareEnabled = true;
- return this;
- }
-
- ///
- ///
- public virtual String CompareVisually(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix)
- {
- return CompareVisually(outPdf, cmpPdf, outPath, differenceImagePrefix, null);
- }
-
- ///
- ///
- public virtual String CompareVisually(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix, IDictionary> ignoredAreas
- )
- {
- Init(outPdf, cmpPdf);
- return CompareVisually(outPath, differenceImagePrefix, ignoredAreas);
- }
-
- ///
- ///
- public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix)
- {
- return CompareByContent(outPdf, cmpPdf, outPath, differenceImagePrefix, null, null
- , null);
- }
-
- ///
- ///
- public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix, byte[] outPass, byte[] cmpPass)
- {
- return CompareByContent(outPdf, cmpPdf, outPath, differenceImagePrefix, null, outPass
- , cmpPass);
- }
-
- ///
- ///
- public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix, IDictionary> ignoredAreas
- )
- {
- Init(outPdf, cmpPdf);
- return CompareByContent(outPath, differenceImagePrefix, ignoredAreas, null, null);
- }
-
- ///
- ///
- public virtual String CompareByContent(String outPdf, String cmpPdf, String outPath
- , String differenceImagePrefix, IDictionary> ignoredAreas
- , byte[] outPass, byte[] cmpPass)
- {
- Init(outPdf, cmpPdf);
- return CompareByContent(outPath, differenceImagePrefix, ignoredAreas, outPass, cmpPass
- );
- }
-
- ///
- public virtual bool CompareDictionaries(PdfDictionary outDict, PdfDictionary cmpDict
- )
- {
- return CompareDictionariesExtended(outDict, cmpDict, null, null);
- }
-
- ///
- public virtual bool CompareStreams(PdfStream outStream, PdfStream cmpStream)
- {
- return CompareStreamsExtended(outStream, cmpStream, null, null);
- }
-
- ///
- public virtual bool CompareArrays(PdfArray outArray, PdfArray cmpArray)
- {
- return CompareArraysExtended(outArray, cmpArray, null, null);
- }
-
- public virtual bool CompareNames(PdfName outName, PdfName cmpName)
- {
- return cmpName.Equals(outName);
- }
-
- public virtual bool CompareNumbers(PdfNumber outNumber, PdfNumber cmpNumber) {
- return 0 == cmpNumber.GetValue().CompareTo(outNumber.GetValue());
- }
-
- public virtual bool CompareStrings(PdfString outString, PdfString cmpString)
- {
- return cmpString.GetValue().Equals(outString.GetValue());
- }
-
- public virtual bool CompareBooleans(PdfBoolean outBoolean, PdfBoolean cmpBoolean)
- {
- return cmpBoolean.GetValue() == outBoolean.GetValue();
- }
-
- public virtual String CompareXmp(String outPdf, String cmpPdf)
- {
- return CompareXmp(outPdf, cmpPdf, false);
- }
-
- public virtual String CompareXmp(String outPdf, String cmpPdf, bool ignoreDateAndProducerProperties
- )
- {
- Init(outPdf, cmpPdf);
- PdfDocument cmpDocument = null;
- PdfDocument outDocument = null;
- try
- {
- cmpDocument = new PdfDocument(new PdfReader(this.cmpPdf));
- outDocument = new PdfDocument(new PdfReader(this.outPdf));
- byte[] cmpBytes = cmpDocument.GetXmpMetadata();
- byte[] outBytes = outDocument.GetXmpMetadata();
- if (ignoreDateAndProducerProperties)
- {
- XMPMeta xmpMeta = XMPMetaFactory.ParseFromBuffer(cmpBytes);
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.CreateDate, true, true
- );
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.ModifyDate, true, true
- );
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.MetadataDate, true,
- true);
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_PDF, PdfConst.Producer, true, true
- );
- cmpBytes = XMPMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions
- .SORT));
- xmpMeta = XMPMetaFactory.ParseFromBuffer(outBytes);
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.CreateDate, true, true
- );
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.ModifyDate, true, true
- );
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_XMP, PdfConst.MetadataDate, true,
- true);
- XMPUtils.RemoveProperties(xmpMeta, XMPConst.NS_PDF, PdfConst.Producer, true, true
- );
- outBytes = XMPMetaFactory.SerializeToBuffer(xmpMeta, new SerializeOptions(SerializeOptions
- .SORT));
- }
- if (!CompareXmls(cmpBytes, outBytes))
- {
- return "The XMP packages different!";
- }
- }
- catch (XMPException)
- {
- return "XMP parsing failure!";
- }
- catch (System.IO.IOException)
- {
- return "XMP parsing failure!";
- }
- finally
- {
- if (cmpDocument != null)
- {
- cmpDocument.Close();
- }
- if (outDocument != null)
- {
- outDocument.Close();
- }
- }
- return null;
- }
-
- ///
- ///
- ///
- public virtual bool CompareXmls(byte[] xml1, byte[] xml2)
- {
- return CompareXmls(new MemoryStream(xml1), new MemoryStream(xml2));
- }
-
- ///
- ///
- ///
- public virtual bool CompareXmls(String xmlFilePath1, String xmlFilePath2)
- {
- return CompareXmls(new FileStream(xmlFilePath1, FileMode.Open, FileAccess.Read), new FileStream(xmlFilePath2
- , FileMode.Open, FileAccess.Read));
- }
-
- ///
- public virtual String CompareDocumentInfo(String outPdf, String cmpPdf, byte[] outPass
- , byte[] cmpPass)
- {
- System.Console.Out.Write("[itext] INFO Comparing document info.......");
- String message = null;
- PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf, new ReaderProperties
- ().SetPassword(outPass)));
- PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf, new ReaderProperties
- ().SetPassword(cmpPass)));
- String[] cmpInfo = ConvertInfo(cmpDocument.GetDocumentInfo());
- String[] outInfo = ConvertInfo(outDocument.GetDocumentInfo());
- for (int i = 0; i < cmpInfo.Length; ++i)
- {
- if (!cmpInfo[i].Equals(outInfo[i]))
- {
- message = "Document info fail";
- break;
- }
- }
- outDocument.Close();
- cmpDocument.Close();
- if (message == null)
- {
- System.Console.Out.WriteLine("OK");
- }
- else
- {
- System.Console.Out.WriteLine("Fail");
- }
- System.Console.Out.Flush();
- return message;
- }
-
- ///
- public virtual String CompareDocumentInfo(String outPdf, String cmpPdf)
- {
- return CompareDocumentInfo(outPdf, cmpPdf, null, null);
- }
-
- ///
- public virtual String CompareLinkAnnotations(String outPdf, String cmpPdf)
- {
- System.Console.Out.Write("[itext] INFO Comparing link annotations....");
- String message = null;
- PdfDocument outDocument = new PdfDocument(new PdfReader(outPdf));
- PdfDocument cmpDocument = new PdfDocument(new PdfReader(cmpPdf));
- for (int i = 0; i < outDocument.GetNumberOfPages() && i < cmpDocument.GetNumberOfPages
- (); i++)
- {
- IList outLinks = GetLinkAnnotations(i + 1, outDocument);
- IList cmpLinks = GetLinkAnnotations(i + 1, cmpDocument);
- if (cmpLinks.Count != outLinks.Count)
- {
- message = String.Format("Different number of links on page {0}.", i + 1);
- break;
- }
- for (int j = 0; j < cmpLinks.Count; j++)
- {
- if (!CompareLinkAnnotations(cmpLinks[j], outLinks[j], cmpDocument, outDocument))
- {
- message = String.Format("Different links on page {0}.\n{1}\n{2}", i + 1, cmpLinks
- [j].ToString(), outLinks[j].ToString());
- break;
- }
- }
- }
- outDocument.Close();
- cmpDocument.Close();
- if (message == null)
- {
- System.Console.Out.WriteLine("OK");
- }
- else
- {
- System.Console.Out.WriteLine("Fail");
- }
- System.Console.Out.Flush();
- return message;
- }
-
- ///
- ///
- ///
- public virtual String CompareTagStructures(String outPdf, String cmpPdf)
- {
- System.Console.Out.Write("[itext] INFO Comparing tag structures......");
- String outXmlPath = outPdf.Replace(".pdf", ".xml");
- String cmpXmlPath = outPdf.Replace(".pdf", ".cmp.xml");
- String message = null;
- PdfReader readerOut = new PdfReader(outPdf);
- PdfDocument docOut = new PdfDocument(readerOut);
- FileStream xmlOut = new FileStream(outXmlPath, FileMode.Create);
- new TaggedPdfReaderTool(docOut).SetRootTag("root").ConvertToXml(xmlOut);
- docOut.Close();
- xmlOut.Close();
- PdfReader readerCmp = new PdfReader(cmpPdf);
- PdfDocument docCmp = new PdfDocument(readerCmp);
- FileStream xmlCmp = new FileStream(cmpXmlPath, FileMode.Create);
- new TaggedPdfReaderTool(docCmp).SetRootTag("root").ConvertToXml(xmlCmp);
- docCmp.Close();
- xmlCmp.Close();
- if (!CompareXmls(outXmlPath, cmpXmlPath))
- {
- message = "The tag structures are different.";
- }
- if (message == null)
- {
- System.Console.Out.WriteLine("OK");
- }
- else
- {
- System.Console.Out.WriteLine("Fail");
- }
- System.Console.Out.Flush();
- return message;
- }
-
- private void Init(String outPdf, String cmpPdf)
- {
- this.outPdf = outPdf;
- this.cmpPdf = cmpPdf;
- outPdfName = new FileInfo(outPdf).Name;
+ private void Init(String outPdf, String cmpPdf) {
+ this.outPdf = outPdf;
+ this.cmpPdf = cmpPdf;
+ outPdfName = new FileInfo(outPdf).Name;
cmpPdfName = new FileInfo(cmpPdf).Name;
- outImage = outPdfName + "-%03d.png";
- if (cmpPdfName.StartsWith("cmp_"))
- {
- cmpImage = cmpPdfName + "-%03d.png";
- }
- else
- {
- cmpImage = "cmp_" + cmpPdfName + "-%03d.png";
- }
- }
-
- ///
- ///
- private String CompareVisually(String outPath, String differenceImagePrefix, IDictionary
- > ignoredAreas)
- {
- return CompareVisually(outPath, differenceImagePrefix, ignoredAreas, null);
- }
-
- ///
- ///
- private String CompareVisually(String outPath, String differenceImagePrefix, IDictionary
- > ignoredAreas, IList equalPages)
- {
- if (gsExec == null)
- {
- return undefinedGsPath;
- }
- if (!FileUtil.FileExists(gsExec))
- {
- return Path.GetFullPath(gsExec) + " does not exist";
- }
- if (!outPath.EndsWith("/"))
- {
- outPath = outPath + "/";
- }
- PrepareOutputDirs(outPath, differenceImagePrefix);
- if (ignoredAreas != null && ignoredAreas.Count > 0)
- {
- CreateIgnoredAreasPdfs(outPath, ignoredAreas);
- }
- String imagesGenerationResult = RunGhostScriptImageGeneration(outPath);
- if (imagesGenerationResult != null)
- {
- return imagesGenerationResult;
- }
- return CompareImagesOfPdfs(outPath, differenceImagePrefix, equalPages);
- }
-
- ///
- ///
- private String CompareImagesOfPdfs(String outPath, String differenceImagePrefix,
- IList equalPages)
- {
- String[] imageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, false, new PngFileFilter(this));
- String[] cmpImageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, false, new CmpPngFileFilter(this));
-
- bool bUnexpectedNumberOfPages = false;
- if (imageFiles.Length != cmpImageFiles.Length)
- {
- bUnexpectedNumberOfPages = true;
- }
- int cnt = Math.Min(imageFiles.Length, cmpImageFiles.Length);
- if (cnt < 1)
- {
- return "No files for comparing.\nThe result or sample pdf file is not processed by GhostScript.";
- }
- System.Array.Sort(imageFiles, new CompareTool.ImageNameComparator(this));
- System.Array.Sort(cmpImageFiles, new CompareTool.ImageNameComparator(this));
- String differentPagesFail = null;
- bool compareExecIsOk = compareExec != null && FileUtil.FileExists(compareExec);
- IList diffPages = new List();
- for (int i = 0; i < cnt; i++)
- {
- if (equalPages != null && equalPages.Contains(i))
- {
- continue;
- }
- System.Console.Out.Write("Comparing page " + iText.IO.Util.JavaUtil.IntegerToString
- (i + 1) + " (" + imageFiles[i] + ")...");
- FileStream is1 = new FileStream(imageFiles[i], FileMode.Open, FileAccess.Read);
- FileStream is2 = new FileStream(cmpImageFiles[i], FileMode.Open, FileAccess.Read);
- bool cmpResult = CompareStreams(is1, is2);
- is1.Close();
- is2.Close();
- if (!cmpResult)
- {
- differentPagesFail = " Page is different!";
- diffPages.Add(i + 1);
- if (compareExecIsOk)
- {
- String currCompareParams = compareParams.Replace("", imageFiles[i])
- .Replace("", cmpImageFiles[i]).Replace(""
- , outPath + differenceImagePrefix + iText.IO.Util.JavaUtil.IntegerToString(
- i + 1) + ".png");
- if (RunProcessAndWait(compareExec, currCompareParams))
- {
- differentPagesFail += "\nPlease, examine " + outPath + differenceImagePrefix + iText.IO.Util.JavaUtil.IntegerToString
- (i + 1) + ".png for more details.";
- }
- }
- System.Console.Out.WriteLine(differentPagesFail);
- }
- else
- {
- System.Console.Out.WriteLine(" done.");
- }
- }
- if (differentPagesFail != null)
- {
- String errorMessage = differentPages.Replace("", outPdf).Replace(""
- , diffPages.ToString());
- if (!compareExecIsOk)
- {
- errorMessage += "\nYou can optionally specify path to ImageMagick compare tool (e.g. -DcompareExec=\"C:/Program Files/ImageMagick-6.5.4-2/compare.exe\") to visualize differences.";
- }
- return errorMessage;
- }
- else
- {
- if (bUnexpectedNumberOfPages)
- {
- return unexpectedNumberOfPages.Replace("", outPdf);
- }
- }
- return null;
- }
-
- ///
- private void CreateIgnoredAreasPdfs(String outPath, IDictionary> ignoredAreas)
- {
- PdfWriter outWriter = new PdfWriter(new FileStream(outPath + ignoredAreasPrefix +
- outPdfName, FileMode.Create));
- PdfWriter cmpWriter = new PdfWriter(new FileStream(outPath + ignoredAreasPrefix +
- cmpPdfName, FileMode.Create));
- PdfDocument pdfOutDoc = new PdfDocument(new PdfReader(outPdf), outWriter);
- PdfDocument pdfCmpDoc = new PdfDocument(new PdfReader(cmpPdf), cmpWriter);
- foreach (KeyValuePair> entry in ignoredAreas)
- {
- int pageNumber = (int) entry.Key;
- IList rectangles = entry.Value;
- if (rectangles != null && rectangles.Count > 0)
- {
- //drawing rectangles manually, because we don't want to create dependency on itextpdf.canvas module for itextpdf.kernel
- PdfStream outStream = GetPageContentStream(pdfOutDoc.GetPage(pageNumber));
- PdfStream cmpStream = GetPageContentStream(pdfCmpDoc.GetPage(pageNumber));
- outStream.GetOutputStream().WriteBytes(ByteUtils.GetIsoBytes("q\n"));
- outStream.GetOutputStream().WriteFloats(new float[] { 0.0f, 0.0f, 0.0f }).WriteSpace
- ().WriteBytes(ByteUtils.GetIsoBytes("rg\n"));
- cmpStream.GetOutputStream().WriteBytes(ByteUtils.GetIsoBytes("q\n"));
- cmpStream.GetOutputStream().WriteFloats(new float[] { 0.0f, 0.0f, 0.0f }).WriteSpace
- ().WriteBytes(ByteUtils.GetIsoBytes("rg\n"));
- foreach (Rectangle rect in rectangles)
- {
- outStream.GetOutputStream().WriteFloats(new float[] { rect.GetX(), rect.GetY(), rect
- .GetWidth(), rect.GetHeight() }).WriteSpace().WriteBytes(ByteUtils.GetIsoBytes("re\n"
- )).WriteBytes(ByteUtils.GetIsoBytes("f\n"));
- cmpStream.GetOutputStream().WriteFloats(new float[] { rect.GetX(), rect.GetY(), rect
- .GetWidth(), rect.GetHeight() }).WriteSpace().WriteBytes(ByteUtils.GetIsoBytes("re\n"
- )).WriteBytes(ByteUtils.GetIsoBytes("f\n"));
- }
- outStream.GetOutputStream().WriteBytes(ByteUtils.GetIsoBytes("Q\n"));
- cmpStream.GetOutputStream().WriteBytes(ByteUtils.GetIsoBytes("Q\n"));
- }
- }
- pdfOutDoc.Close();
- pdfCmpDoc.Close();
- Init(outPath + ignoredAreasPrefix + outPdfName, outPath + ignoredAreasPrefix + cmpPdfName
- );
- }
-
- private PdfStream GetPageContentStream(PdfPage page)
- {
- PdfStream stream = page.GetContentStream(page.GetContentStreamCount() - 1);
- return stream.GetOutputStream() == null ? page.NewContentStreamAfter() : stream;
- }
-
- private void PrepareOutputDirs(String outPath, String differenceImagePrefix)
- {
- String[] imageFiles;
- String[] cmpImageFiles;
- String[] diffFiles;
- if (FileUtil.DirectoryExists(outPath)) {
- Directory.CreateDirectory(outPath);
- }
- else
- {
- imageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, false, new CompareTool.PngFileFilter(this));
- foreach (String file in imageFiles)
- {
- File.Delete(file);
- }
- cmpImageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, false, new CompareTool.CmpPngFileFilter(this));
- foreach (String file in cmpImageFiles)
- {
- File.Delete(file);
- }
- diffFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, false, new CompareTool.DiffPngFileFilter(this, differenceImagePrefix
- ));
- foreach (String file in diffFiles)
- {
- File.Delete(file);
- }
- }
- }
-
- /// Runs ghostscript to create images of pdfs.
- /// Path to the output folder.
- /// Returns null if result is successful, else returns error message.
- ///
- ///
- private String RunGhostScriptImageGeneration(String outPath)
- {
- if (!FileUtil.DirectoryExists(outPath))
- {
- return cannotOpenOutputDirectory.Replace("", outPdf);
- }
- String currGsParams = gsParams.Replace("", outPath + cmpImage).Replace
- ("", cmpPdf);
- if (!RunProcessAndWait(gsExec, currGsParams))
- {
- return gsFailed.Replace("", cmpPdf);
- }
- currGsParams = gsParams.Replace("", outPath + outImage).Replace(""
- , outPdf);
- if (!RunProcessAndWait(gsExec, currGsParams))
- {
- return gsFailed.Replace("", outPdf);
- }
- return null;
- }
-
- ///
- ///
- private bool RunProcessAndWait(String execPath, String @params)
- {
- StringTokenizer st = new StringTokenizer(@params);
- String[] cmdArray = new String[st.CountTokens() + 1];
- cmdArray[0] = execPath;
- for (int i = 1; st.HasMoreTokens(); ++i)
- {
- cmdArray[i] = st.NextToken();
- }
- Process p = new Process();
- p.StartInfo = new ProcessStartInfo(execPath, @params);
- p.StartInfo.RedirectStandardOutput = true;
- p.StartInfo.RedirectStandardError = true;
- p.StartInfo.UseShellExecute = false;
- p.StartInfo.CreateNoWindow = true;
- p.Start();
-
- PrintProcessOutput(p);
- p.WaitForExit();
- return true;
- }
-
- ///
- private void PrintProcessOutput(Process p) {
- StringBuilder bri = new StringBuilder();
- StringBuilder bre = new StringBuilder();
- while (!p.HasExited) {
- bri.Append(p.StandardOutput.ReadToEnd());
- bre.Append(p.StandardError.ReadToEnd());
- }
- System.Console.Out.WriteLine(bri.ToString());
- System.Console.Out.WriteLine(bre.ToString());
- }
-
- ///
- ///
- private String CompareByContent(String outPath, String differenceImagePrefix, IDictionary
- > ignoredAreas)
- {
- return CompareByContent(outPath, differenceImagePrefix, ignoredAreas, null, null);
- }
-
- ///
- ///
- private String CompareByContent(String outPath, String differenceImagePrefix, IDictionary
- > ignoredAreas, byte[] outPass, byte[] cmpPass)
- {
- System.Console.Out.Write("[itext] INFO Comparing by content..........");
- PdfDocument outDocument;
- try
- {
- outDocument = new PdfDocument(new PdfReader(outPdf, new ReaderProperties().SetPassword
- (outPass)));
- }
- catch (System.IO.IOException e)
- {
- throw new System.IO.IOException("File \"" + outPdf + "\" not found", e);
- }
- IList outPages = new List();
- outPagesRef = new List();
- LoadPagesFromReader(outDocument, outPages, outPagesRef);
- PdfDocument cmpDocument;
- try
- {
- cmpDocument = new PdfDocument(new PdfReader(cmpPdf, new ReaderProperties().SetPassword
- (cmpPass)));
- }
- catch (System.IO.IOException e)
- {
- throw new System.IO.IOException("File \"" + cmpPdf + "\" not found", e);
- }
- IList cmpPages = new List();
- cmpPagesRef = new List();
- LoadPagesFromReader(cmpDocument, cmpPages, cmpPagesRef);
- if (outPages.Count != cmpPages.Count)
- {
- return CompareVisually(outPath, differenceImagePrefix, ignoredAreas);
- }
- CompareTool.CompareResult compareResult = new CompareTool.CompareResult(this, compareByContentErrorsLimit
- );
- IList equalPages = new List(cmpPages.Count);
- for (int i = 0; i < cmpPages.Count; i++)
- {
- CompareTool.ObjectPath currentPath = new CompareTool.ObjectPath(cmpPagesRef
- [i], outPagesRef[i]);
- if (CompareDictionariesExtended(outPages[i], cmpPages[i], currentPath, compareResult
- ))
- {
- equalPages.Add(i);
- }
- }
- CompareTool.ObjectPath catalogPath = new CompareTool.ObjectPath(cmpDocument
- .GetCatalog().GetPdfObject().GetIndirectReference(), outDocument.GetCatalog().GetPdfObject
- ().GetIndirectReference());
- ICollection ignoredCatalogEntries = new LinkedHashSet(iText.IO.Util.JavaUtil.ArraysAsList
- (PdfName.Pages, PdfName.Metadata));
- CompareDictionariesExtended(outDocument.GetCatalog().GetPdfObject(), cmpDocument.
- GetCatalog().GetPdfObject(), catalogPath, compareResult, ignoredCatalogEntries);
- if (encryptionCompareEnabled)
- {
- CompareDocumentsEncryption(outDocument, cmpDocument, compareResult);
- }
- outDocument.Close();
- cmpDocument.Close();
- if (generateCompareByContentXmlReport)
- {
- try
- {
- String filename = Path.GetFileName(outPdf);
- FileStream xml = new FileStream(outPath + "/" + filename.Substring(0, filename.Length - 3) + "report.xml",
- FileMode.Create
- );
- compareResult.WriteReportToXml(xml);
+ outImage = outPdfName + "-%03d.png";
+ if (cmpPdfName.StartsWith("cmp_")) {
+ cmpImage = cmpPdfName + "-%03d.png";
+ }
+ else {
+ cmpImage = "cmp_" + cmpPdfName + "-%03d.png";
+ }
+ }
+
+ private void SetPassword(byte[] outPass, byte[] cmpPass) {
+ if (outPass != null) {
+ GetOutReaderProperties().SetPassword(outPass);
+ }
+ if (cmpPass != null) {
+ GetCmpReaderProperties().SetPassword(outPass);
+ }
+ }
+
+ ///
+ ///
+ private String CompareVisually(String outPath, String differenceImagePrefix, IDictionary> ignoredAreas) {
+ return CompareVisually(outPath, differenceImagePrefix, ignoredAreas, null);
+ }
+
+ ///
+ ///
+ private String CompareVisually(String outPath, String differenceImagePrefix, IDictionary> ignoredAreas, IList equalPages) {
+ if (gsExec == null) {
+ return undefinedGsPath;
+ }
+ if (!(new FileInfo(gsExec).Exists)) {
+ return new FileInfo(gsExec).FullName + " does not exist";
+ }
+ if (!outPath.EndsWith("/")) {
+ outPath = outPath + "/";
+ }
+ PrepareOutputDirs(outPath, differenceImagePrefix);
+ if (ignoredAreas != null && !ignoredAreas.IsEmpty()) {
+ CreateIgnoredAreasPdfs(outPath, ignoredAreas);
+ }
+ String imagesGenerationResult = RunGhostScriptImageGeneration(outPath);
+ if (imagesGenerationResult != null) {
+ return imagesGenerationResult;
+ }
+ return CompareImagesOfPdfs(outPath, differenceImagePrefix, equalPages);
+ }
+
+ ///
+ ///
+ private String CompareImagesOfPdfs(String outPath, String differenceImagePrefix, IList equalPages) {
+ FileInfo[] imageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, new CompareTool.PngFileFilter(this)
+ );
+ FileInfo[] cmpImageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, new CompareTool.CmpPngFileFilter
+ (this));
+ bool bUnexpectedNumberOfPages = false;
+ if (imageFiles.Length != cmpImageFiles.Length) {
+ bUnexpectedNumberOfPages = true;
+ }
+ int cnt = Math.Min(imageFiles.Length, cmpImageFiles.Length);
+ if (cnt < 1) {
+ return "No files for comparing.\nThe result or sample pdf file is not processed by GhostScript.";
+ }
+ iText.IO.Util.JavaUtil.Sort(imageFiles, new CompareTool.ImageNameComparator(this));
+ iText.IO.Util.JavaUtil.Sort(cmpImageFiles, new CompareTool.ImageNameComparator(this));
+ String differentPagesFail = null;
+ bool compareExecIsOk = compareExec != null && new FileInfo(compareExec).Exists;
+ IList diffPages = new List();
+ for (int i = 0; i < cnt; i++) {
+ if (equalPages != null && equalPages.Contains(i)) {
+ continue;
+ }
+ System.Console.Out.Write("Comparing page " + iText.IO.Util.JavaUtil.IntegerToString(i + 1) + " (" + imageFiles
+ [i].FullName + ")...");
+ FileStream is1 = new FileStream(imageFiles[i].FullName, FileMode.Open, FileAccess.Read);
+ FileStream is2 = new FileStream(cmpImageFiles[i].FullName, FileMode.Open, FileAccess.Read);
+ bool cmpResult = CompareStreams(is1, is2);
+ is1.Close();
+ is2.Close();
+ if (!cmpResult) {
+ differentPagesFail = " Page is different!";
+ diffPages.Add(i + 1);
+ if (compareExecIsOk) {
+ String currCompareParams = compareParams.Replace("", imageFiles[i].FullName).Replace("", cmpImageFiles
+ [i].FullName).Replace("", outPath + differenceImagePrefix + iText.IO.Util.JavaUtil.IntegerToString
+ (i + 1) + ".png");
+ if (SystemUtil.RunProcessAndWait(compareExec, currCompareParams)) {
+ differentPagesFail += "\nPlease, examine " + outPath + differenceImagePrefix + iText.IO.Util.JavaUtil.IntegerToString
+ (i + 1) + ".png for more details.";
+ }
+ }
+ System.Console.Out.WriteLine(differentPagesFail);
+ }
+ else {
+ System.Console.Out.WriteLine(" done.");
+ }
+ }
+ if (differentPagesFail != null) {
+ String errorMessage = differentPages.Replace("", outPdf).Replace("", ListDiffPagesAsString
+ (diffPages));
+ if (!compareExecIsOk) {
+ errorMessage += "\nYou can optionally specify path to ImageMagick compare tool (e.g. -DcompareExec=\"C:/Program Files/ImageMagick-6.5.4-2/compare.exe\") to visualize differences.";
+ }
+ return errorMessage;
+ }
+ else {
+ if (bUnexpectedNumberOfPages) {
+ return unexpectedNumberOfPages.Replace("", outPdf);
+ }
+ }
+ return null;
+ }
+
+ private String ListDiffPagesAsString(IList diffPages) {
+ StringBuilder sb = new StringBuilder("[");
+ for (int i = 0; i < diffPages.Count; i++) {
+ sb.Append(diffPages[i]);
+ if (i < diffPages.Count - 1) {
+ sb.Append(", ");
+ }
+ }
+ sb.Append("]");
+ return sb.ToString();
+ }
+
+ ///
+ private void CreateIgnoredAreasPdfs(String outPath, IDictionary> ignoredAreas) {
+ PdfWriter outWriter = new PdfWriter(outPath + ignoredAreasPrefix + outPdfName);
+ PdfWriter cmpWriter = new PdfWriter(outPath + ignoredAreasPrefix + cmpPdfName);
+ PdfDocument pdfOutDoc = new PdfDocument(new PdfReader(outPdf), outWriter);
+ PdfDocument pdfCmpDoc = new PdfDocument(new PdfReader(cmpPdf), cmpWriter);
+ foreach (KeyValuePair> entry in ignoredAreas) {
+ int pageNumber = entry.Key;
+ IList rectangles = entry.Value;
+ if (rectangles != null && !rectangles.IsEmpty()) {
+ PdfCanvas outCanvas = new PdfCanvas(pdfOutDoc.GetPage(pageNumber));
+ PdfCanvas cmpCanvas = new PdfCanvas(pdfCmpDoc.GetPage(pageNumber));
+ outCanvas.SaveState();
+ cmpCanvas.SaveState();
+ foreach (Rectangle rect in rectangles) {
+ outCanvas.Rectangle(rect).Fill();
+ cmpCanvas.Rectangle(rect).Fill();
+ }
+ outCanvas.RestoreState();
+ cmpCanvas.RestoreState();
+ }
+ }
+ pdfOutDoc.Close();
+ pdfCmpDoc.Close();
+ Init(outPath + ignoredAreasPrefix + outPdfName, outPath + ignoredAreasPrefix + cmpPdfName);
+ }
+
+ private void PrepareOutputDirs(String outPath, String differenceImagePrefix) {
+ FileInfo[] imageFiles;
+ FileInfo[] cmpImageFiles;
+ FileInfo[] diffFiles;
+ if (!FileUtil.DirectoryExists(outPath)) {
+ FileUtil.CreateDirectories(outPath);
+ }
+ else {
+ imageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, new CompareTool.PngFileFilter(this));
+ foreach (FileInfo file in imageFiles) {
+ file.Delete();
+ }
+ cmpImageFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, new CompareTool.CmpPngFileFilter(this));
+ foreach (FileInfo file_1 in cmpImageFiles) {
+ file_1.Delete();
+ }
+ diffFiles = FileUtil.ListFilesInDirectoryByFilter(outPath, new CompareTool.DiffPngFileFilter(this, differenceImagePrefix
+ ));
+ foreach (FileInfo file_2 in diffFiles) {
+ file_2.Delete();
+ }
+ }
+ }
+
+ /// Runs ghostscript to create images of pdfs.
+ /// Path to the output folder.
+ /// Returns null if result is successful, else returns error message.
+ ///
+ ///
+ private String RunGhostScriptImageGeneration(String outPath) {
+ if (!FileUtil.DirectoryExists(outPath)) {
+ return cannotOpenOutputDirectory.Replace("", outPdf);
+ }
+ String currGsParams = gsParams.Replace("", outPath + cmpImage).Replace("