react-pdf icon indicating copy to clipboard operation
react-pdf copied to clipboard

SVG elements are missing interpretation of dx and dy values

Open dennemark opened this issue 4 years ago • 2 comments

Describe the bug As described in this issue: https://github.com/diegomura/react-pdf/issues/1234 Text, T-Span and Rect elements (maybe others, too) are not considering dx and dy values for relative positioning.

To Reproduce Take this svg i.e. Each color has a different relative positioning to the parent.

  • If the child has a x or y property, it will favour it over the parent property and position itself absolute. In this case dx and dy will be ignore, too.
  • If the x or y porperty is missing it will be positioned relative to parent.
  • If dx or dy exist, they will be added to the parent
<svg width="500" height="500">
    <text x="10" y="10" width="90" height="60">
		<tspan dx="10" dy="10" width="20" height="10" fill="blue">text</tspan>
    </text>
    <text x="10" y="10" width="90" height="60" >
    	<tspan x="10" dy="10" fill="red">text</tspan>
    </text>
  <text x="10" y="10" width="90" height="60" fill="green">
 	 <tspan x="10" y="10">text</tspan>
   </text>
</svg>

image

The result of react-pdf has all text elements at position x=10 and y=10: image

The issue seems only relevant for conversion from existing svgs to react-pdf svg. The above mentioned issue has examples on how to convert from SVG to react-pdf SVG with consideration of parent position.

dennemark avatar Apr 28 '21 07:04 dennemark

This should be fixed

diegomura avatar Mar 03 '25 20:03 diegomura

@diegomura Still not working as expected for me in the latest 4.3.0 release.

A <Tspan> with and without a dy value seems to render in the same position. See REPL. The code is:

const Sample = () => (
  <Document>
    <Page>
      <Svg debug={true} height={100} width={200}>
      	<Text x={50} y={50}>
          <Tspan x={50} dy={75}>With dy</Tspan>
        </Text>
      </Svg>
      
      <Svg debug={true} height={100} width={200}>
      	<Text x={50} y={50}>
          <Tspan x={50}>Without dy</Tspan>
        </Text>
      </Svg>
    </Page>
  </Document>
);

ReactPDF.render(<Sample />);

Renders as:

Image

The same equivalent in HTML:

<div style={{display: 'flex', flexDirection: 'column'}}>
  <svg debug={true} height={100} width={200} style={{border: '1px solid black'}}>
    <text x={50} y={50}>
      <tspan x={50} dy={75}>With dy</tspan>
    </text>
  </svg>

  <svg debug={true} height={100} width={200} style={{border: '1px solid black'}}>
    <text x={50} y={50}>
      <tspan x={50}>Without dy</tspan>
    </text>
  </svg>
</div>

Renders like this:

Image

Note how in the top box (the only with dy) the text is pushed outside the SVG boundary and doesn't show up at all.

EvHaus avatar Mar 05 '25 04:03 EvHaus