Search code examples
svginkscapelibreoffice-draw

Merging two SVG Paths: Open Bezier and Line


The merge portion of my question has been well answered here: https://stackoverflow.com/a/49051988/4272389 which resolved two LineGradients with one line node and the other a path node.

In my situation I have an Open Bezier path and a Line path and am not sure if that answer for LineGradient still applies

<g class="com.sun.star.drawing.OpenBezierShape">
 <g id="id5">
  <rect class="BoundingBox" stroke="none" fill="none" x="7699" y="4699" width="303" height="203"/>
  <path fill="none" stroke="rgb(52,101,164)" d="M 7700,4900 C 7816,4847 7964,4842 8000,4700"/>
 </g>
</g>
<g class="com.sun.star.drawing.LineShape">
 <g id="id6">
  <rect class="BoundingBox" stroke="none" fill="none" x="8799" y="6099" width="30" height="3"/>
  <path fill="none" stroke="rgb(52,101,164)" d="M 8800,6100 L 8827,6100"/>
 </g>
</g>

Using the viewbox transform procedure suggested in the prior answer (https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform), would the merge entail the expanding the bounding box then using the origin from id5 and then converting id6 coordinates into relative values inside the expanded box I call "merged"?: My arithmetic expression is pseudo code to indicate my transform formula)

<g id="merged">
  <rect class="BoundingBox" stroke="none" fill="none" x="8799" y="6099" width="300+(8799-7699)+30" height="203+(6100-4699)+3"/>
  <path fill="none" stroke="rgb(52,101,164)" d="M 7700,4900 C 7816,4847 7964,4842 8000,4700 m [(8799-7699) + (8800-8799), (6099-4699) + (6100-6099)] l (8827-8799),(6100-6099)"/>
</g>

Reason: The fragments were drawn with LibreOffice draw and the paths were joined using Inkscape, but I could not do so fully, so I have to manually close the paths in the final Inkscape result.


Solution

  • Paths can have multiple subpaths. So most of the time, you can just append them together, like so:

    d="M 7700,4900 C 7816,4847 7964,4842 8000,4700 M 8800,6100 L 8827,6100"/>
    

    The only thing you need to watch for is if the move command in the second path is a lower-case m. In a single path, starting with an m (relative move) is an error, and it is interpreted as a M (absolute move). But if you append it to another path, a lower-case m would be valid. So you would need to change the m to an M when appending.

    As for the bounding box, you just need to do a "union" operation. In other words finding the min and max X and Y coords of the two rectangles.

    Box 1: minX="7699" minY="4699" maxX="7699 + 303 = 8002" maxY="4699 + 203 = 4902"
    Box 2: minX="8799" minY="6099" maxX="8799 + 30 = 8829" maxY="6099 + 3 = 6102"
    
    Union: minX="7699" minY="4699" maxX="8829" maxY="6102"
    Box:   x="7699" y="4699" width="1130" height="1403"
    

    So the merged paths should be:

    <g id="merged">
      <rect class="BoundingBox" stroke="none" fill="none" x="7699" y="4699" width="1130" height="1403"/>
      <path fill="none" stroke="rgb(52,101,164)" d="M 7700,4900 C 7816,4847 7964,4842 8000,4700 M 8800,6100 L 8827,6100"/>
    </g>