mirror of
https://github.com/UglyToad/PdfPig.git
synced 2025-10-15 19:54:52 +08:00
Improve minimum bounding box orientation
This commit is contained in:
@@ -266,6 +266,12 @@
|
|||||||
|
|
||||||
private Tuple<string, PdfRectangle> GetBoundingBoxOther(IReadOnlyList<Letter> letters)
|
private Tuple<string, PdfRectangle> GetBoundingBoxOther(IReadOnlyList<Letter> letters)
|
||||||
{
|
{
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
for (var i = 0; i < letters.Count; i++)
|
||||||
|
{
|
||||||
|
builder.Append(letters[i].Value);
|
||||||
|
}
|
||||||
|
|
||||||
var points = letters.SelectMany(r => new[]
|
var points = letters.SelectMany(r => new[]
|
||||||
{
|
{
|
||||||
r.StartBaseLine,
|
r.StartBaseLine,
|
||||||
@@ -274,47 +280,53 @@
|
|||||||
r.GlyphRectangle.TopRight
|
r.GlyphRectangle.TopRight
|
||||||
}).Distinct();
|
}).Distinct();
|
||||||
var convexHull = GeometryExtensions.GrahamScan(points).ToList();
|
var convexHull = GeometryExtensions.GrahamScan(points).ToList();
|
||||||
var minimalBoundingRectangle = GeometryExtensions.ParametricPerpendicularProjection(convexHull);
|
var mbr = GeometryExtensions.ParametricPerpendicularProjection(convexHull);
|
||||||
|
var mbrPoints = new[] { mbr.TopLeft, mbr.TopRight, mbr.BottomLeft, mbr.BottomRight };
|
||||||
var builder = new StringBuilder();
|
|
||||||
for (var i = 0; i < letters.Count; i++)
|
|
||||||
{
|
|
||||||
builder.Append(letters[i].Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Find the orientation of the minimum bounding box, using the baseline angle.
|
||||||
|
// This method needs improvment as the baseline angle and the bbox angle can
|
||||||
|
// belong to different quadrants of the unit circle.
|
||||||
var firstLetter = letters[0];
|
var firstLetter = letters[0];
|
||||||
var lastLetter = letters[letters.Count - 1];
|
var lastLetter = letters[letters.Count - 1];
|
||||||
var rotation = Math.Atan2(
|
var rotation = Math.Atan2(
|
||||||
lastLetter.EndBaseLine.Y - firstLetter.StartBaseLine.Y,
|
lastLetter.EndBaseLine.Y - firstLetter.StartBaseLine.Y,
|
||||||
lastLetter.EndBaseLine.X - firstLetter.StartBaseLine.X);
|
lastLetter.EndBaseLine.X - firstLetter.StartBaseLine.X);
|
||||||
|
|
||||||
if (rotation >= -0.785398 && rotation < 0.785398)
|
if (rotation >= -Math.PI && rotation <= -1.570796) // (-180 to -90deg)
|
||||||
{
|
{
|
||||||
// top border on top
|
var br = mbrPoints.OrderBy(p => p.X).ThenByDescending(p => p.Y).First();
|
||||||
//return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(minX, minY, maxX, maxY));
|
var bl = mbrPoints.OrderByDescending(p => p.Y).ThenByDescending(p => p.X).First();
|
||||||
return new Tuple<string, PdfRectangle>(builder.ToString(), minimalBoundingRectangle);
|
var tl = mbrPoints.OrderByDescending(p => p.Y).ThenBy(p => p.X).First();
|
||||||
|
var tr = mbrPoints.OrderBy(p => p.X).ThenBy(p => p.Y).First();
|
||||||
|
return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(tl, tr, bl, br));
|
||||||
}
|
}
|
||||||
else if (rotation >= 0.785398 && rotation < 2.356194)
|
else if (rotation > -1.570796 && rotation <= 0.0) // (-90deg to 0)
|
||||||
{
|
{
|
||||||
// top border on the left
|
var bl = mbrPoints.OrderBy(p => p.X).ThenBy(p => p.Y).First();
|
||||||
//return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(
|
var tl = mbrPoints.OrderByDescending(p => p.Y).ThenBy(p => p.X).First();
|
||||||
// new PdfPoint(minX, minY), new PdfPoint(minX, maxY),
|
var tr = mbrPoints.OrderByDescending(p => p.X).ThenByDescending(p => p.Y).First();
|
||||||
// new PdfPoint(maxX, minY), new PdfPoint(maxX, maxY)));
|
var br = mbrPoints.OrderBy(p => p.Y).ThenByDescending(p => p.X).First();
|
||||||
return new Tuple<string, PdfRectangle>(builder.ToString(), minimalBoundingRectangle);
|
return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(tl, tr, bl, br));
|
||||||
}
|
}
|
||||||
else if (rotation >= 2.356194 && rotation < 3.926991)
|
else if (rotation > 0.0 && rotation <= 1.570796) // (0 to 90deg)
|
||||||
{
|
{
|
||||||
// top border on the bottom
|
var tl = mbrPoints.OrderBy(p => p.X).ThenByDescending(p => p.Y).First();
|
||||||
//return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(minX, maxY, maxX, minY));
|
var bl = mbrPoints.OrderBy(p => p.Y).ThenBy(p => p.X).First();
|
||||||
return new Tuple<string, PdfRectangle>(builder.ToString(), minimalBoundingRectangle);
|
var br = mbrPoints.OrderByDescending(p => p.X).ThenBy(p => p.Y).First();
|
||||||
|
var tr = mbrPoints.OrderByDescending(p => p.Y).ThenByDescending(p => p.X).First();
|
||||||
|
return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(tl, tr, bl, br));
|
||||||
|
}
|
||||||
|
else if (rotation > 1.570796 && rotation <= Math.PI) // (90 to 180deg)
|
||||||
|
{
|
||||||
|
var tr = mbrPoints.OrderBy(p => p.X).ThenBy(p => p.Y).First();
|
||||||
|
var bl = mbrPoints.OrderByDescending(p => p.X).ThenByDescending(p => p.Y).First();
|
||||||
|
var br = mbrPoints.OrderByDescending(p => p.Y).ThenBy(p => p.X).First();
|
||||||
|
var tl = mbrPoints.OrderBy(p => p.X).ThenByDescending(p => p.Y).First();
|
||||||
|
return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(tl, tr, bl, br));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// top border on the right
|
throw new ArgumentOutOfRangeException(nameof(rotation), "Word orientation not handled.");
|
||||||
//return new Tuple<string, PdfRectangle>(builder.ToString(), new PdfRectangle(
|
|
||||||
// new PdfPoint(maxX, maxY), new PdfPoint(maxX, minY),
|
|
||||||
// new PdfPoint(minX, maxY), new PdfPoint(minX, minY)));
|
|
||||||
return new Tuple<string, PdfRectangle>(builder.ToString(), minimalBoundingRectangle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
Reference in New Issue
Block a user