From f3e37eafae4ec3e008b15704941ad0dfb928237c Mon Sep 17 00:00:00 2001 From: davebrokit <87085235+davebrokit@users.noreply.github.com> Date: Sat, 28 Feb 2026 16:25:51 +0000 Subject: [PATCH] Introduce IBlock and ILettersBlock interfaces (Round 2) (#1263) * Code review changes - Keep the Bounds property on the image classes so this isn't a major breaking API change - Don't expose letters collection * Minor fix * Switch to using BoundingBox in the library --------- Co-authored-by: davmarksman --- .../DuplicateOverlappingTextProcessor.cs | 18 ++++---- .../Export/AltoXmlTextExporter.cs | 10 ++--- .../Export/HOcrTextExporter.cs | 2 +- .../Export/PageXmlTextExporter.cs | 4 +- .../Export/SvgTextExporter.cs | 6 +-- .../PageSegmenter/RecursiveXYCut.cs | 4 +- .../TextBlock.cs | 2 +- .../ContentOrderTextExtractor.cs | 2 +- .../TextLine.cs | 2 +- .../WhitespaceCoverExtractor.cs | 6 +-- .../NearestNeighbourWordExtractor.cs | 4 +- .../Fonts/SystemFonts/Linux.cs | 14 +++---- .../Fonts/Type1/Type1CharStringParserTests.cs | 8 ++-- .../Integration/AssertablePositionData.cs | 2 +- .../Integration/EncodingsTests.cs | 2 +- .../Integration/GithubIssuesTests.cs | 2 +- .../Integration/IntegrationDocumentTests.cs | 2 +- .../Integration/LaTexTests.cs | 2 +- .../Integration/RotationAndCroppingTests.cs | 4 +- .../SinglePageLibreOfficeImages.cs | 26 ++++++------ .../SinglePageSimpleOpenOfficeTests.cs | 24 +++++------ .../Integration/Type0FontTests.cs | 4 +- .../Integration/Type3FontTests.cs | 4 +- .../GenerateLetterBoundingBoxImages.cs | 2 +- .../GenerateLetterGlyphImages.cs | 2 +- .../PublicApiScannerTests.cs | 1 + src/UglyToad.PdfPig.Tests/TestPdfImage.cs | 3 +- .../Fonts/Standard14WritingFontTests.cs | 36 ++++++++-------- .../Writer/PdfDocumentBuilderTests.cs | 42 +++++++++---------- src/UglyToad.PdfPig/Content/IBoundingBox.cs | 15 +++++++ src/UglyToad.PdfPig/Content/IPdfImage.cs | 4 +- src/UglyToad.PdfPig/Content/InlineImage.cs | 10 +++-- src/UglyToad.PdfPig/Content/Letter.cs | 18 +++++--- src/UglyToad.PdfPig/Content/Word.cs | 32 +++++++------- .../Graphics/ContentStreamProcessor.cs | 2 +- .../Util/DefaultWordExtractor.cs | 2 +- src/UglyToad.PdfPig/XObjects/XObjectImage.cs | 11 +++-- 37 files changed, 184 insertions(+), 150 deletions(-) create mode 100644 src/UglyToad.PdfPig/Content/IBoundingBox.cs diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs index f26b48b9..1fbdf857 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs @@ -35,20 +35,20 @@ var key = (letter.Value, letter.FontName); if (duplicateIndex.TryGetValue(key, out var candidateIndices)) { - double tolerance = letter.GlyphRectangle.Width / (letter.Value.Length == 0 ? 1 : letter.Value.Length) / 3.0; - double minX = letter.GlyphRectangle.BottomLeft.X - tolerance; - double maxX = letter.GlyphRectangle.BottomLeft.X + tolerance; - double minY = letter.GlyphRectangle.BottomLeft.Y - tolerance; - double maxY = letter.GlyphRectangle.BottomLeft.Y + tolerance; + double tolerance = letter.BoundingBox.Width / (letter.Value.Length == 0 ? 1 : letter.Value.Length) / 3.0; + double minX = letter.BoundingBox.BottomLeft.X - tolerance; + double maxX = letter.BoundingBox.BottomLeft.X + tolerance; + double minY = letter.BoundingBox.BottomLeft.Y - tolerance; + double maxY = letter.BoundingBox.BottomLeft.Y + tolerance; for (int ci = 0; ci < candidateIndices.Count; ci++) { int idx = candidateIndices[ci]; var l = cleanLetters[idx]; - if (minX <= l.GlyphRectangle.BottomLeft.X && - maxX >= l.GlyphRectangle.BottomLeft.X && - minY <= l.GlyphRectangle.BottomLeft.Y && - maxY >= l.GlyphRectangle.BottomLeft.Y) + if (minX <= l.BoundingBox.BottomLeft.X && + maxX >= l.BoundingBox.BottomLeft.X && + minY <= l.BoundingBox.BottomLeft.Y && + maxY >= l.BoundingBox.BottomLeft.Y) { addLetter = false; duplicatesOverlappingIndex = idx; diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/AltoXmlTextExporter.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/AltoXmlTextExporter.cs index 62a86d69..511fc598 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/AltoXmlTextExporter.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/AltoXmlTextExporter.cs @@ -229,7 +229,7 @@ private AltoDocument.AltoIllustration ToAltoIllustration(IPdfImage pdfImage, double height) { illustrationCount++; - var rectangle = pdfImage.Bounds; + var rectangle = pdfImage.BoundingBox; return new AltoDocument.AltoIllustration { @@ -311,10 +311,10 @@ glyphCount++; return new AltoDocument.AltoGlyph { - VerticalPosition = (float)Math.Round((height - letter.GlyphRectangle.Top) * scale), - HorizontalPosition = (float)Math.Round(letter.GlyphRectangle.Left * scale), - Height = (float)Math.Round(letter.GlyphRectangle.Height * scale), - Width = (float)Math.Round(letter.GlyphRectangle.Width * scale), + VerticalPosition = (float)Math.Round((height - letter.BoundingBox.Top) * scale), + HorizontalPosition = (float)Math.Round(letter.BoundingBox.Left * scale), + Height = (float)Math.Round(letter.BoundingBox.Height * scale), + Width = (float)Math.Round(letter.BoundingBox.Width * scale), Gc = 1.0f, Content = invalidCharacterHandler(letter.Value), Id = "P" + pageCount + "_ST" + stringCount.ToString("#00000") + "_G" + glyphCount.ToString("#00") diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/HOcrTextExporter.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/HOcrTextExporter.cs index 3441ac8c..9c8dc3e6 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/HOcrTextExporter.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/HOcrTextExporter.cs @@ -277,7 +277,7 @@ private string GetCode(IPdfImage pdfImage, double pageHeight, int level) { imageCount++; - var bbox = pdfImage.Bounds; + var bbox = pdfImage.BoundingBox; return GetIndent(level) + ""; } diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/PageXmlTextExporter.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/PageXmlTextExporter.cs index 7297143a..c07a8a9a 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/PageXmlTextExporter.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/PageXmlTextExporter.cs @@ -280,7 +280,7 @@ private PageXmlDocument.PageXmlImageRegion ToPageXmlImageRegion(IPdfImage pdfImage, PageXmlData data, double pageWidth, double pageHeight) { data.RegionsCount++; - var bbox = pdfImage.Bounds; + var bbox = pdfImage.BoundingBox; return new PageXmlDocument.PageXmlImageRegion() { Coords = ToCoords(bbox, pageWidth, pageHeight), @@ -360,7 +360,7 @@ data.GlyphsCount++; return new PageXmlDocument.PageXmlGlyph() { - Coords = ToCoords(letter.GlyphRectangle, pageWidth, pageHeight), + Coords = ToCoords(letter.BoundingBox, pageWidth, pageHeight), Ligature = false, Production = PageXmlDocument.PageXmlProductionSimpleType.Printed, TextStyle = new PageXmlDocument.PageXmlTextStyle() diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/SvgTextExporter.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/SvgTextExporter.cs index 1c5ac654..2f68fbaa 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/SvgTextExporter.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/Export/SvgTextExporter.cs @@ -96,12 +96,12 @@ { string fontFamily = GetFontFamily(l.FontName, out string style, out string weight); string rotation = ""; - if (l.GlyphRectangle.Rotation != 0) + if (l.BoundingBox.Rotation != 0) { - rotation = $" transform='rotate({Math.Round(-l.GlyphRectangle.Rotation, Rounding)} {Math.Round(l.GlyphRectangle.BottomLeft.X, Rounding)},{Math.Round(height - l.GlyphRectangle.TopLeft.Y, Rounding)})'"; + rotation = $" transform='rotate({Math.Round(-l.BoundingBox.Rotation, Rounding)} {Math.Round(l.BoundingBox.BottomLeft.X, Rounding)},{Math.Round(height - l.BoundingBox.TopLeft.Y, Rounding)})'"; } - string fontSize = l.FontSize != 1 ? $"font-size='{l.FontSize:0}'" : $"style='font-size:{Math.Round(l.GlyphRectangle.Height, 2)}px'"; + string fontSize = l.FontSize != 1 ? $"font-size='{l.FontSize:0}'" : $"style='font-size:{Math.Round(l.BoundingBox.Height, 2)}px'"; var safeValue = XmlEscape(l, doc); var x = Math.Round(l.StartBaseLine.X, Rounding); diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/PageSegmenter/RecursiveXYCut.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/PageSegmenter/RecursiveXYCut.cs index 7c30b34e..05fb82c5 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/PageSegmenter/RecursiveXYCut.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/PageSegmenter/RecursiveXYCut.cs @@ -372,7 +372,7 @@ public Func, double> DominantFontWidthFunc { get; set; } = (letters) => { - var widths = letters.Select(x => Math.Max(Math.Round(x.Width, 3), Math.Round(x.GlyphRectangle.Width, 3))); + var widths = letters.Select(x => Math.Max(Math.Round(x.Width, 3), Math.Round(x.BoundingBox.Width, 3))); var mode = widths.Mode(); if (double.IsNaN(mode) || mode == 0) { @@ -389,7 +389,7 @@ public Func, double> DominantFontHeightFunc { get; set; } = (letters) => { - var heights = letters.Select(x => Math.Round(x.GlyphRectangle.Height, 3)); + var heights = letters.Select(x => Math.Round(x.BoundingBox.Height, 3)); var mode = heights.Mode(); if (double.IsNaN(mode) || mode == 0) { diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextBlock.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextBlock.cs index eb7bf75b..4f15c446 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextBlock.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextBlock.cs @@ -9,7 +9,7 @@ /// /// A block of text. /// - public class TextBlock + public class TextBlock: IBoundingBox { /// /// The separator used between lines in the block. diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs index 6b61c80e..e98f89c6 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs @@ -59,7 +59,7 @@ { letter = new Letter( " ", - letter.GlyphRectangle, + letter.BoundingBox, letter.GlyphRectangleLoose, letter.StartBaseLine, letter.EndBaseLine, diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextLine.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextLine.cs index 322780f3..877c96a2 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextLine.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextLine.cs @@ -9,7 +9,7 @@ /// /// A line of text. /// - public class TextLine + public class TextLine : IBoundingBox { /// /// The separator used between words in the line. diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WhitespaceCoverExtractor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WhitespaceCoverExtractor.cs index 395780ed..e1ecdf49 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WhitespaceCoverExtractor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WhitespaceCoverExtractor.cs @@ -25,8 +25,8 @@ { return GetWhitespaces(words, images, - words.SelectMany(w => w.Letters).Select(x => x.GlyphRectangle.Width).Mode() * 1.25, - words.SelectMany(w => w.Letters).Select(x => x.GlyphRectangle.Height).Mode() * 1.25, + words.SelectMany(w => w.Letters).Select(x => x.BoundingBox.Width).Mode() * 1.25, + words.SelectMany(w => w.Letters).Select(x => x.BoundingBox.Height).Mode() * 1.25, maxRectangleCount: maxRectangleCount, maxBoundQueueSize: maxBoundQueueSize); } @@ -51,7 +51,7 @@ if (images?.Any() == true) { - bboxes.AddRange(images.Where(w => w.Bounds.Width > 0 && w.Bounds.Height > 0).Select(o => o.Bounds)); + bboxes.AddRange(images.Where(w => w.BoundingBox.Width > 0 && w.BoundingBox.Height > 0).Select(o => o.BoundingBox)); } return GetWhitespaces(bboxes, diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WordExtractor/NearestNeighbourWordExtractor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WordExtractor/NearestNeighbourWordExtractor.cs index 4e0ce710..949b04a6 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WordExtractor/NearestNeighbourWordExtractor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/WordExtractor/NearestNeighbourWordExtractor.cs @@ -163,8 +163,8 @@ public Func MaximumDistance { get; set; } = (l1, l2) => { double maxDist = Math.Max(Math.Max(Math.Max(Math.Max(Math.Max( - Math.Abs(l1.GlyphRectangle.Width), - Math.Abs(l2.GlyphRectangle.Width)), + Math.Abs(l1.BoundingBox.Width), + Math.Abs(l2.BoundingBox.Width)), Math.Abs(l1.Width)), Math.Abs(l2.Width)), l1.PointSize), l2.PointSize) * 0.2; diff --git a/src/UglyToad.PdfPig.Tests/Fonts/SystemFonts/Linux.cs b/src/UglyToad.PdfPig.Tests/Fonts/SystemFonts/Linux.cs index 105c2f43..fc5b44d0 100644 --- a/src/UglyToad.PdfPig.Tests/Fonts/SystemFonts/Linux.cs +++ b/src/UglyToad.PdfPig.Tests/Fonts/SystemFonts/Linux.cs @@ -65,14 +65,14 @@ namespace UglyToad.PdfPig.Tests.Fonts.SystemFonts var current = page.Letters[i]; - Assert.Equal(expectedData.TopLeft.X, current.GlyphRectangle.TopLeft.X, 6); - Assert.Equal(expectedData.TopLeft.Y, current.GlyphRectangle.TopLeft.Y, 6); - Assert.Equal(expectedData.Width, current.GlyphRectangle.Width, 6); - Assert.Equal(expectedData.Height, current.GlyphRectangle.Height, 6); - Assert.Equal(expectedData.Rotation, current.GlyphRectangle.Rotation, 3); + Assert.Equal(expectedData.TopLeft.X, current.BoundingBox.TopLeft.X, 6); + Assert.Equal(expectedData.TopLeft.Y, current.BoundingBox.TopLeft.Y, 6); + Assert.Equal(expectedData.Width, current.BoundingBox.Width, 6); + Assert.Equal(expectedData.Height, current.BoundingBox.Height, 6); + Assert.Equal(expectedData.Rotation, current.BoundingBox.Rotation, 3); - Assert.True(current.GlyphRectangle.IntersectsWith(current.GlyphRectangleLoose)); - Assert.Equal(current.GlyphRectangle.Rotation, current.GlyphRectangleLoose.Rotation, 3); + Assert.True(current.BoundingBox.IntersectsWith(current.GlyphRectangleLoose)); + Assert.Equal(current.BoundingBox.Rotation, current.GlyphRectangleLoose.Rotation, 3); } } } diff --git a/src/UglyToad.PdfPig.Tests/Fonts/Type1/Type1CharStringParserTests.cs b/src/UglyToad.PdfPig.Tests/Fonts/Type1/Type1CharStringParserTests.cs index 4f80590e..d43c6e43 100644 --- a/src/UglyToad.PdfPig.Tests/Fonts/Type1/Type1CharStringParserTests.cs +++ b/src/UglyToad.PdfPig.Tests/Fonts/Type1/Type1CharStringParserTests.cs @@ -20,14 +20,14 @@ // check 'm' var m = letters[0]; Assert.Equal("m", m.Value); - Assert.Equal(new PdfPoint(253.4458, 658.431), m.GlyphRectangle.BottomLeft, pointComparer); - Assert.Equal(new PdfPoint(261.22659, 662.83446), m.GlyphRectangle.TopRight, pointComparer); + Assert.Equal(new PdfPoint(253.4458, 658.431), m.BoundingBox.BottomLeft, pointComparer); + Assert.Equal(new PdfPoint(261.22659, 662.83446), m.BoundingBox.TopRight, pointComparer); // check 'p' var p = letters[1]; Assert.Equal("p", p.Value); - Assert.Equal(new PdfPoint(261.70778, 656.49825), p.GlyphRectangle.BottomLeft, pointComparer); - Assert.Equal(new PdfPoint(266.6193, 662.83446), p.GlyphRectangle.TopRight, pointComparer); + Assert.Equal(new PdfPoint(261.70778, 656.49825), p.BoundingBox.BottomLeft, pointComparer); + Assert.Equal(new PdfPoint(266.6193, 662.83446), p.BoundingBox.TopRight, pointComparer); } } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/AssertablePositionData.cs b/src/UglyToad.PdfPig.Tests/Integration/AssertablePositionData.cs index c7e8beb5..c152b1f2 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/AssertablePositionData.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/AssertablePositionData.cs @@ -50,7 +50,7 @@ Assert.Equal(Width, letter.Width, 1); if (includeHeight) { - Assert.Equal(Height, letter.GlyphRectangle.Height, 1); + Assert.Equal(Height, letter.BoundingBox.Height, 1); } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/EncodingsTests.cs b/src/UglyToad.PdfPig.Tests/Integration/EncodingsTests.cs index a8dd79a3..d5dc9364 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/EncodingsTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/EncodingsTests.cs @@ -33,7 +33,7 @@ var rect = new PdfRectangle(207, 158, 229, 168.5); - var missingChars = letters.Where(l => rect.Contains(l.GlyphRectangle)).ToArray(); + var missingChars = letters.Where(l => rect.Contains(l.BoundingBox)).ToArray(); Assert.NotEmpty(missingChars); Assert.True(missingChars.Length == 2); diff --git a/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs b/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs index 4c5a17b2..2dbda020 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/GithubIssuesTests.cs @@ -758,7 +758,7 @@ { var letter = page1.Letters[l]; Assert.Equal(TextOrientation.Other, letter.TextOrientation); - Assert.Equal(45.0, letter.GlyphRectangle.Rotation, 5); + Assert.Equal(45.0, letter.BoundingBox.Rotation, 5); } var page2 = document.GetPage(2); diff --git a/src/UglyToad.PdfPig.Tests/Integration/IntegrationDocumentTests.cs b/src/UglyToad.PdfPig.Tests/Integration/IntegrationDocumentTests.cs index 45a6521d..2675fdbe 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/IntegrationDocumentTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/IntegrationDocumentTests.cs @@ -28,7 +28,7 @@ var page = document.GetPage(i + 1); foreach (var letter in page.Letters) { - var bbox = letter.GlyphRectangle; + var bbox = letter.BoundingBox; if (bbox.Height > 0) { if (letter.GlyphRectangleLoose.Height <= 0) diff --git a/src/UglyToad.PdfPig.Tests/Integration/LaTexTests.cs b/src/UglyToad.PdfPig.Tests/Integration/LaTexTests.cs index 4b10cd4e..7e1f8269 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/LaTexTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/LaTexTests.cs @@ -34,7 +34,7 @@ namespace UglyToad.PdfPig.Tests.Integration { var page = document.GetPage(1); - Assert.NotEqual(0, page.Letters[0].GlyphRectangle.Height); + Assert.NotEqual(0, page.Letters[0].BoundingBox.Height); } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/RotationAndCroppingTests.cs b/src/UglyToad.PdfPig.Tests/Integration/RotationAndCroppingTests.cs index 8af80f3f..39c68b49 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/RotationAndCroppingTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/RotationAndCroppingTests.cs @@ -12,8 +12,8 @@ var page = document.GetPage(1); Assert.Equal(612, page.Width); // Due to cropping Assert.Equal(792, page.Height); // Due to cropping - var minX = page.Letters.Select(l => l.GlyphRectangle.Left).Min(); - var maxX = page.Letters.Select(l => l.GlyphRectangle.Right).Max(); + var minX = page.Letters.Select(l => l.BoundingBox.Left).Min(); + var maxX = page.Letters.Select(l => l.BoundingBox.Right).Max(); Assert.Equal(74, minX, 0); // If cropping is not applied correctly, these values will be off Assert.Equal(540, maxX, 0); // If cropping is not applied correctly, these values will be off // The page is cropped at diff --git a/src/UglyToad.PdfPig.Tests/Integration/SinglePageLibreOfficeImages.cs b/src/UglyToad.PdfPig.Tests/Integration/SinglePageLibreOfficeImages.cs index 2a8b253f..8b9b87a5 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/SinglePageLibreOfficeImages.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/SinglePageLibreOfficeImages.cs @@ -47,29 +47,29 @@ { var page = document.GetPage(1); - var images = page.GetImages().OrderBy(x => x.Bounds.Width).ToList(); + var images = page.GetImages().OrderBy(x => x.BoundingBox.Width).ToList(); var pdfPigSquare = images[0]; - Assert.Equal(148.3d, pdfPigSquare.Bounds.Width, doubleComparer); - Assert.Equal(148.3d, pdfPigSquare.Bounds.Height, doubleComparer); - Assert.Equal(60.1d, pdfPigSquare.Bounds.Left, doubleComparer); - Assert.Equal(765.8d, pdfPigSquare.Bounds.Top, doubleComparer); + Assert.Equal(148.3d, pdfPigSquare.BoundingBox.Width, doubleComparer); + Assert.Equal(148.3d, pdfPigSquare.BoundingBox.Height, doubleComparer); + Assert.Equal(60.1d, pdfPigSquare.BoundingBox.Left, doubleComparer); + Assert.Equal(765.8d, pdfPigSquare.BoundingBox.Top, doubleComparer); var pdfPigSquished = images[1]; - Assert.Equal(206.8d, pdfPigSquished.Bounds.Width, doubleComparer); - Assert.Equal(83.2d, pdfPigSquished.Bounds.Height, doubleComparer); - Assert.Equal(309.8d, pdfPigSquished.Bounds.Left, doubleComparer); - Assert.Equal(552.1d, pdfPigSquished.Bounds.Top, doubleComparer); + Assert.Equal(206.8d, pdfPigSquished.BoundingBox.Width, doubleComparer); + Assert.Equal(83.2d, pdfPigSquished.BoundingBox.Height, doubleComparer); + Assert.Equal(309.8d, pdfPigSquished.BoundingBox.Left, doubleComparer); + Assert.Equal(552.1d, pdfPigSquished.BoundingBox.Top, doubleComparer); var birthdayPigs = images[2]; - Assert.Equal(391d, birthdayPigs.Bounds.Width, doubleComparer); - Assert.Equal(267.1d, birthdayPigs.Bounds.Height, doubleComparer); - Assert.Equal(102.2d, birthdayPigs.Bounds.Left, doubleComparer); - Assert.Equal(426.3d, birthdayPigs.Bounds.Top, doubleComparer); + Assert.Equal(391d, birthdayPigs.BoundingBox.Width, doubleComparer); + Assert.Equal(267.1d, birthdayPigs.BoundingBox.Height, doubleComparer); + Assert.Equal(102.2d, birthdayPigs.BoundingBox.Left, doubleComparer); + Assert.Equal(426.3d, birthdayPigs.BoundingBox.Top, doubleComparer); } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/SinglePageSimpleOpenOfficeTests.cs b/src/UglyToad.PdfPig.Tests/Integration/SinglePageSimpleOpenOfficeTests.cs index 9ca05f4e..dc568711 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/SinglePageSimpleOpenOfficeTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/SinglePageSimpleOpenOfficeTests.cs @@ -42,27 +42,27 @@ Assert.Equal("I", page.Letters[0].Value); - Assert.Equal(90.1d, page.Letters[0].GlyphRectangle.BottomLeft.X, comparer); - Assert.Equal(709.2d, page.Letters[0].GlyphRectangle.BottomLeft.Y, comparer); + Assert.Equal(90.1d, page.Letters[0].BoundingBox.BottomLeft.X, comparer); + Assert.Equal(709.2d, page.Letters[0].BoundingBox.BottomLeft.Y, comparer); - Assert.Equal(94.0d, page.Letters[0].GlyphRectangle.TopRight.X, comparer); - Assert.Equal(719.89d, page.Letters[0].GlyphRectangle.TopRight.Y, comparer); + Assert.Equal(94.0d, page.Letters[0].BoundingBox.TopRight.X, comparer); + Assert.Equal(719.89d, page.Letters[0].BoundingBox.TopRight.Y, comparer); Assert.Equal("a", page.Letters[5].Value); - Assert.Equal(114.5d, page.Letters[5].GlyphRectangle.BottomLeft.X, comparer); - Assert.Equal(709.2d, page.Letters[5].GlyphRectangle.BottomLeft.Y, comparer); + Assert.Equal(114.5d, page.Letters[5].BoundingBox.BottomLeft.X, comparer); + Assert.Equal(709.2d, page.Letters[5].BoundingBox.BottomLeft.Y, comparer); - Assert.Equal(119.82d, page.Letters[5].GlyphRectangle.TopRight.X, comparer); - Assert.Equal(714.89d, page.Letters[5].GlyphRectangle.TopRight.Y, comparer); + Assert.Equal(119.82d, page.Letters[5].BoundingBox.TopRight.X, comparer); + Assert.Equal(714.89d, page.Letters[5].BoundingBox.TopRight.Y, comparer); Assert.Equal("f", page.Letters[16].Value); - Assert.Equal(169.9d, page.Letters[16].GlyphRectangle.BottomLeft.X, comparer); - Assert.Equal(709.2d, page.Letters[16].GlyphRectangle.BottomLeft.Y, comparer); + Assert.Equal(169.9d, page.Letters[16].BoundingBox.BottomLeft.X, comparer); + Assert.Equal(709.2d, page.Letters[16].BoundingBox.BottomLeft.Y, comparer); - Assert.Equal(176.89d, page.Letters[16].GlyphRectangle.TopRight.X, comparer); - Assert.Equal(719.89d, page.Letters[16].GlyphRectangle.TopRight.Y, comparer); + Assert.Equal(176.89d, page.Letters[16].BoundingBox.TopRight.X, comparer); + Assert.Equal(719.89d, page.Letters[16].BoundingBox.TopRight.Y, comparer); } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/Type0FontTests.cs b/src/UglyToad.PdfPig.Tests/Integration/Type0FontTests.cs index f5bdd3b4..fedf3c1f 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/Type0FontTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/Type0FontTests.cs @@ -51,8 +51,8 @@ namespace UglyToad.PdfPig.Tests.Integration { var page = document.GetPage(1); - Assert.Contains(page.Letters, x => x.GlyphRectangle.Width != 0); - Assert.Contains(page.Letters, x => x.GlyphRectangle.Height != 0); + Assert.Contains(page.Letters, x => x.BoundingBox.Width != 0); + Assert.Contains(page.Letters, x => x.BoundingBox.Height != 0); Assert.Contains(page.Letters, x => x.GlyphRectangleLoose.Width != 0); Assert.Contains(page.Letters, x => x.GlyphRectangleLoose.Height != 0); } diff --git a/src/UglyToad.PdfPig.Tests/Integration/Type3FontTests.cs b/src/UglyToad.PdfPig.Tests/Integration/Type3FontTests.cs index e13e148d..d87d9557 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/Type3FontTests.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/Type3FontTests.cs @@ -14,8 +14,8 @@ namespace UglyToad.PdfPig.Tests.Integration { var page = document.GetPage(1); - Assert.Contains(page.Letters, x => x.GlyphRectangle.Width != 0); - Assert.Contains(page.Letters, x => x.GlyphRectangle.Height != 0); + Assert.Contains(page.Letters, x => x.BoundingBox.Width != 0); + Assert.Contains(page.Letters, x => x.BoundingBox.Height != 0); } } } diff --git a/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterBoundingBoxImages.cs b/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterBoundingBoxImages.cs index 7953c946..a0632f0e 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterBoundingBoxImages.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterBoundingBoxImages.cs @@ -175,7 +175,7 @@ foreach (var letter in page.Letters) { - DrawRectangle(letter.GlyphRectangle, graphics, violetPen, imageHeight, scale); + DrawRectangle(letter.BoundingBox, graphics, violetPen, imageHeight, scale); } foreach (var annotation in page.GetAnnotations()) diff --git a/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterGlyphImages.cs b/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterGlyphImages.cs index 763c097e..eefcb5da 100644 --- a/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterGlyphImages.cs +++ b/src/UglyToad.PdfPig.Tests/Integration/VisualVerification/GenerateLetterGlyphImages.cs @@ -72,7 +72,7 @@ { foreach (var letter in page.Letters) { - DrawRectangle(letter.GlyphRectangle, canvas, redPaint, size.Height, Scale); + DrawRectangle(letter.BoundingBox, canvas, redPaint, size.Height, Scale); } } diff --git a/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs index a649b6e7..292c1b25 100644 --- a/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs +++ b/src/UglyToad.PdfPig.Tests/PublicApiScannerTests.cs @@ -77,6 +77,7 @@ "UglyToad.PdfPig.Content.DocumentInformation", "UglyToad.PdfPig.Content.EmbeddedFile", "UglyToad.PdfPig.Content.Hyperlink", + "UglyToad.PdfPig.Content.IBoundingBox", "UglyToad.PdfPig.Content.InlineImage", "UglyToad.PdfPig.Content.IPageFactory`1", "UglyToad.PdfPig.Content.IPdfImage", diff --git a/src/UglyToad.PdfPig.Tests/TestPdfImage.cs b/src/UglyToad.PdfPig.Tests/TestPdfImage.cs index ada57d7b..c9fb264f 100644 --- a/src/UglyToad.PdfPig.Tests/TestPdfImage.cs +++ b/src/UglyToad.PdfPig.Tests/TestPdfImage.cs @@ -9,7 +9,8 @@ public class TestPdfImage : IPdfImage { - public PdfRectangle Bounds { get; set; } + public PdfRectangle BoundingBox { get; set; } + public PdfRectangle Bounds => BoundingBox; public int WidthInSamples { get; set; } diff --git a/src/UglyToad.PdfPig.Tests/Writer/Fonts/Standard14WritingFontTests.cs b/src/UglyToad.PdfPig.Tests/Writer/Fonts/Standard14WritingFontTests.cs index 5f334ba3..e14fea17 100644 --- a/src/UglyToad.PdfPig.Tests/Writer/Fonts/Standard14WritingFontTests.cs +++ b/src/UglyToad.PdfPig.Tests/Writer/Fonts/Standard14WritingFontTests.cs @@ -31,10 +31,10 @@ var point = new PdfPoint(leftX, topPageY); DateTimeStampPage(pdfBuilder, page, point, cm); var letters = page.AddText("Adobe Standard Font ZapfDingbats", 21, point, F2); - var newY = topPageY - letters.Select(v => v.GlyphRectangle.Height).Max() * 1.2; + var newY = topPageY - letters.Select(v => v.BoundingBox.Height).Max() * 1.2; point = new PdfPoint(leftX, newY); letters = page.AddText("Font Specific encoding in Black (octal) and Unicode in Blue (hex)", 10, point, F2); - newY = newY - letters.Select(v => v.GlyphRectangle.Height).Max() * 3; + newY = newY - letters.Select(v => v.BoundingBox.Height).Max() * 3; point = new PdfPoint(leftX, newY); var eachRowY = new List(); eachRowY.Add(newY); // First row @@ -216,10 +216,10 @@ var point = new PdfPoint(leftX, topPageY); DateTimeStampPage(pdfBuilder, page, point, cm); var letters = page.AddText("Adobe Standard Font Symbol ", 21, point, F2); - var newY = topPageY - letters.Select(v => v.GlyphRectangle.Height).Max() * 1.2; + var newY = topPageY - letters.Select(v => v.BoundingBox.Height).Max() * 1.2; point = new PdfPoint(leftX, newY); letters = page.AddText("Font Specific encoding in Black (octal), Unicode in Blue (hex), Red only available using Unicode", 10, point, F2); - newY = newY - letters.Select(v => v.GlyphRectangle.Height).Max() * 3; + newY = newY - letters.Select(v => v.BoundingBox.Height).Max() * 3; @@ -492,10 +492,10 @@ var point = new PdfPoint(leftX, topPageY); DateTimeStampPage(pdfBuilder, page, point, cm); var letters = page.AddText("Adobe Standard Font " + fontName, 21, point, F2); - var newY = topPageY - letters.Select(v => v.GlyphRectangle.Height).Max() * 1.2; + var newY = topPageY - letters.Select(v => v.BoundingBox.Height).Max() * 1.2; point = new PdfPoint(leftX, newY); letters = page.AddText("Font Specific encoding in Black, Unicode in Blue, Red only available using Unicode", 10, point, F2); - newY = newY - letters.Select(v => v.GlyphRectangle.Height).Max() * 3; + newY = newY - letters.Select(v => v.BoundingBox.Height).Max() * 3; point = new PdfPoint(leftX, newY); @@ -799,10 +799,10 @@ var labelPointSize = 5; var octalString = System.Convert.ToString((int)stringToAdd[0], 8).PadLeft(3, '0'); var label = octalString; - var codeMidPoint = point.X + letter[0].GlyphRectangle.Width / 2; + var codeMidPoint = point.X + letter[0].BoundingBox.Width / 2; var ml = page.MeasureText(label, labelPointSize, point, fontLabel); - var labelY = point.Y + ml.Max(v => v.GlyphRectangle.Height) * 0.1 + maxCharacterHeight; - var xLabel = codeMidPoint - (ml.Sum(v => v.GlyphRectangle.Width) / 2); + var labelY = point.Y + ml.Max(v => v.BoundingBox.Height) * 0.1 + maxCharacterHeight; + var xLabel = codeMidPoint - (ml.Sum(v => v.BoundingBox.Width) / 2); var labelPoint = new PdfPoint(xLabel, labelY); page.AddText(label, labelPointSize, labelPoint, fontLabel); } @@ -812,10 +812,10 @@ var labelPointSize = 3; var hexString = $"{(int)stringToAdd[0]:X}".PadLeft(4, '0'); var label = "0x" + hexString; - var codeMidPoint = point.X + letter[0].GlyphRectangle.Width / 2; + var codeMidPoint = point.X + letter[0].BoundingBox.Width / 2; var ml = page.MeasureText(label, labelPointSize, point, fontLabel); - var labelY = point.Y - ml.Max(v => v.GlyphRectangle.Height) * 2.5; - var xLabel = codeMidPoint - (ml.Sum(v => v.GlyphRectangle.Width) / 2); + var labelY = point.Y - ml.Max(v => v.BoundingBox.Height) * 2.5; + var xLabel = codeMidPoint - (ml.Sum(v => v.BoundingBox.Width) / 2); var labelPoint = new PdfPoint(xLabel, labelY); page.AddText(label, labelPointSize, labelPoint, fontLabel); } @@ -829,8 +829,8 @@ double inch = (page.PageSize.Width / 8.5); double cm = inch / 2.54; - var letterWidth = letter[0].GlyphRectangle.Width * 2; - var letterHeight = letter[0].GlyphRectangle.Height * 2; + var letterWidth = letter[0].BoundingBox.Width * 2; + var letterHeight = letter[0].BoundingBox.Height * 2; var newX = point.X + maxCharacterWidth * 1.1; var newY = point.Y; @@ -892,7 +892,7 @@ double maxCharacterWidth; { var point = new PdfPoint(10, 10); - var characterRectangles = unicodesCharacters.Select(v => page.MeasureText($"{v}", 12, point, font)[0].GlyphRectangle); + var characterRectangles = unicodesCharacters.Select(v => page.MeasureText($"{v}", 12, point, font)[0].BoundingBox); maxCharacterHeight = characterRectangles.Max(v => v.Height); maxCharacterWidth = characterRectangles.Max(v => v.Height); } @@ -921,8 +921,8 @@ { var mtUTC = page.MeasureText(stampTextUTC, fontSize, point, courierFont); var mtlocal = page.MeasureText(stampTextLocal, fontSize, point, courierFont); - var widthUTC = mtUTC.Sum(v => v.GlyphRectangle.Width); - var widthLocal = mtlocal.Sum(v => v.GlyphRectangle.Width); + var widthUTC = mtUTC.Sum(v => v.BoundingBox.Width); + var widthLocal = mtlocal.Sum(v => v.BoundingBox.Width); indentFromLeft -= Math.Max(widthUTC, widthLocal); } @@ -930,7 +930,7 @@ { point = new PdfPoint(indentFromLeft, point.Y); var letters = page.AddText(stampTextUTC, 7, point, courierFont); - var maxHeight = letters.Max(v => v.GlyphRectangle.Height); + var maxHeight = letters.Max(v => v.BoundingBox.Height); point = new PdfPoint(indentFromLeft, point.Y - maxHeight * 1.2); } diff --git a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs index 70d455d3..82618b5a 100644 --- a/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs +++ b/src/UglyToad.PdfPig.Tests/Writer/PdfDocumentBuilderTests.cs @@ -328,9 +328,9 @@ Assert.Equal(readerLetter.Value, writerLetter.Value); Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer); Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer); - Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer); + Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer); + Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer); + Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer); } } } @@ -471,9 +471,9 @@ Assert.Equal(readerLetter.Value, writerLetter.Value); Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer); Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer); - Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer); + Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer); + Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer); + Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer); } } } @@ -513,13 +513,13 @@ var topLine = new PdfPoint(30, page1.PageSize.Height - 60); var letters = page1.AddText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor", 9, topLine, font); - page1.AddText("incididunt ut labore et dolore magna aliqua.", 9, new PdfPoint(30, topLine.Y - letters.Max(x => x.GlyphRectangle.Height) - 5), font); + page1.AddText("incididunt ut labore et dolore magna aliqua.", 9, new PdfPoint(30, topLine.Y - letters.Max(x => x.BoundingBox.Height) - 5), font); var page2Letters = page2.AddText("The very hungry caterpillar ate all the apples in the garden.", 12, topLine, font); - var left = page2Letters[0].GlyphRectangle.Left; - var bottom = page2Letters.Min(x => x.GlyphRectangle.Bottom); - var right = page2Letters[page2Letters.Count - 1].GlyphRectangle.Right; - var top = page2Letters.Max(x => x.GlyphRectangle.Top); + var left = page2Letters[0].BoundingBox.Left; + var bottom = page2Letters.Min(x => x.BoundingBox.Bottom); + var right = page2Letters[page2Letters.Count - 1].BoundingBox.Right; + var top = page2Letters.Max(x => x.BoundingBox.Top); page2.SetStrokeColor(10, 250, 69); page2.DrawRectangle(new PdfPoint(left, bottom), right - left, top - bottom); @@ -591,8 +591,8 @@ Assert.NotNull(image); - Assert.Equal(expectedBounds.BottomLeft, image.Bounds.BottomLeft); - Assert.Equal(expectedBounds.TopRight, image.Bounds.TopRight); + Assert.Equal(expectedBounds.BottomLeft, image.BoundingBox.BottomLeft); + Assert.Equal(expectedBounds.TopRight, image.BoundingBox.TopRight); Assert.Equal(imageBytes, image.RawMemory.ToArray()); } @@ -637,10 +637,10 @@ Assert.Equal(2, page1Images.Count); var image1 = page1Images[0]; - Assert.Equal(expectedBounds1, image1.Bounds); + Assert.Equal(expectedBounds1, image1.BoundingBox); var image2 = page1Images[1]; - Assert.Equal(expectedBounds2, image2.Bounds); + Assert.Equal(expectedBounds2, image2.BoundingBox); var page2Doc = document.GetPage(2); @@ -648,7 +648,7 @@ Assert.NotNull(image3); - Assert.Equal(expectedBounds3, image3.Bounds); + Assert.Equal(expectedBounds3, image3.BoundingBox); Assert.Equal(imageBytes, image1.RawMemory.ToArray()); Assert.Equal(imageBytes, image2.RawMemory.ToArray()); @@ -724,8 +724,8 @@ Assert.NotNull(image); - Assert.Equal(expectedBounds.BottomLeft, image.Bounds.BottomLeft); - Assert.Equal(expectedBounds.TopRight, image.Bounds.TopRight); + Assert.Equal(expectedBounds.BottomLeft, image.BoundingBox.BottomLeft); + Assert.Equal(expectedBounds.TopRight, image.BoundingBox.TopRight); Assert.True(image.TryGetPng(out var png)); Assert.NotNull(png); @@ -927,9 +927,9 @@ Assert.Equal(readerLetter.Value, writerLetter.Value); Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer); Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer); - Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer); - Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer); + Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer); + Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer); + Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer); } } } diff --git a/src/UglyToad.PdfPig/Content/IBoundingBox.cs b/src/UglyToad.PdfPig/Content/IBoundingBox.cs new file mode 100644 index 00000000..f64531bd --- /dev/null +++ b/src/UglyToad.PdfPig/Content/IBoundingBox.cs @@ -0,0 +1,15 @@ +namespace UglyToad.PdfPig.Content +{ + using UglyToad.PdfPig.Core; + + /// + /// Interface for classes with a bounding box + /// + public interface IBoundingBox + { + /// + /// Gets the Bounding Box: The rectangle completely containing this object + /// + PdfRectangle BoundingBox { get; } + } +} diff --git a/src/UglyToad.PdfPig/Content/IPdfImage.cs b/src/UglyToad.PdfPig/Content/IPdfImage.cs index 6d024392..a879d40b 100644 --- a/src/UglyToad.PdfPig/Content/IPdfImage.cs +++ b/src/UglyToad.PdfPig/Content/IPdfImage.cs @@ -12,11 +12,13 @@ /// /// An image in a PDF document, may be an or a PostScript image XObject (). /// - public interface IPdfImage + public interface IPdfImage: IBoundingBox { /// /// The placement rectangle of the image in PDF coordinates. + /// Kept so not major breaking API change. Use instead /// + [Obsolete("Use BoundingBox instead.")] PdfRectangle Bounds { get; } /// diff --git a/src/UglyToad.PdfPig/Content/InlineImage.cs b/src/UglyToad.PdfPig/Content/InlineImage.cs index 9c407332..135e1928 100644 --- a/src/UglyToad.PdfPig/Content/InlineImage.cs +++ b/src/UglyToad.PdfPig/Content/InlineImage.cs @@ -19,7 +19,11 @@ private readonly Lazy>? memoryFactory; /// - public PdfRectangle Bounds { get; } + public PdfRectangle BoundingBox { get; } + + /// + [Obsolete("Use BoundingBox instead.")] + public PdfRectangle Bounds => BoundingBox; /// public int WidthInSamples { get; } @@ -79,7 +83,7 @@ IPdfImage? softMaskImage) { IsInlineImage = true; - Bounds = bounds; + BoundingBox = bounds; WidthInSamples = widthInSamples; HeightInSamples = heightInSamples; Decode = decode; @@ -138,7 +142,7 @@ /// public override string ToString() { - return $"Inline Image (w {Bounds.Width}, h {Bounds.Height})"; + return $"Inline Image (w {BoundingBox.Width}, h {BoundingBox.Height})"; } } } diff --git a/src/UglyToad.PdfPig/Content/Letter.cs b/src/UglyToad.PdfPig/Content/Letter.cs index 27333390..c13fd922 100644 --- a/src/UglyToad.PdfPig/Content/Letter.cs +++ b/src/UglyToad.PdfPig/Content/Letter.cs @@ -7,7 +7,7 @@ /// /// A glyph or combination of glyphs (characters) drawn by a PDF content stream. /// - public class Letter + public class Letter:IBoundingBox { /// /// The text for this letter or unicode character. @@ -44,10 +44,16 @@ /// For example letters with descenders, p, j, etc., will have a box extending below the they are placed at. /// The width of the glyph may also be more or less than the allocated for the character in the PDF content. /// - public PdfRectangle GlyphRectangle { get; } + public PdfRectangle BoundingBox { get; } + + /// + /// Gets the Bounding Box: The rectangle completely containing this object. + /// + [Obsolete("Use BoundingBox instead.")] + public PdfRectangle GlyphRectangle => BoundingBox; /// - /// The loose bounding box for the glyph. Contrary to the , the loose bounding box will be the same across all glyphes of the same font. + /// The loose bounding box for the glyph. Contrary to the , the loose bounding box will be the same across all glyphes of the same font. /// It takes in account the font Ascent and Descent. /// public PdfRectangle GlyphRectangleLoose { get; } @@ -173,7 +179,7 @@ int textSequence) { Value = value; - GlyphRectangle = glyphRectangle; + BoundingBox = glyphRectangle; GlyphRectangleLoose = glyphRectangleLoose; StartBaseLine = startBaseLine; EndBaseLine = endBaseLine; @@ -207,7 +213,7 @@ public Letter AsBold() { return new Letter(Value, - GlyphRectangle, + BoundingBox, GlyphRectangleLoose, StartBaseLine, EndBaseLine, @@ -273,7 +279,7 @@ private TextOrientation GetTextOrientationRot() { - double rotation = GlyphRectangle.Rotation; + double rotation = BoundingBox.Rotation; if (Math.Abs(rotation % 90) >= 10e-5) { return TextOrientation.Other; diff --git a/src/UglyToad.PdfPig/Content/Word.cs b/src/UglyToad.PdfPig/Content/Word.cs index 7d157fba..8140b204 100644 --- a/src/UglyToad.PdfPig/Content/Word.cs +++ b/src/UglyToad.PdfPig/Content/Word.cs @@ -9,7 +9,7 @@ /// /// A word. /// - public class Word + public class Word : IBoundingBox { /// /// The text of the word. @@ -107,15 +107,15 @@ blY = letter.StartBaseLine.Y; } - var right = letter.StartBaseLine.X + Math.Max(letter.Width, letter.GlyphRectangle.Width); + var right = letter.StartBaseLine.X + Math.Max(letter.Width, letter.BoundingBox.Width); if (right > trX) { trX = right; } - if (letter.GlyphRectangle.TopLeft.Y > trY) + if (letter.BoundingBox.TopLeft.Y > trY) { - trY = letter.GlyphRectangle.TopLeft.Y; + trY = letter.BoundingBox.TopLeft.Y; } } @@ -146,15 +146,15 @@ blY = letter.StartBaseLine.Y; } - var right = letter.StartBaseLine.X - Math.Max(letter.Width, letter.GlyphRectangle.Width); + var right = letter.StartBaseLine.X - Math.Max(letter.Width, letter.BoundingBox.Width); if (right < trX) { trX = right; } - if (letter.GlyphRectangle.TopRight.Y < trY) + if (letter.BoundingBox.TopRight.Y < trY) { - trY = letter.GlyphRectangle.TopRight.Y; + trY = letter.BoundingBox.TopRight.Y; } } @@ -185,15 +185,15 @@ r = letter.EndBaseLine.Y; } - var right = letter.StartBaseLine.X + letter.GlyphRectangle.Height; + var right = letter.StartBaseLine.X + letter.BoundingBox.Height; if (right > t) { t = right; } - if (letter.GlyphRectangle.BottomLeft.Y > l) + if (letter.BoundingBox.BottomLeft.Y > l) { - l = letter.GlyphRectangle.BottomLeft.Y; + l = letter.BoundingBox.BottomLeft.Y; } } @@ -226,15 +226,15 @@ l = letter.StartBaseLine.Y; } - var right = letter.StartBaseLine.X - letter.GlyphRectangle.Height; + var right = letter.StartBaseLine.X - letter.BoundingBox.Height; if (right < t) { t = right; } - if (letter.GlyphRectangle.BottomRight.Y > r) + if (letter.BoundingBox.BottomRight.Y > r) { - r = letter.GlyphRectangle.BottomRight.Y; + r = letter.BoundingBox.BottomRight.Y; } } @@ -253,7 +253,7 @@ if (letters.Count == 1) { - return new(builder.ToString(), letters[0].GlyphRectangle); + return new(builder.ToString(), letters[0].BoundingBox); } else { @@ -299,8 +299,8 @@ { r.StartBaseLine, r.EndBaseLine, - r.GlyphRectangle.TopLeft, - r.GlyphRectangle.TopRight + r.BoundingBox.TopLeft, + r.BoundingBox.TopRight }).Distinct().Select(p => inverseRotation.Transform(p)); var aabb = new PdfRectangle(transformedPoints.Min(p => p.X), diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs index b1371a11..b50a0953 100644 --- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs +++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs @@ -122,7 +122,7 @@ namespace UglyToad.PdfPig.Graphics letter = new Letter( newLetter, - attachTo.GlyphRectangle, + attachTo.BoundingBox, attachTo.GlyphRectangleLoose, attachTo.StartBaseLine, attachTo.EndBaseLine, diff --git a/src/UglyToad.PdfPig/Util/DefaultWordExtractor.cs b/src/UglyToad.PdfPig/Util/DefaultWordExtractor.cs index 44a90996..f8ee8d04 100644 --- a/src/UglyToad.PdfPig/Util/DefaultWordExtractor.cs +++ b/src/UglyToad.PdfPig/Util/DefaultWordExtractor.cs @@ -72,7 +72,7 @@ continue; } - var letterHeight = Math.Max(lastLetter.GlyphRectangle.Height, letter.GlyphRectangle.Height); + var letterHeight = Math.Max(lastLetter.BoundingBox.Height, letter.BoundingBox.Height); var gap = letter.Location.X - (lastLetter.Location.X + lastLetter.Width); var nextToLeft = letter.Location.X < lastX.Value - 1; diff --git a/src/UglyToad.PdfPig/XObjects/XObjectImage.cs b/src/UglyToad.PdfPig/XObjects/XObjectImage.cs index f7d65075..8f54c334 100644 --- a/src/UglyToad.PdfPig/XObjects/XObjectImage.cs +++ b/src/UglyToad.PdfPig/XObjects/XObjectImage.cs @@ -19,7 +19,12 @@ private readonly Lazy>? memoryFactory; /// - public PdfRectangle Bounds { get; } + public PdfRectangle BoundingBox { get; } + + /// + + [Obsolete("Use BoundingBox instead.")] + public PdfRectangle Bounds => BoundingBox; /// public int WidthInSamples { get; } @@ -85,7 +90,7 @@ ColorSpaceDetails? colorSpaceDetails, IPdfImage? softMaskImage) { - Bounds = bounds; + BoundingBox = bounds; WidthInSamples = widthInSamples; HeightInSamples = heightInSamples; BitsPerComponent = bitsPerComponent; @@ -121,7 +126,7 @@ /// public override string ToString() { - return $"XObject Image (w {Bounds.Width}, h {Bounds.Height}): {ImageDictionary}"; + return $"XObject Image (w {BoundingBox.Width}, h {BoundingBox.Height}): {ImageDictionary}"; } } }