| 522 | |
| 523 | |
| 524 | def _text_block(parent, item, color, fs, family, font=None): |
| 525 | from PySide6.QtGui import QFontMetricsF |
| 526 | pos = item.pos() |
| 527 | # QGraphicsTextItem.pos() is the top-left of the document frame. |
| 528 | # SVG <text y="…"> anchors the baseline; offset by the document margin and |
| 529 | # the font ascent so the first baseline lands in the right place. |
| 530 | doc_margin = item.document().documentMargin() if hasattr(item, 'document') else 0.0 |
| 531 | if font is not None: |
| 532 | fm = QFontMetricsF(font) |
| 533 | ascent = fm.ascent() |
| 534 | line_h = fm.lineSpacing() |
| 535 | else: |
| 536 | ascent = fs * 0.8 |
| 537 | line_h = fs * 1.5 |
| 538 | x0 = pos.x() + doc_margin |
| 539 | baseline_y = pos.y() + doc_margin + ascent |
| 540 | lines = item.toPlainText().splitlines() |
| 541 | for i, line in enumerate(lines): |
| 542 | if not line.strip(): |
| 543 | continue |
| 544 | t = ET.SubElement(parent, f"{{{_SVG_NS}}}text") |
| 545 | t.set("x", f"{x0:.2f}") |
| 546 | t.set("y", f"{baseline_y + i * line_h:.2f}") |
| 547 | t.set("font-family", family) |
| 548 | t.set("font-size", f"{fs}pt") |
| 549 | t.set("fill", color) |
| 550 | t.text = line |
| 551 | |
| 552 | |
| 553 | _DASH_ARRAY = { |