Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Support retaining whitespace in DrawingGroups

Open poppeman opened this issue 7 months ago • 3 comments

Is your feature request related to a problem? Please describe.

Issue/problem

DrawingGroup seemingly trims away whitespace, which can cause design issues.

User story

Imagine that you want to create a spinner by creating a drawing in Inkscape and then add an animation that rotates said image.

Example xaml:

<DrawingGroup x:Key="Spinner">
    <DrawingGroup.ClipGeometry>
        <RectangleGeometry Rect="0.0,0.0,32.0,32.0"/>
    </DrawingGroup.ClipGeometry>

    <GeometryDrawing>
        <GeometryDrawing.Pen>
            <Pen Brush="#ffffffff" LineJoin="Miter" Thickness="2.0"/>
        </GeometryDrawing.Pen>
        <GeometryDrawing.Geometry>
            <PathGeometry Figures="M 31.082 16 A 15.082 15.0815 0 0 1 25.8947 27.3822" FillRule="NonZero" />
       </GeometryDrawing.Geometry>
    </GeometryDrawing>
</DrawingGroup>

The image looks like this, note that there's some white space around the arc, especially to the left: Image

Unfortunately, Avalonia seems to trim away the empty space of the drawing (or rather, build the bounding rect by taking the union of the child nodes), causing the arc to spin around it's own center (like a boomerang) rather than the center of the drawing.

Describe the solution you'd like

It would be great if this behavior could be tweaked so that the bounds were defined by the ClipGeometry instead.

Preferably without touching the xaml, as it would be very nice to be able to not touch files exported from Inkscape (or whatever software one is using).

Describe alternatives you've considered

This issue can be worked around by adding an invisible rectangle to the DrawingGroup that covers the visible area:

  <GeometryDrawing Brush="Transparent">
      <GeometryDrawing.Geometry>
          <RectangleGeometry Rect="0.0,0.0,32.0,32.0"/>
      </GeometryDrawing.Geometry>
  </GeometryDrawing>

Additional context

https://github.com/AvaloniaUI/Avalonia/blob/aaf6fe9cb64316ce03f6134a166f918b60e8a399/src/Avalonia.Base/Media/DrawingGroup.cs#L89-L104

poppeman avatar May 15 '25 18:05 poppeman

Clip is only used for rendering, it won't affect the layout. Adding the invisible rectangle is the intended way to achieve the effect that you want, and is also how WPF works.

With that said, I can see that GeometryDrawing has a GetBounds method. It's easy to add a new Rect? Frame property to the class, and then do this:

public override Rect GetBounds() => Frame ?? Geometry?.GetRenderBounds(Pen ?? s_boundsPen) ?? default;

Then it becomes possible to do this in XAML:

<GeometryDrawing Frame="0,0,32,32">

And everything works the way you want. Seems like a sensible change to me.

TomEdwardsEnscape avatar May 19 '25 20:05 TomEdwardsEnscape

True, reusing the dimensions from ClipGeometry would technically work in this particular case, but be quite hacky and probably break other things. A new property is way cleaner, and shouldn't be too much of a hassle for Inkscape etc to implement.

poppeman avatar May 25 '25 20:05 poppeman

invisible rectangle

This is the intended way of specifying extra space. It's the same as in WPF.

kekekeks avatar May 26 '25 13:05 kekekeks