mirror of
https://github.com/UglyToad/PdfPig.git
synced 2026-03-10 00:23:29 +08:00
Introduce IBlock and ILettersBlock interfaces (Round 2) (#1263)
Some checks failed
Build, test and publish draft / build (push) Has been cancelled
Build and test [MacOS] / build (push) Has been cancelled
Run Common Crawl Tests / build (0000-0001) (push) Has been cancelled
Run Common Crawl Tests / build (0002-0003) (push) Has been cancelled
Run Common Crawl Tests / build (0004-0005) (push) Has been cancelled
Run Common Crawl Tests / build (0006-0007) (push) Has been cancelled
Run Common Crawl Tests / build (0008-0009) (push) Has been cancelled
Run Common Crawl Tests / build (0010-0011) (push) Has been cancelled
Run Common Crawl Tests / build (0012-0013) (push) Has been cancelled
Run Integration Tests / build (push) Has been cancelled
Tag Release / tag_if_version_changed (push) Has been cancelled
Nightly Release / Check if this commit has already been published (push) Has been cancelled
Nightly Release / tests (push) Has been cancelled
Nightly Release / build_and_publish_nightly (push) Has been cancelled
Some checks failed
Build, test and publish draft / build (push) Has been cancelled
Build and test [MacOS] / build (push) Has been cancelled
Run Common Crawl Tests / build (0000-0001) (push) Has been cancelled
Run Common Crawl Tests / build (0002-0003) (push) Has been cancelled
Run Common Crawl Tests / build (0004-0005) (push) Has been cancelled
Run Common Crawl Tests / build (0006-0007) (push) Has been cancelled
Run Common Crawl Tests / build (0008-0009) (push) Has been cancelled
Run Common Crawl Tests / build (0010-0011) (push) Has been cancelled
Run Common Crawl Tests / build (0012-0013) (push) Has been cancelled
Run Integration Tests / build (push) Has been cancelled
Tag Release / tag_if_version_changed (push) Has been cancelled
Nightly Release / Check if this commit has already been published (push) Has been cancelled
Nightly Release / tests (push) Has been cancelled
Nightly Release / build_and_publish_nightly (push) Has been cancelled
* 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 <david@brokit.co.uk>
This commit is contained in:
@@ -35,20 +35,20 @@
|
|||||||
var key = (letter.Value, letter.FontName);
|
var key = (letter.Value, letter.FontName);
|
||||||
if (duplicateIndex.TryGetValue(key, out var candidateIndices))
|
if (duplicateIndex.TryGetValue(key, out var candidateIndices))
|
||||||
{
|
{
|
||||||
double tolerance = letter.GlyphRectangle.Width / (letter.Value.Length == 0 ? 1 : letter.Value.Length) / 3.0;
|
double tolerance = letter.BoundingBox.Width / (letter.Value.Length == 0 ? 1 : letter.Value.Length) / 3.0;
|
||||||
double minX = letter.GlyphRectangle.BottomLeft.X - tolerance;
|
double minX = letter.BoundingBox.BottomLeft.X - tolerance;
|
||||||
double maxX = letter.GlyphRectangle.BottomLeft.X + tolerance;
|
double maxX = letter.BoundingBox.BottomLeft.X + tolerance;
|
||||||
double minY = letter.GlyphRectangle.BottomLeft.Y - tolerance;
|
double minY = letter.BoundingBox.BottomLeft.Y - tolerance;
|
||||||
double maxY = letter.GlyphRectangle.BottomLeft.Y + tolerance;
|
double maxY = letter.BoundingBox.BottomLeft.Y + tolerance;
|
||||||
|
|
||||||
for (int ci = 0; ci < candidateIndices.Count; ci++)
|
for (int ci = 0; ci < candidateIndices.Count; ci++)
|
||||||
{
|
{
|
||||||
int idx = candidateIndices[ci];
|
int idx = candidateIndices[ci];
|
||||||
var l = cleanLetters[idx];
|
var l = cleanLetters[idx];
|
||||||
if (minX <= l.GlyphRectangle.BottomLeft.X &&
|
if (minX <= l.BoundingBox.BottomLeft.X &&
|
||||||
maxX >= l.GlyphRectangle.BottomLeft.X &&
|
maxX >= l.BoundingBox.BottomLeft.X &&
|
||||||
minY <= l.GlyphRectangle.BottomLeft.Y &&
|
minY <= l.BoundingBox.BottomLeft.Y &&
|
||||||
maxY >= l.GlyphRectangle.BottomLeft.Y)
|
maxY >= l.BoundingBox.BottomLeft.Y)
|
||||||
{
|
{
|
||||||
addLetter = false;
|
addLetter = false;
|
||||||
duplicatesOverlappingIndex = idx;
|
duplicatesOverlappingIndex = idx;
|
||||||
|
|||||||
@@ -229,7 +229,7 @@
|
|||||||
private AltoDocument.AltoIllustration ToAltoIllustration(IPdfImage pdfImage, double height)
|
private AltoDocument.AltoIllustration ToAltoIllustration(IPdfImage pdfImage, double height)
|
||||||
{
|
{
|
||||||
illustrationCount++;
|
illustrationCount++;
|
||||||
var rectangle = pdfImage.Bounds;
|
var rectangle = pdfImage.BoundingBox;
|
||||||
|
|
||||||
return new AltoDocument.AltoIllustration
|
return new AltoDocument.AltoIllustration
|
||||||
{
|
{
|
||||||
@@ -311,10 +311,10 @@
|
|||||||
glyphCount++;
|
glyphCount++;
|
||||||
return new AltoDocument.AltoGlyph
|
return new AltoDocument.AltoGlyph
|
||||||
{
|
{
|
||||||
VerticalPosition = (float)Math.Round((height - letter.GlyphRectangle.Top) * scale),
|
VerticalPosition = (float)Math.Round((height - letter.BoundingBox.Top) * scale),
|
||||||
HorizontalPosition = (float)Math.Round(letter.GlyphRectangle.Left * scale),
|
HorizontalPosition = (float)Math.Round(letter.BoundingBox.Left * scale),
|
||||||
Height = (float)Math.Round(letter.GlyphRectangle.Height * scale),
|
Height = (float)Math.Round(letter.BoundingBox.Height * scale),
|
||||||
Width = (float)Math.Round(letter.GlyphRectangle.Width * scale),
|
Width = (float)Math.Round(letter.BoundingBox.Width * scale),
|
||||||
Gc = 1.0f,
|
Gc = 1.0f,
|
||||||
Content = invalidCharacterHandler(letter.Value),
|
Content = invalidCharacterHandler(letter.Value),
|
||||||
Id = "P" + pageCount + "_ST" + stringCount.ToString("#00000") + "_G" + glyphCount.ToString("#00")
|
Id = "P" + pageCount + "_ST" + stringCount.ToString("#00000") + "_G" + glyphCount.ToString("#00")
|
||||||
|
|||||||
@@ -277,7 +277,7 @@
|
|||||||
private string GetCode(IPdfImage pdfImage, double pageHeight, int level)
|
private string GetCode(IPdfImage pdfImage, double pageHeight, int level)
|
||||||
{
|
{
|
||||||
imageCount++;
|
imageCount++;
|
||||||
var bbox = pdfImage.Bounds;
|
var bbox = pdfImage.BoundingBox;
|
||||||
return GetIndent(level) + "<span class='ocr_image' id='image_" + pageCount + "_"
|
return GetIndent(level) + "<span class='ocr_image' id='image_" + pageCount + "_"
|
||||||
+ imageCount + "' title='" + GetCode(bbox, pageHeight) + "' />";
|
+ imageCount + "' title='" + GetCode(bbox, pageHeight) + "' />";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,7 +280,7 @@
|
|||||||
private PageXmlDocument.PageXmlImageRegion ToPageXmlImageRegion(IPdfImage pdfImage, PageXmlData data, double pageWidth, double pageHeight)
|
private PageXmlDocument.PageXmlImageRegion ToPageXmlImageRegion(IPdfImage pdfImage, PageXmlData data, double pageWidth, double pageHeight)
|
||||||
{
|
{
|
||||||
data.RegionsCount++;
|
data.RegionsCount++;
|
||||||
var bbox = pdfImage.Bounds;
|
var bbox = pdfImage.BoundingBox;
|
||||||
return new PageXmlDocument.PageXmlImageRegion()
|
return new PageXmlDocument.PageXmlImageRegion()
|
||||||
{
|
{
|
||||||
Coords = ToCoords(bbox, pageWidth, pageHeight),
|
Coords = ToCoords(bbox, pageWidth, pageHeight),
|
||||||
@@ -360,7 +360,7 @@
|
|||||||
data.GlyphsCount++;
|
data.GlyphsCount++;
|
||||||
return new PageXmlDocument.PageXmlGlyph()
|
return new PageXmlDocument.PageXmlGlyph()
|
||||||
{
|
{
|
||||||
Coords = ToCoords(letter.GlyphRectangle, pageWidth, pageHeight),
|
Coords = ToCoords(letter.BoundingBox, pageWidth, pageHeight),
|
||||||
Ligature = false,
|
Ligature = false,
|
||||||
Production = PageXmlDocument.PageXmlProductionSimpleType.Printed,
|
Production = PageXmlDocument.PageXmlProductionSimpleType.Printed,
|
||||||
TextStyle = new PageXmlDocument.PageXmlTextStyle()
|
TextStyle = new PageXmlDocument.PageXmlTextStyle()
|
||||||
|
|||||||
@@ -96,12 +96,12 @@
|
|||||||
{
|
{
|
||||||
string fontFamily = GetFontFamily(l.FontName, out string style, out string weight);
|
string fontFamily = GetFontFamily(l.FontName, out string style, out string weight);
|
||||||
string rotation = "";
|
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 safeValue = XmlEscape(l, doc);
|
||||||
var x = Math.Round(l.StartBaseLine.X, Rounding);
|
var x = Math.Round(l.StartBaseLine.X, Rounding);
|
||||||
|
|||||||
@@ -372,7 +372,7 @@
|
|||||||
public Func<IEnumerable<Letter>, double> DominantFontWidthFunc { get; set; } =
|
public Func<IEnumerable<Letter>, double> DominantFontWidthFunc { get; set; } =
|
||||||
(letters) =>
|
(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();
|
var mode = widths.Mode();
|
||||||
if (double.IsNaN(mode) || mode == 0)
|
if (double.IsNaN(mode) || mode == 0)
|
||||||
{
|
{
|
||||||
@@ -389,7 +389,7 @@
|
|||||||
public Func<IEnumerable<Letter>, double> DominantFontHeightFunc { get; set; } =
|
public Func<IEnumerable<Letter>, double> DominantFontHeightFunc { get; set; } =
|
||||||
(letters) =>
|
(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();
|
var mode = heights.Mode();
|
||||||
if (double.IsNaN(mode) || mode == 0)
|
if (double.IsNaN(mode) || mode == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A block of text.
|
/// A block of text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TextBlock
|
public class TextBlock: IBoundingBox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The separator used between lines in the block.
|
/// The separator used between lines in the block.
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
{
|
{
|
||||||
letter = new Letter(
|
letter = new Letter(
|
||||||
" ",
|
" ",
|
||||||
letter.GlyphRectangle,
|
letter.BoundingBox,
|
||||||
letter.GlyphRectangleLoose,
|
letter.GlyphRectangleLoose,
|
||||||
letter.StartBaseLine,
|
letter.StartBaseLine,
|
||||||
letter.EndBaseLine,
|
letter.EndBaseLine,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A line of text.
|
/// A line of text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TextLine
|
public class TextLine : IBoundingBox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The separator used between words in the line.
|
/// The separator used between words in the line.
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
{
|
{
|
||||||
return GetWhitespaces(words,
|
return GetWhitespaces(words,
|
||||||
images,
|
images,
|
||||||
words.SelectMany(w => w.Letters).Select(x => x.GlyphRectangle.Width).Mode() * 1.25,
|
words.SelectMany(w => w.Letters).Select(x => x.BoundingBox.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.Height).Mode() * 1.25,
|
||||||
maxRectangleCount: maxRectangleCount,
|
maxRectangleCount: maxRectangleCount,
|
||||||
maxBoundQueueSize: maxBoundQueueSize);
|
maxBoundQueueSize: maxBoundQueueSize);
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
if (images?.Any() == true)
|
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,
|
return GetWhitespaces(bboxes,
|
||||||
|
|||||||
@@ -163,8 +163,8 @@
|
|||||||
public Func<Letter, Letter, double> MaximumDistance { get; set; } = (l1, l2) =>
|
public Func<Letter, Letter, double> MaximumDistance { get; set; } = (l1, l2) =>
|
||||||
{
|
{
|
||||||
double maxDist = Math.Max(Math.Max(Math.Max(Math.Max(Math.Max(
|
double maxDist = Math.Max(Math.Max(Math.Max(Math.Max(Math.Max(
|
||||||
Math.Abs(l1.GlyphRectangle.Width),
|
Math.Abs(l1.BoundingBox.Width),
|
||||||
Math.Abs(l2.GlyphRectangle.Width)),
|
Math.Abs(l2.BoundingBox.Width)),
|
||||||
Math.Abs(l1.Width)),
|
Math.Abs(l1.Width)),
|
||||||
Math.Abs(l2.Width)),
|
Math.Abs(l2.Width)),
|
||||||
l1.PointSize), l2.PointSize) * 0.2;
|
l1.PointSize), l2.PointSize) * 0.2;
|
||||||
|
|||||||
@@ -65,14 +65,14 @@ namespace UglyToad.PdfPig.Tests.Fonts.SystemFonts
|
|||||||
|
|
||||||
var current = page.Letters[i];
|
var current = page.Letters[i];
|
||||||
|
|
||||||
Assert.Equal(expectedData.TopLeft.X, current.GlyphRectangle.TopLeft.X, 6);
|
Assert.Equal(expectedData.TopLeft.X, current.BoundingBox.TopLeft.X, 6);
|
||||||
Assert.Equal(expectedData.TopLeft.Y, current.GlyphRectangle.TopLeft.Y, 6);
|
Assert.Equal(expectedData.TopLeft.Y, current.BoundingBox.TopLeft.Y, 6);
|
||||||
Assert.Equal(expectedData.Width, current.GlyphRectangle.Width, 6);
|
Assert.Equal(expectedData.Width, current.BoundingBox.Width, 6);
|
||||||
Assert.Equal(expectedData.Height, current.GlyphRectangle.Height, 6);
|
Assert.Equal(expectedData.Height, current.BoundingBox.Height, 6);
|
||||||
Assert.Equal(expectedData.Rotation, current.GlyphRectangle.Rotation, 3);
|
Assert.Equal(expectedData.Rotation, current.BoundingBox.Rotation, 3);
|
||||||
|
|
||||||
Assert.True(current.GlyphRectangle.IntersectsWith(current.GlyphRectangleLoose));
|
Assert.True(current.BoundingBox.IntersectsWith(current.GlyphRectangleLoose));
|
||||||
Assert.Equal(current.GlyphRectangle.Rotation, current.GlyphRectangleLoose.Rotation, 3);
|
Assert.Equal(current.BoundingBox.Rotation, current.GlyphRectangleLoose.Rotation, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,14 @@
|
|||||||
// check 'm'
|
// check 'm'
|
||||||
var m = letters[0];
|
var m = letters[0];
|
||||||
Assert.Equal("m", m.Value);
|
Assert.Equal("m", m.Value);
|
||||||
Assert.Equal(new PdfPoint(253.4458, 658.431), m.GlyphRectangle.BottomLeft, pointComparer);
|
Assert.Equal(new PdfPoint(253.4458, 658.431), m.BoundingBox.BottomLeft, pointComparer);
|
||||||
Assert.Equal(new PdfPoint(261.22659, 662.83446), m.GlyphRectangle.TopRight, pointComparer);
|
Assert.Equal(new PdfPoint(261.22659, 662.83446), m.BoundingBox.TopRight, pointComparer);
|
||||||
|
|
||||||
// check 'p'
|
// check 'p'
|
||||||
var p = letters[1];
|
var p = letters[1];
|
||||||
Assert.Equal("p", p.Value);
|
Assert.Equal("p", p.Value);
|
||||||
Assert.Equal(new PdfPoint(261.70778, 656.49825), p.GlyphRectangle.BottomLeft, pointComparer);
|
Assert.Equal(new PdfPoint(261.70778, 656.49825), p.BoundingBox.BottomLeft, pointComparer);
|
||||||
Assert.Equal(new PdfPoint(266.6193, 662.83446), p.GlyphRectangle.TopRight, pointComparer);
|
Assert.Equal(new PdfPoint(266.6193, 662.83446), p.BoundingBox.TopRight, pointComparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
Assert.Equal(Width, letter.Width, 1);
|
Assert.Equal(Width, letter.Width, 1);
|
||||||
if (includeHeight)
|
if (includeHeight)
|
||||||
{
|
{
|
||||||
Assert.Equal(Height, letter.GlyphRectangle.Height, 1);
|
Assert.Equal(Height, letter.BoundingBox.Height, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
var rect = new PdfRectangle(207, 158, 229, 168.5);
|
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.NotEmpty(missingChars);
|
||||||
Assert.True(missingChars.Length == 2);
|
Assert.True(missingChars.Length == 2);
|
||||||
|
|||||||
@@ -758,7 +758,7 @@
|
|||||||
{
|
{
|
||||||
var letter = page1.Letters[l];
|
var letter = page1.Letters[l];
|
||||||
Assert.Equal(TextOrientation.Other, letter.TextOrientation);
|
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);
|
var page2 = document.GetPage(2);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
var page = document.GetPage(i + 1);
|
var page = document.GetPage(i + 1);
|
||||||
foreach (var letter in page.Letters)
|
foreach (var letter in page.Letters)
|
||||||
{
|
{
|
||||||
var bbox = letter.GlyphRectangle;
|
var bbox = letter.BoundingBox;
|
||||||
if (bbox.Height > 0)
|
if (bbox.Height > 0)
|
||||||
{
|
{
|
||||||
if (letter.GlyphRectangleLoose.Height <= 0)
|
if (letter.GlyphRectangleLoose.Height <= 0)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace UglyToad.PdfPig.Tests.Integration
|
|||||||
{
|
{
|
||||||
var page = document.GetPage(1);
|
var page = document.GetPage(1);
|
||||||
|
|
||||||
Assert.NotEqual(0, page.Letters[0].GlyphRectangle.Height);
|
Assert.NotEqual(0, page.Letters[0].BoundingBox.Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
var page = document.GetPage(1);
|
var page = document.GetPage(1);
|
||||||
Assert.Equal(612, page.Width); // Due to cropping
|
Assert.Equal(612, page.Width); // Due to cropping
|
||||||
Assert.Equal(792, page.Height); // Due to cropping
|
Assert.Equal(792, page.Height); // Due to cropping
|
||||||
var minX = page.Letters.Select(l => l.GlyphRectangle.Left).Min();
|
var minX = page.Letters.Select(l => l.BoundingBox.Left).Min();
|
||||||
var maxX = page.Letters.Select(l => l.GlyphRectangle.Right).Max();
|
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(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
|
Assert.Equal(540, maxX, 0); // If cropping is not applied correctly, these values will be off
|
||||||
// The page is cropped at
|
// The page is cropped at
|
||||||
|
|||||||
@@ -47,29 +47,29 @@
|
|||||||
{
|
{
|
||||||
var page = document.GetPage(1);
|
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];
|
var pdfPigSquare = images[0];
|
||||||
|
|
||||||
Assert.Equal(148.3d, pdfPigSquare.Bounds.Width, doubleComparer);
|
Assert.Equal(148.3d, pdfPigSquare.BoundingBox.Width, doubleComparer);
|
||||||
Assert.Equal(148.3d, pdfPigSquare.Bounds.Height, doubleComparer);
|
Assert.Equal(148.3d, pdfPigSquare.BoundingBox.Height, doubleComparer);
|
||||||
Assert.Equal(60.1d, pdfPigSquare.Bounds.Left, doubleComparer);
|
Assert.Equal(60.1d, pdfPigSquare.BoundingBox.Left, doubleComparer);
|
||||||
Assert.Equal(765.8d, pdfPigSquare.Bounds.Top, doubleComparer);
|
Assert.Equal(765.8d, pdfPigSquare.BoundingBox.Top, doubleComparer);
|
||||||
|
|
||||||
|
|
||||||
var pdfPigSquished = images[1];
|
var pdfPigSquished = images[1];
|
||||||
|
|
||||||
Assert.Equal(206.8d, pdfPigSquished.Bounds.Width, doubleComparer);
|
Assert.Equal(206.8d, pdfPigSquished.BoundingBox.Width, doubleComparer);
|
||||||
Assert.Equal(83.2d, pdfPigSquished.Bounds.Height, doubleComparer);
|
Assert.Equal(83.2d, pdfPigSquished.BoundingBox.Height, doubleComparer);
|
||||||
Assert.Equal(309.8d, pdfPigSquished.Bounds.Left, doubleComparer);
|
Assert.Equal(309.8d, pdfPigSquished.BoundingBox.Left, doubleComparer);
|
||||||
Assert.Equal(552.1d, pdfPigSquished.Bounds.Top, doubleComparer);
|
Assert.Equal(552.1d, pdfPigSquished.BoundingBox.Top, doubleComparer);
|
||||||
|
|
||||||
var birthdayPigs = images[2];
|
var birthdayPigs = images[2];
|
||||||
|
|
||||||
Assert.Equal(391d, birthdayPigs.Bounds.Width, doubleComparer);
|
Assert.Equal(391d, birthdayPigs.BoundingBox.Width, doubleComparer);
|
||||||
Assert.Equal(267.1d, birthdayPigs.Bounds.Height, doubleComparer);
|
Assert.Equal(267.1d, birthdayPigs.BoundingBox.Height, doubleComparer);
|
||||||
Assert.Equal(102.2d, birthdayPigs.Bounds.Left, doubleComparer);
|
Assert.Equal(102.2d, birthdayPigs.BoundingBox.Left, doubleComparer);
|
||||||
Assert.Equal(426.3d, birthdayPigs.Bounds.Top, doubleComparer);
|
Assert.Equal(426.3d, birthdayPigs.BoundingBox.Top, doubleComparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,27 +42,27 @@
|
|||||||
|
|
||||||
Assert.Equal("I", page.Letters[0].Value);
|
Assert.Equal("I", page.Letters[0].Value);
|
||||||
|
|
||||||
Assert.Equal(90.1d, page.Letters[0].GlyphRectangle.BottomLeft.X, comparer);
|
Assert.Equal(90.1d, page.Letters[0].BoundingBox.BottomLeft.X, comparer);
|
||||||
Assert.Equal(709.2d, page.Letters[0].GlyphRectangle.BottomLeft.Y, 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(94.0d, page.Letters[0].BoundingBox.TopRight.X, comparer);
|
||||||
Assert.Equal(719.89d, page.Letters[0].GlyphRectangle.TopRight.Y, comparer);
|
Assert.Equal(719.89d, page.Letters[0].BoundingBox.TopRight.Y, comparer);
|
||||||
|
|
||||||
Assert.Equal("a", page.Letters[5].Value);
|
Assert.Equal("a", page.Letters[5].Value);
|
||||||
|
|
||||||
Assert.Equal(114.5d, page.Letters[5].GlyphRectangle.BottomLeft.X, comparer);
|
Assert.Equal(114.5d, page.Letters[5].BoundingBox.BottomLeft.X, comparer);
|
||||||
Assert.Equal(709.2d, page.Letters[5].GlyphRectangle.BottomLeft.Y, 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(119.82d, page.Letters[5].BoundingBox.TopRight.X, comparer);
|
||||||
Assert.Equal(714.89d, page.Letters[5].GlyphRectangle.TopRight.Y, comparer);
|
Assert.Equal(714.89d, page.Letters[5].BoundingBox.TopRight.Y, comparer);
|
||||||
|
|
||||||
Assert.Equal("f", page.Letters[16].Value);
|
Assert.Equal("f", page.Letters[16].Value);
|
||||||
|
|
||||||
Assert.Equal(169.9d, page.Letters[16].GlyphRectangle.BottomLeft.X, comparer);
|
Assert.Equal(169.9d, page.Letters[16].BoundingBox.BottomLeft.X, comparer);
|
||||||
Assert.Equal(709.2d, page.Letters[16].GlyphRectangle.BottomLeft.Y, 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(176.89d, page.Letters[16].BoundingBox.TopRight.X, comparer);
|
||||||
Assert.Equal(719.89d, page.Letters[16].GlyphRectangle.TopRight.Y, comparer);
|
Assert.Equal(719.89d, page.Letters[16].BoundingBox.TopRight.Y, comparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ namespace UglyToad.PdfPig.Tests.Integration
|
|||||||
{
|
{
|
||||||
var page = document.GetPage(1);
|
var page = document.GetPage(1);
|
||||||
|
|
||||||
Assert.Contains(page.Letters, x => x.GlyphRectangle.Width != 0);
|
Assert.Contains(page.Letters, x => x.BoundingBox.Width != 0);
|
||||||
Assert.Contains(page.Letters, x => x.GlyphRectangle.Height != 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.Width != 0);
|
||||||
Assert.Contains(page.Letters, x => x.GlyphRectangleLoose.Height != 0);
|
Assert.Contains(page.Letters, x => x.GlyphRectangleLoose.Height != 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ namespace UglyToad.PdfPig.Tests.Integration
|
|||||||
{
|
{
|
||||||
var page = document.GetPage(1);
|
var page = document.GetPage(1);
|
||||||
|
|
||||||
Assert.Contains(page.Letters, x => x.GlyphRectangle.Width != 0);
|
Assert.Contains(page.Letters, x => x.BoundingBox.Width != 0);
|
||||||
Assert.Contains(page.Letters, x => x.GlyphRectangle.Height != 0);
|
Assert.Contains(page.Letters, x => x.BoundingBox.Height != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@
|
|||||||
|
|
||||||
foreach (var letter in page.Letters)
|
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())
|
foreach (var annotation in page.GetAnnotations())
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
{
|
{
|
||||||
foreach (var letter in page.Letters)
|
foreach (var letter in page.Letters)
|
||||||
{
|
{
|
||||||
DrawRectangle(letter.GlyphRectangle, canvas, redPaint, size.Height, Scale);
|
DrawRectangle(letter.BoundingBox, canvas, redPaint, size.Height, Scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
"UglyToad.PdfPig.Content.DocumentInformation",
|
"UglyToad.PdfPig.Content.DocumentInformation",
|
||||||
"UglyToad.PdfPig.Content.EmbeddedFile",
|
"UglyToad.PdfPig.Content.EmbeddedFile",
|
||||||
"UglyToad.PdfPig.Content.Hyperlink",
|
"UglyToad.PdfPig.Content.Hyperlink",
|
||||||
|
"UglyToad.PdfPig.Content.IBoundingBox",
|
||||||
"UglyToad.PdfPig.Content.InlineImage",
|
"UglyToad.PdfPig.Content.InlineImage",
|
||||||
"UglyToad.PdfPig.Content.IPageFactory`1",
|
"UglyToad.PdfPig.Content.IPageFactory`1",
|
||||||
"UglyToad.PdfPig.Content.IPdfImage",
|
"UglyToad.PdfPig.Content.IPdfImage",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
public class TestPdfImage : IPdfImage
|
public class TestPdfImage : IPdfImage
|
||||||
{
|
{
|
||||||
public PdfRectangle Bounds { get; set; }
|
public PdfRectangle BoundingBox { get; set; }
|
||||||
|
public PdfRectangle Bounds => BoundingBox;
|
||||||
|
|
||||||
public int WidthInSamples { get; set; }
|
public int WidthInSamples { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,10 @@
|
|||||||
var point = new PdfPoint(leftX, topPageY);
|
var point = new PdfPoint(leftX, topPageY);
|
||||||
DateTimeStampPage(pdfBuilder, page, point, cm);
|
DateTimeStampPage(pdfBuilder, page, point, cm);
|
||||||
var letters = page.AddText("Adobe Standard Font ZapfDingbats", 21, point, F2);
|
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);
|
point = new PdfPoint(leftX, newY);
|
||||||
letters = page.AddText("Font Specific encoding in Black (octal) and Unicode in Blue (hex)", 10, point, F2);
|
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);
|
point = new PdfPoint(leftX, newY);
|
||||||
var eachRowY = new List<double>();
|
var eachRowY = new List<double>();
|
||||||
eachRowY.Add(newY); // First row
|
eachRowY.Add(newY); // First row
|
||||||
@@ -216,10 +216,10 @@
|
|||||||
var point = new PdfPoint(leftX, topPageY);
|
var point = new PdfPoint(leftX, topPageY);
|
||||||
DateTimeStampPage(pdfBuilder, page, point, cm);
|
DateTimeStampPage(pdfBuilder, page, point, cm);
|
||||||
var letters = page.AddText("Adobe Standard Font Symbol ", 21, point, F2);
|
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);
|
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);
|
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);
|
var point = new PdfPoint(leftX, topPageY);
|
||||||
DateTimeStampPage(pdfBuilder, page, point, cm);
|
DateTimeStampPage(pdfBuilder, page, point, cm);
|
||||||
var letters = page.AddText("Adobe Standard Font " + fontName, 21, point, F2);
|
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);
|
point = new PdfPoint(leftX, newY);
|
||||||
letters = page.AddText("Font Specific encoding in Black, Unicode in Blue, Red only available using Unicode", 10, point, F2);
|
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);
|
point = new PdfPoint(leftX, newY);
|
||||||
|
|
||||||
|
|
||||||
@@ -799,10 +799,10 @@
|
|||||||
var labelPointSize = 5;
|
var labelPointSize = 5;
|
||||||
var octalString = System.Convert.ToString((int)stringToAdd[0], 8).PadLeft(3, '0');
|
var octalString = System.Convert.ToString((int)stringToAdd[0], 8).PadLeft(3, '0');
|
||||||
var label = octalString;
|
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 ml = page.MeasureText(label, labelPointSize, point, fontLabel);
|
||||||
var labelY = point.Y + ml.Max(v => v.GlyphRectangle.Height) * 0.1 + maxCharacterHeight;
|
var labelY = point.Y + ml.Max(v => v.BoundingBox.Height) * 0.1 + maxCharacterHeight;
|
||||||
var xLabel = codeMidPoint - (ml.Sum(v => v.GlyphRectangle.Width) / 2);
|
var xLabel = codeMidPoint - (ml.Sum(v => v.BoundingBox.Width) / 2);
|
||||||
var labelPoint = new PdfPoint(xLabel, labelY);
|
var labelPoint = new PdfPoint(xLabel, labelY);
|
||||||
page.AddText(label, labelPointSize, labelPoint, fontLabel);
|
page.AddText(label, labelPointSize, labelPoint, fontLabel);
|
||||||
}
|
}
|
||||||
@@ -812,10 +812,10 @@
|
|||||||
var labelPointSize = 3;
|
var labelPointSize = 3;
|
||||||
var hexString = $"{(int)stringToAdd[0]:X}".PadLeft(4, '0');
|
var hexString = $"{(int)stringToAdd[0]:X}".PadLeft(4, '0');
|
||||||
var label = "0x" + hexString;
|
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 ml = page.MeasureText(label, labelPointSize, point, fontLabel);
|
||||||
var labelY = point.Y - ml.Max(v => v.GlyphRectangle.Height) * 2.5;
|
var labelY = point.Y - ml.Max(v => v.BoundingBox.Height) * 2.5;
|
||||||
var xLabel = codeMidPoint - (ml.Sum(v => v.GlyphRectangle.Width) / 2);
|
var xLabel = codeMidPoint - (ml.Sum(v => v.BoundingBox.Width) / 2);
|
||||||
var labelPoint = new PdfPoint(xLabel, labelY);
|
var labelPoint = new PdfPoint(xLabel, labelY);
|
||||||
page.AddText(label, labelPointSize, labelPoint, fontLabel);
|
page.AddText(label, labelPointSize, labelPoint, fontLabel);
|
||||||
}
|
}
|
||||||
@@ -829,8 +829,8 @@
|
|||||||
double inch = (page.PageSize.Width / 8.5);
|
double inch = (page.PageSize.Width / 8.5);
|
||||||
double cm = inch / 2.54;
|
double cm = inch / 2.54;
|
||||||
|
|
||||||
var letterWidth = letter[0].GlyphRectangle.Width * 2;
|
var letterWidth = letter[0].BoundingBox.Width * 2;
|
||||||
var letterHeight = letter[0].GlyphRectangle.Height * 2;
|
var letterHeight = letter[0].BoundingBox.Height * 2;
|
||||||
|
|
||||||
var newX = point.X + maxCharacterWidth * 1.1;
|
var newX = point.X + maxCharacterWidth * 1.1;
|
||||||
var newY = point.Y;
|
var newY = point.Y;
|
||||||
@@ -892,7 +892,7 @@
|
|||||||
double maxCharacterWidth;
|
double maxCharacterWidth;
|
||||||
{
|
{
|
||||||
var point = new PdfPoint(10, 10);
|
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);
|
maxCharacterHeight = characterRectangles.Max(v => v.Height);
|
||||||
maxCharacterWidth = characterRectangles.Max(v => v.Height);
|
maxCharacterWidth = characterRectangles.Max(v => v.Height);
|
||||||
}
|
}
|
||||||
@@ -921,8 +921,8 @@
|
|||||||
{
|
{
|
||||||
var mtUTC = page.MeasureText(stampTextUTC, fontSize, point, courierFont);
|
var mtUTC = page.MeasureText(stampTextUTC, fontSize, point, courierFont);
|
||||||
var mtlocal = page.MeasureText(stampTextLocal, fontSize, point, courierFont);
|
var mtlocal = page.MeasureText(stampTextLocal, fontSize, point, courierFont);
|
||||||
var widthUTC = mtUTC.Sum(v => v.GlyphRectangle.Width);
|
var widthUTC = mtUTC.Sum(v => v.BoundingBox.Width);
|
||||||
var widthLocal = mtlocal.Sum(v => v.GlyphRectangle.Width);
|
var widthLocal = mtlocal.Sum(v => v.BoundingBox.Width);
|
||||||
|
|
||||||
indentFromLeft -= Math.Max(widthUTC, widthLocal);
|
indentFromLeft -= Math.Max(widthUTC, widthLocal);
|
||||||
}
|
}
|
||||||
@@ -930,7 +930,7 @@
|
|||||||
{
|
{
|
||||||
point = new PdfPoint(indentFromLeft, point.Y);
|
point = new PdfPoint(indentFromLeft, point.Y);
|
||||||
var letters = page.AddText(stampTextUTC, 7, point, courierFont);
|
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);
|
point = new PdfPoint(indentFromLeft, point.Y - maxHeight * 1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -328,9 +328,9 @@
|
|||||||
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
||||||
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
||||||
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer);
|
Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,9 +471,9 @@
|
|||||||
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
||||||
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
||||||
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer);
|
Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,13 +513,13 @@
|
|||||||
|
|
||||||
var topLine = new PdfPoint(30, page1.PageSize.Height - 60);
|
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);
|
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 page2Letters = page2.AddText("The very hungry caterpillar ate all the apples in the garden.", 12, topLine, font);
|
||||||
var left = page2Letters[0].GlyphRectangle.Left;
|
var left = page2Letters[0].BoundingBox.Left;
|
||||||
var bottom = page2Letters.Min(x => x.GlyphRectangle.Bottom);
|
var bottom = page2Letters.Min(x => x.BoundingBox.Bottom);
|
||||||
var right = page2Letters[page2Letters.Count - 1].GlyphRectangle.Right;
|
var right = page2Letters[page2Letters.Count - 1].BoundingBox.Right;
|
||||||
var top = page2Letters.Max(x => x.GlyphRectangle.Top);
|
var top = page2Letters.Max(x => x.BoundingBox.Top);
|
||||||
page2.SetStrokeColor(10, 250, 69);
|
page2.SetStrokeColor(10, 250, 69);
|
||||||
page2.DrawRectangle(new PdfPoint(left, bottom), right - left, top - bottom);
|
page2.DrawRectangle(new PdfPoint(left, bottom), right - left, top - bottom);
|
||||||
|
|
||||||
@@ -591,8 +591,8 @@
|
|||||||
|
|
||||||
Assert.NotNull(image);
|
Assert.NotNull(image);
|
||||||
|
|
||||||
Assert.Equal(expectedBounds.BottomLeft, image.Bounds.BottomLeft);
|
Assert.Equal(expectedBounds.BottomLeft, image.BoundingBox.BottomLeft);
|
||||||
Assert.Equal(expectedBounds.TopRight, image.Bounds.TopRight);
|
Assert.Equal(expectedBounds.TopRight, image.BoundingBox.TopRight);
|
||||||
|
|
||||||
Assert.Equal(imageBytes, image.RawMemory.ToArray());
|
Assert.Equal(imageBytes, image.RawMemory.ToArray());
|
||||||
}
|
}
|
||||||
@@ -637,10 +637,10 @@
|
|||||||
Assert.Equal(2, page1Images.Count);
|
Assert.Equal(2, page1Images.Count);
|
||||||
|
|
||||||
var image1 = page1Images[0];
|
var image1 = page1Images[0];
|
||||||
Assert.Equal(expectedBounds1, image1.Bounds);
|
Assert.Equal(expectedBounds1, image1.BoundingBox);
|
||||||
|
|
||||||
var image2 = page1Images[1];
|
var image2 = page1Images[1];
|
||||||
Assert.Equal(expectedBounds2, image2.Bounds);
|
Assert.Equal(expectedBounds2, image2.BoundingBox);
|
||||||
|
|
||||||
var page2Doc = document.GetPage(2);
|
var page2Doc = document.GetPage(2);
|
||||||
|
|
||||||
@@ -648,7 +648,7 @@
|
|||||||
|
|
||||||
Assert.NotNull(image3);
|
Assert.NotNull(image3);
|
||||||
|
|
||||||
Assert.Equal(expectedBounds3, image3.Bounds);
|
Assert.Equal(expectedBounds3, image3.BoundingBox);
|
||||||
|
|
||||||
Assert.Equal(imageBytes, image1.RawMemory.ToArray());
|
Assert.Equal(imageBytes, image1.RawMemory.ToArray());
|
||||||
Assert.Equal(imageBytes, image2.RawMemory.ToArray());
|
Assert.Equal(imageBytes, image2.RawMemory.ToArray());
|
||||||
@@ -724,8 +724,8 @@
|
|||||||
|
|
||||||
Assert.NotNull(image);
|
Assert.NotNull(image);
|
||||||
|
|
||||||
Assert.Equal(expectedBounds.BottomLeft, image.Bounds.BottomLeft);
|
Assert.Equal(expectedBounds.BottomLeft, image.BoundingBox.BottomLeft);
|
||||||
Assert.Equal(expectedBounds.TopRight, image.Bounds.TopRight);
|
Assert.Equal(expectedBounds.TopRight, image.BoundingBox.TopRight);
|
||||||
|
|
||||||
Assert.True(image.TryGetPng(out var png));
|
Assert.True(image.TryGetPng(out var png));
|
||||||
Assert.NotNull(png);
|
Assert.NotNull(png);
|
||||||
@@ -927,9 +927,9 @@
|
|||||||
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
Assert.Equal(readerLetter.Value, writerLetter.Value);
|
||||||
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
Assert.Equal(readerLetter.Location, writerLetter.Location, pointComparer);
|
||||||
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
Assert.Equal(readerLetter.FontSize, writerLetter.FontSize, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Width, writerLetter.GlyphRectangle.Width, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Width, writerLetter.BoundingBox.Width, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.Height, writerLetter.GlyphRectangle.Height, comparer);
|
Assert.Equal(readerLetter.BoundingBox.Height, writerLetter.BoundingBox.Height, comparer);
|
||||||
Assert.Equal(readerLetter.GlyphRectangle.BottomLeft, writerLetter.GlyphRectangle.BottomLeft, pointComparer);
|
Assert.Equal(readerLetter.BoundingBox.BottomLeft, writerLetter.BoundingBox.BottomLeft, pointComparer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/UglyToad.PdfPig/Content/IBoundingBox.cs
Normal file
15
src/UglyToad.PdfPig/Content/IBoundingBox.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace UglyToad.PdfPig.Content
|
||||||
|
{
|
||||||
|
using UglyToad.PdfPig.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for classes with a bounding box
|
||||||
|
/// </summary>
|
||||||
|
public interface IBoundingBox
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Bounding Box: The rectangle completely containing this object
|
||||||
|
/// </summary>
|
||||||
|
PdfRectangle BoundingBox { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,11 +12,13 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An image in a PDF document, may be an <see cref="InlineImage"/> or a PostScript image XObject (<see cref="XObjectImage"/>).
|
/// An image in a PDF document, may be an <see cref="InlineImage"/> or a PostScript image XObject (<see cref="XObjectImage"/>).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPdfImage
|
public interface IPdfImage: IBoundingBox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The placement rectangle of the image in PDF coordinates.
|
/// The placement rectangle of the image in PDF coordinates.
|
||||||
|
/// Kept so not major breaking API change. Use instead <see cref="IBoundingBox.BoundingBox"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Use BoundingBox instead.")]
|
||||||
PdfRectangle Bounds { get; }
|
PdfRectangle Bounds { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -19,7 +19,11 @@
|
|||||||
private readonly Lazy<Memory<byte>>? memoryFactory;
|
private readonly Lazy<Memory<byte>>? memoryFactory;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public PdfRectangle Bounds { get; }
|
public PdfRectangle BoundingBox { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[Obsolete("Use BoundingBox instead.")]
|
||||||
|
public PdfRectangle Bounds => BoundingBox;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int WidthInSamples { get; }
|
public int WidthInSamples { get; }
|
||||||
@@ -79,7 +83,7 @@
|
|||||||
IPdfImage? softMaskImage)
|
IPdfImage? softMaskImage)
|
||||||
{
|
{
|
||||||
IsInlineImage = true;
|
IsInlineImage = true;
|
||||||
Bounds = bounds;
|
BoundingBox = bounds;
|
||||||
WidthInSamples = widthInSamples;
|
WidthInSamples = widthInSamples;
|
||||||
HeightInSamples = heightInSamples;
|
HeightInSamples = heightInSamples;
|
||||||
Decode = decode;
|
Decode = decode;
|
||||||
@@ -138,7 +142,7 @@
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"Inline Image (w {Bounds.Width}, h {Bounds.Height})";
|
return $"Inline Image (w {BoundingBox.Width}, h {BoundingBox.Height})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A glyph or combination of glyphs (characters) drawn by a PDF content stream.
|
/// A glyph or combination of glyphs (characters) drawn by a PDF content stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Letter
|
public class Letter:IBoundingBox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The text for this letter or unicode character.
|
/// 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 <see cref="Location"/> they are placed at.
|
/// For example letters with descenders, p, j, etc., will have a box extending below the <see cref="Location"/> they are placed at.
|
||||||
/// The width of the glyph may also be more or less than the <see cref="Width"/> allocated for the character in the PDF content.
|
/// The width of the glyph may also be more or less than the <see cref="Width"/> allocated for the character in the PDF content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PdfRectangle GlyphRectangle { get; }
|
public PdfRectangle BoundingBox { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Bounding Box: The rectangle completely containing this object.
|
||||||
|
/// </summary>
|
||||||
|
[Obsolete("Use BoundingBox instead.")]
|
||||||
|
public PdfRectangle GlyphRectangle => BoundingBox;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The loose bounding box for the glyph. Contrary to the <see cref="GlyphRectangle"/>, 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 <see cref="BoundingBox"/>, the loose bounding box will be the same across all glyphes of the same font.
|
||||||
/// It takes in account the font Ascent and Descent.
|
/// It takes in account the font Ascent and Descent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PdfRectangle GlyphRectangleLoose { get; }
|
public PdfRectangle GlyphRectangleLoose { get; }
|
||||||
@@ -173,7 +179,7 @@
|
|||||||
int textSequence)
|
int textSequence)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = value;
|
||||||
GlyphRectangle = glyphRectangle;
|
BoundingBox = glyphRectangle;
|
||||||
GlyphRectangleLoose = glyphRectangleLoose;
|
GlyphRectangleLoose = glyphRectangleLoose;
|
||||||
StartBaseLine = startBaseLine;
|
StartBaseLine = startBaseLine;
|
||||||
EndBaseLine = endBaseLine;
|
EndBaseLine = endBaseLine;
|
||||||
@@ -207,7 +213,7 @@
|
|||||||
public Letter AsBold()
|
public Letter AsBold()
|
||||||
{
|
{
|
||||||
return new Letter(Value,
|
return new Letter(Value,
|
||||||
GlyphRectangle,
|
BoundingBox,
|
||||||
GlyphRectangleLoose,
|
GlyphRectangleLoose,
|
||||||
StartBaseLine,
|
StartBaseLine,
|
||||||
EndBaseLine,
|
EndBaseLine,
|
||||||
@@ -273,7 +279,7 @@
|
|||||||
|
|
||||||
private TextOrientation GetTextOrientationRot()
|
private TextOrientation GetTextOrientationRot()
|
||||||
{
|
{
|
||||||
double rotation = GlyphRectangle.Rotation;
|
double rotation = BoundingBox.Rotation;
|
||||||
if (Math.Abs(rotation % 90) >= 10e-5)
|
if (Math.Abs(rotation % 90) >= 10e-5)
|
||||||
{
|
{
|
||||||
return TextOrientation.Other;
|
return TextOrientation.Other;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A word.
|
/// A word.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Word
|
public class Word : IBoundingBox
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The text of the word.
|
/// The text of the word.
|
||||||
@@ -107,15 +107,15 @@
|
|||||||
blY = letter.StartBaseLine.Y;
|
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)
|
if (right > trX)
|
||||||
{
|
{
|
||||||
trX = right;
|
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;
|
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)
|
if (right < trX)
|
||||||
{
|
{
|
||||||
trX = right;
|
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;
|
r = letter.EndBaseLine.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
var right = letter.StartBaseLine.X + letter.GlyphRectangle.Height;
|
var right = letter.StartBaseLine.X + letter.BoundingBox.Height;
|
||||||
if (right > t)
|
if (right > t)
|
||||||
{
|
{
|
||||||
t = right;
|
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;
|
l = letter.StartBaseLine.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
var right = letter.StartBaseLine.X - letter.GlyphRectangle.Height;
|
var right = letter.StartBaseLine.X - letter.BoundingBox.Height;
|
||||||
if (right < t)
|
if (right < t)
|
||||||
{
|
{
|
||||||
t = right;
|
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)
|
if (letters.Count == 1)
|
||||||
{
|
{
|
||||||
return new(builder.ToString(), letters[0].GlyphRectangle);
|
return new(builder.ToString(), letters[0].BoundingBox);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -299,8 +299,8 @@
|
|||||||
{
|
{
|
||||||
r.StartBaseLine,
|
r.StartBaseLine,
|
||||||
r.EndBaseLine,
|
r.EndBaseLine,
|
||||||
r.GlyphRectangle.TopLeft,
|
r.BoundingBox.TopLeft,
|
||||||
r.GlyphRectangle.TopRight
|
r.BoundingBox.TopRight
|
||||||
}).Distinct().Select(p => inverseRotation.Transform(p));
|
}).Distinct().Select(p => inverseRotation.Transform(p));
|
||||||
|
|
||||||
var aabb = new PdfRectangle(transformedPoints.Min(p => p.X),
|
var aabb = new PdfRectangle(transformedPoints.Min(p => p.X),
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace UglyToad.PdfPig.Graphics
|
|||||||
|
|
||||||
letter = new Letter(
|
letter = new Letter(
|
||||||
newLetter,
|
newLetter,
|
||||||
attachTo.GlyphRectangle,
|
attachTo.BoundingBox,
|
||||||
attachTo.GlyphRectangleLoose,
|
attachTo.GlyphRectangleLoose,
|
||||||
attachTo.StartBaseLine,
|
attachTo.StartBaseLine,
|
||||||
attachTo.EndBaseLine,
|
attachTo.EndBaseLine,
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
continue;
|
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 gap = letter.Location.X - (lastLetter.Location.X + lastLetter.Width);
|
||||||
var nextToLeft = letter.Location.X < lastX.Value - 1;
|
var nextToLeft = letter.Location.X < lastX.Value - 1;
|
||||||
|
|||||||
@@ -19,7 +19,12 @@
|
|||||||
private readonly Lazy<Memory<byte>>? memoryFactory;
|
private readonly Lazy<Memory<byte>>? memoryFactory;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public PdfRectangle Bounds { get; }
|
public PdfRectangle BoundingBox { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
|
||||||
|
[Obsolete("Use BoundingBox instead.")]
|
||||||
|
public PdfRectangle Bounds => BoundingBox;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int WidthInSamples { get; }
|
public int WidthInSamples { get; }
|
||||||
@@ -85,7 +90,7 @@
|
|||||||
ColorSpaceDetails? colorSpaceDetails,
|
ColorSpaceDetails? colorSpaceDetails,
|
||||||
IPdfImage? softMaskImage)
|
IPdfImage? softMaskImage)
|
||||||
{
|
{
|
||||||
Bounds = bounds;
|
BoundingBox = bounds;
|
||||||
WidthInSamples = widthInSamples;
|
WidthInSamples = widthInSamples;
|
||||||
HeightInSamples = heightInSamples;
|
HeightInSamples = heightInSamples;
|
||||||
BitsPerComponent = bitsPerComponent;
|
BitsPerComponent = bitsPerComponent;
|
||||||
@@ -121,7 +126,7 @@
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"XObject Image (w {Bounds.Width}, h {Bounds.Height}): {ImageDictionary}";
|
return $"XObject Image (w {BoundingBox.Width}, h {BoundingBox.Height}): {ImageDictionary}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user