yWorks / svg2pdf.js

A javascript-only SVG to PDF conversion utility that runs in the browser. Brought to you by yWorks - the diagramming experts
MIT License
643 stars 96 forks source link

tspan dx makes incorrect offset #269

Open edemaine opened 11 months ago

edemaine commented 11 months ago

Describe the bug <tspan dx="..."> seems to offset by an incorrect amount.

svg2pdf.js@2.2.0 jspdf@2.5.1

To Reproduce Playground

SVG for reference:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="118.55218505859375 236.08206176757812 49.96488952636719 24.615386962890625" width="49.96488952636719px" height="24.615386962890625px">
  <g transform="translate(117.16923522949219,255.77438354492188)">
    <text fill="black" style="font-size:19px">
      <tspan data-tex="x" dx="12.858478000000002"> </tspan>
      is
      <tspan data-tex="y" dx="11.020133000000001"> </tspan>
    </text>
    <g transform="translate(0.5961534477920516 -9.72823342590332) scale(19)">
      <svg xmlns="http://www.w3.org/2000/svg" width="0.6767620000000001" height="0.536075" role="img" focusable="false" viewBox="0 -442 572 453" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="MJX-1-TEX-I-1D465" d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z"/></defs><g stroke="black" fill="black" stroke-width="0" transform="scale(1,-1)"><g><g><use xlink:href="#MJX-1-TEX-I-1D465"/></g></g></g></svg>
    </g>
    <g transform="translate(39.73155750693512 -9.920076425903321) scale(19)">
      <svg xmlns="http://www.w3.org/2000/svg" width="0.580007" height="0.765672" role="img" focusable="false" viewBox="0 -442 490 647" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="MJX-2-TEX-I-1D466" d="M21 287Q21 301 36 335T84 406T158 442Q199 442 224 419T250 355Q248 336 247 334Q247 331 231 288T198 191T182 105Q182 62 196 45T238 27Q261 27 281 38T312 61T339 94Q339 95 344 114T358 173T377 247Q415 397 419 404Q432 431 462 431Q475 431 483 424T494 412T496 403Q496 390 447 193T391 -23Q363 -106 294 -155T156 -205Q111 -205 77 -183T43 -117Q43 -95 50 -80T69 -58T89 -48T106 -45Q150 -45 150 -87Q150 -107 138 -122T115 -142T102 -147L99 -148Q101 -153 118 -160T152 -167H160Q177 -167 186 -165Q219 -156 247 -127T290 -65T313 -9T321 21L315 17Q309 13 296 6T270 -6Q250 -11 231 -11Q185 -11 150 11T104 82Q103 89 103 113Q103 170 138 262T173 379Q173 380 173 381Q173 390 173 393T169 400T158 404H154Q131 404 112 385T82 344T65 302T57 280Q55 278 41 278H27Q21 284 21 287Z"/></defs><g stroke="black" fill="black" stroke-width="0" transform="scale(1,-1)"><g><g><use xlink:href="#MJX-2-TEX-I-1D466"/></g></g></g></svg>
    </g>
  </g>
</svg>

Expected behavior SVG displays with correct offset:

image

Screenshots PDF displays a smaller offset for the "is" text:

image

If I chain more such tspans, the reduced horizontal offset accumulates, and the SVG glyphs start overlapping with the text.

Desktop

Additional context This arises in SVG generated by my Cocreate software, which renders regular text along with LaTeX rendered by MathJax.

HackbrettXXX commented 11 months ago

Thanks for this bug report. I think the issue is not that the dx is applied in a wrong way but that the space in

<tspan data-tex="x" dx="12.858478000000002"> </tspan>

is trimmed away. The space is a unicode 8202 hair space character. If you replace the hair space with a letter it seems to work as expected.

I think the trim functions use the wrong character set: https://github.com/yWorks/svg2pdf.js/blob/07b8ca12bc8f622c36514ce3899464be526048e6/src/utils/text.ts#L60-L66

I would consider this a very minor bug, because I would argue that this is not best the way to achieve the drawing. Why not apply the dx to the word itself? Nevertheless, I would accept a pull request.