SVG icon indicating copy to clipboard operation
SVG copied to clipboard

Bounds not correctly computed for texts and groups

Open Moggel12 opened this issue 1 year ago • 5 comments

Both text elements with multiple child tspan elements, and group elements, incorrectly compute the bounding box. Have not tested other elements.

Example: creating a text element with three tspans internally (using the dy property to simulate newlines) and calling .Bounds will return a box that does not fit the entire text nor is positioned correctly. Putting the text element inside a group will act likewise. Atleast this is the case when trying to render the box via a rect element in an SVG file. In my case font-size is set to 15 with Sans-Serif font family. Using text-anchor or dominant-baseline does not seem to help either.

Using SVG v3.4.6 and .NET 7.

Moggel12 avatar Feb 07 '24 11:02 Moggel12

@Moggel12 It will help a lot if you provide a sample.

paulushub avatar Feb 07 '24 11:02 paulushub

Sure, something like this? @paulushub

using Svg;

var document = new SvgDocument()
{
    Width = new SvgUnit(SvgUnitType.Inch, 10),
    Height = new SvgUnit(SvgUnitType.Inch, 10),
    FontSize = 15,
    FontFamily = "Sans-Serif",
};

var svgGroup = new SvgGroup();

float x = 100, y = 100;

var xLocation = new SvgUnitCollection();
var yLocation = new SvgUnitCollection();

xLocation.Add(x);
yLocation.Add(y);

var textBox = new SvgText
{
    X = xLocation,
    Y = yLocation
};

var lines = new List<string>()
{
    "This is",
    "a multiline",
    "test"
};

float offset = 0;

foreach (var line in lines)
{
    var unit = new SvgUnit(SvgUnitType.Em, offset);
    var yOffset = new SvgUnitCollection
    {
        unit
    };

    var textSpan = new SvgTextSpan
    {
        Text = line,
        Dy = yOffset,
        X = xLocation,
    };

    textBox.Children.Add(textSpan);
    offset += 1F;
}

textBox.AddStyle("fill", "black", 0);
textBox.AddStyle("font-size", "inherit", 0);

svgGroup.Children.Add(textBox);

var boundingBox = new SvgRectangle
{
    X = textBox.Bounds.X,
    Y = textBox.Bounds.Y,
    Width = textBox.Bounds.Width,
    Height = textBox.Bounds.Height
};

boundingBox.AddStyle("fill", "none", 0);
boundingBox.AddStyle("stroke", "black", 0);

svgGroup.Children.Add(boundingBox);

document.Children.Add(svgGroup);

var completePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "test.svg");

document.Write(completePath, false);

Moggel12 avatar Feb 07 '24 12:02 Moggel12

Alright, just spotted that the problem only occurs when elements are added to a group prior to being added to an SvgDocument. I edited the previous comment so that the problem actually occurs. Sorry!

Moggel12 avatar Feb 07 '24 12:02 Moggel12

@Moggel12 Thanks for the illustration. Please, is this related to #946 ?

paulushub avatar Feb 07 '24 12:02 paulushub

@Moggel12 Thanks for the illustration. Please, is this related to #946 ?

It may be an extension to it, but I don't believe it to be the same. In my case, no transformations have been added to the group. However, it does look like #946 adds elements to the group first and then adds the group to the document, so maybe the same root cause?

Moggel12 avatar Feb 07 '24 12:02 Moggel12