question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Invalid Cast Exception when updating SvgText Coordinates

See original GitHub issue

The issue is happening when you want to update SvgText.X property value with a new one.

if you run this unit test you will see the error:

[Test]
public void TestUpdateCoordinatesForCollectionChange()
{
    SvgText text = new SvgText()
    {
        Text = "Test coordinates",
        X = { 10 },
        Y = { 30 },
        Dx = { 40 },
        Dy = { 50 }
    };

    text.X = new SvgUnitCollection() { 20 };  // <- This line throws an Invalid Cast Exception

    var xml = text.GetXML();
    Assert.IsTrue(xml.Contains("x=\"20\""));
    Assert.IsTrue(xml.Contains("y=\"30\""));
    Assert.IsTrue(xml.Contains("dx=\"40\""));
    Assert.IsTrue(xml.Contains("dy=\"50\""));
}

Exception detail

System.InvalidCastException
  HResult=0x80004002
  Message=Unable to cast object of type 'Svg.SvgUnitCollection' to type 'Svg.SvgUnit'.
  Source=Svg
  StackTrace:
   at Svg.SvgAttributeCollection.UnboxAndCheck[T](Object a, Object b) in C:\Projects\Svg-Net\SVG\Source\SvgAttributeCollection.cs:line 136
   at Svg.SvgAttributeCollection.TryUnboxedCheck(Object a, Object b) in C:\Projects\Svg-Net\SVG\Source\SvgAttributeCollection.cs:line 118
   at Svg.SvgAttributeCollection.set_Item(String attributeName, Object value) in C:\Projects\Svg-Net\SVG\Source\SvgAttributeCollection.cs:line 99
   at Svg.SvgTextBase.set_X(SvgUnitCollection value) in C:\Projects\Svg-Net\SVG\Source\Text\SvgTextBase.cs:line 70
   at Svg.UnitTests.SvgTextTests.TestWritesCoordinatesForCollectionChange2() in C:\Projects\Svg-Net\SVG\Tests\Svg.UnitTests\SvgTextTests.cs:line 102

From the code reference below you can see this happens in line 70

https://github.com/svg-net/SVG/blob/e37e4441641806205b6aeb055864a899de1adc36/Source/Text/SvgTextBase.cs#L56-L78

We can see the following

From the

  • _x -> Type = SvgUnitCollection
  • incoming value -> Type = SvgUnitCollection
  • Attributes[“x”] -> Type = SvgUnit

So when line 70 is executed it throws an invalid case exception Attributes["x"] = value; .

My observations

  • It’s valid for a SvgText element to have multiple values for X property as described in MDN page, so passing a collection is valid
  • From the current code, We can see that it only stores the first element in the collection, see line 76 from referenced code. So I assume multiple values are not supported yet.
  • As coding practice we may want or not (it depends on what we want to do) overwrite a property that it has a collection, I guess most of the times we don’t want to allow that, but in this case I think it is a good behavior, since you can update a set of values (in the furture) without the need of empty the current collection and then populate by using Collection.Add property, it is not too friendly in this case in my opinion

Proposal

Having said this, I think the SvgText.X property should allow direct collection assignment following the current implementation, that is only supporting one single value for X property by now.

Based on what we have on line 76 I updated line 70 and it worked.

[SvgAttribute("x")]
public virtual SvgUnitCollection X
{
    get { return _x; }
    set
    {
        if (_x != value)
        {
            if (_x != null) _x.CollectionChanged -= OnXChanged;
            _x = value;
            if (_x != null) _x.CollectionChanged += OnXChanged;

            IsPathDirty = true;
        }
        Attributes["x"] = value.FirstOrDefault(); // <- Adding FirstOrDefault sends the SVGUnit value and no cast exception happens
    }
}

Notes

  • Let me know if you agree with my approach, so I can create the PR. Btw The same behavior is in Y, Dx & Dy properties

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
mrbean-bremencommented, Mar 19, 2022

Ok, I made a new bugfix release (3.4.1).

1reaction
H1Gdevcommented, Feb 17, 2022

This is due to setting only first element in OnXChanged(and others).

Read more comments on GitHub >

github_iconTop Results From Across the Web

JS error after setAttribute on SVG element is not catchable
I am working on a web tool, which lets you change attributes of SVG elements. Currently I am trying to give the user...
Read more >
Coordinate Systems, Transformations and Units — SVG 2
Computing the equivalent transform of an SVG viewport. This process converts the min-x, min-y, width and height values of a viewBox attribute, the...
Read more >
[Android] [Reanimated] crash with react-native-svg 13.0.0
Everything works fine on iOS. And I have a fatal crash with this error: Fatal Exception: java.lang.NullPointerException Attempt to invoke ...
Read more >
How to Translate from DOM to SVG Coordinates and Back ...
Mix DOM and vector interactions in SVG, translating from SVG to DOM coordinates and back, and translating to transformed SVG coordinates.
Read more >
Balisage Paper: How long is my SVG <text> element?
Abstract. SVG layout requires that the developer be in control of the dimensions of the objects that must be placed in the coordinate...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found