diff --git a/src/UglyToad.Pdf.Tests/Integration/FontSizeTestFromGoogleChromeTests.cs b/src/UglyToad.Pdf.Tests/Integration/FontSizeTestFromGoogleChromeTests.cs index 80cfdb1d..6ca321e7 100644 --- a/src/UglyToad.Pdf.Tests/Integration/FontSizeTestFromGoogleChromeTests.cs +++ b/src/UglyToad.Pdf.Tests/Integration/FontSizeTestFromGoogleChromeTests.cs @@ -3,6 +3,7 @@ using System; using System.IO; using System.Linq; + using Content; using Xunit; public class FontSizeTestFromGoogleChromeTests @@ -49,5 +50,16 @@ Assert.Equal("Hello, this is 16ptHello, this is 16px", text); } } + + [Fact] + public void GetsCorrectPageSize() + { + using (var document = PdfDocument.Open(GetFilename())) + { + var page = document.GetPage(1); + + Assert.Equal(PageSize.A4, page.Size); + } + } } } diff --git a/src/UglyToad.Pdf.Tests/Integration/SinglePageSimpleTests.cs b/src/UglyToad.Pdf.Tests/Integration/SinglePageSimpleTests.cs index de7d2c9f..e825aad1 100644 --- a/src/UglyToad.Pdf.Tests/Integration/SinglePageSimpleTests.cs +++ b/src/UglyToad.Pdf.Tests/Integration/SinglePageSimpleTests.cs @@ -5,6 +5,7 @@ namespace UglyToad.Pdf.Tests.Integration using System.Collections.Generic; using System.IO; using System.Linq; + using Content; using Xunit; public class SinglePageSimpleTests @@ -92,6 +93,17 @@ namespace UglyToad.Pdf.Tests.Integration } } + [Fact] + public void GetsCorrectPageSize() + { + using (var document = PdfDocument.Open(GetFilename())) + { + var page = document.GetPage(1); + + Assert.Equal(PageSize.Letter, page.Size); + } + } + [Fact] public void LettersHavePdfBoxPositions() { diff --git a/src/UglyToad.Pdf.Tests/Parser/Parts/CrossReference/CrossReferenceTableParserTests.cs b/src/UglyToad.Pdf.Tests/Parser/Parts/CrossReference/CrossReferenceTableParserTests.cs index 5f3e8188..195dc99c 100644 --- a/src/UglyToad.Pdf.Tests/Parser/Parts/CrossReference/CrossReferenceTableParserTests.cs +++ b/src/UglyToad.Pdf.Tests/Parser/Parts/CrossReference/CrossReferenceTableParserTests.cs @@ -1,5 +1,6 @@ namespace UglyToad.Pdf.Tests.Parser.Parts.CrossReference { + using System; using System.Linq; using IO; using Pdf.Cos; @@ -228,6 +229,51 @@ trailer Assert.Equal(32, results[4].Generation); } + [Fact] + public void EntryPointingAtOffsetInTableThrows() + { + var input = GetReader(@"xref +0 2 +0000000000 65535 f +0000000010 00000 n +trailer +<<>>"); + + Action action = () => parser.TryParse(input, 0, false, objectPool, out var _); + + Assert.Throws(action); + } + + [Fact] + public void EntryWithInvalidFormatThrows() + { + var input = GetReader(@"xref +0 22 +0000000000 65535 f +0000aa0010 00000 n +trailer +<<>>"); + + Action action = () => parser.TryParse(input, 0, false, objectPool, out var _); + + Assert.Throws(action); + } + + [Fact] + public void ShortLineInTableReturnsFalse() + { + var input = GetReader(@"xref +15 2 +000000019000000 n +0000000250 00032 n +trailer +<<>>"); + + var result = parser.TryParse(input, 0, false, objectPool, out var table); + + Assert.False(result); + } + private static IRandomAccessRead GetReader(string input) { return new RandomAccessBuffer(OtherEncodings.StringAsLatin1Bytes(input)); diff --git a/src/UglyToad.Pdf/Content/Page.cs b/src/UglyToad.Pdf/Content/Page.cs index 133f0395..b2621ac0 100644 --- a/src/UglyToad.Pdf/Content/Page.cs +++ b/src/UglyToad.Pdf/Content/Page.cs @@ -6,7 +6,7 @@ public class Page { /// - /// The 1 indexed page number. + /// The page number (starting at 1). /// public int Number { get; } @@ -28,6 +28,11 @@ /// public decimal Height { get; } + /// + /// The size of the page according to the standard page sizes or Custom if no matching standard size found. + /// + public PageSize Size { get; } + internal Page(int number, MediaBox mediaBox, CropBox cropBox, PageContent content) { if (number <= 0) @@ -42,6 +47,8 @@ Width = mediaBox.Bounds.Width; Height = mediaBox.Bounds.Height; + + Size = mediaBox.Bounds.GetPageSize(); } } } \ No newline at end of file diff --git a/src/UglyToad.Pdf/Content/PageSize.cs b/src/UglyToad.Pdf/Content/PageSize.cs new file mode 100644 index 00000000..b91eff73 --- /dev/null +++ b/src/UglyToad.Pdf/Content/PageSize.cs @@ -0,0 +1,93 @@ +namespace UglyToad.Pdf.Content +{ + using System.Collections.Generic; + using Geometry; + + public enum PageSize + { + Custom = 0, + A0 = 3, + A1 = 4, + A2 = 5, + A3 = 6, + A4 = 7, + A5 = 8, + A6 = 9, + A7 = 10, + A8 = 11, + A9 = 12, + A10 = 13, + Letter = 14, + Legal = 15, + Ledger = 16, + Tabloid = 17, + Executive = 18 + } + + internal static class PageSizeExtensions + { + private static readonly Dictionary Lookup = new Dictionary + { + {new WidthHeight(2384, 3370), PageSize.A0}, + {new WidthHeight(1684, 2384), PageSize.A1}, + // Seems there is some disagreement 1190/1191 + {new WidthHeight(1190, 1684), PageSize.A2}, + {new WidthHeight(1191, 1684), PageSize.A2}, + // Seems there is some disagreement 1190/1191 + {new WidthHeight(842, 1190), PageSize.A3}, + {new WidthHeight(842, 1191), PageSize.A3}, + {new WidthHeight(595, 842), PageSize.A4}, + {new WidthHeight(420, 595), PageSize.A5}, + {new WidthHeight(298, 420), PageSize.A6}, + {new WidthHeight(210, 298), PageSize.A7}, + {new WidthHeight(147, 210), PageSize.A8}, + {new WidthHeight(105, 147), PageSize.A9}, + {new WidthHeight(74, 105), PageSize.A10}, + {new WidthHeight(612, 792), PageSize.Letter}, + {new WidthHeight(612, 1008), PageSize.Legal}, + {new WidthHeight(1224, 792), PageSize.Ledger}, + {new WidthHeight(792, 1224), PageSize.Tabloid}, + // Again there is disagreement here + {new WidthHeight(540, 720), PageSize.Executive}, + {new WidthHeight(522, 756), PageSize.Executive}, + }; + + public static PageSize GetPageSize(this PdfRectangle rectangle) + { + if (!Lookup.TryGetValue(new WidthHeight(rectangle.Width, rectangle.Height), out var size)) + { + return PageSize.Custom; + } + + return size; + } + + private struct WidthHeight + { + public decimal Width { get; } + + public decimal Height { get; } + + public WidthHeight(decimal width, decimal height) + { + Width = width; + Height = height; + } + + public override bool Equals(object obj) + { + return obj is WidthHeight height && + Width == height.Width && + Height == height.Height; + } + + public override int GetHashCode() + { + var hashCode = 859600377; + hashCode = hashCode * -1521134295 + Width.GetHashCode(); + hashCode = hashCode * -1521134295 + Height.GetHashCode(); + return hashCode; + } + } + } +}