jsvg icon indicating copy to clipboard operation
jsvg copied to clipboard

<textpath> doesn't support transform property

Open rensx opened this issue 6 months ago β€’ 7 comments

my_path1 and my_path2 was overlapped.

Image

rensx avatar Jun 24 '25 12:06 rensx

Could you please elaborate a bit more? What is the SVG source and what exactly is overlapping?

weisJ avatar Jun 24 '25 13:06 weisJ

Image

rensx avatar Jun 24 '25 22:06 rensx

import javax.swing.; import java.awt.; import java.net.URL; import com.jsvg.view.ViewBox;

import com.jsvg.; import com.jsvg.attributes.; import com.jsvg.parser.*;

import java.util.Objects;

public class RenderExample {

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        SVGLoader loader = new SVGLoader();

        URL svgUrl =

RenderExample.class.getResource("assets/textpath.svg"); SVGDocument document = loader.load(Objects.requireNonNull(svgUrl, "SVG file not found"));

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(400, 400));
        frame.setContentPane(new

SVGPanel(Objects.requireNonNull(document))); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); }); }

static class SVGPanel extends JPanel {
    private final SVGDocument document;

    SVGPanel(SVGDocument document) {
        this.document = document;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        ((Graphics2D) g).setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        ((Graphics2D) g).setRenderingHint(
            RenderingHints.KEY_STROKE_CONTROL,
            RenderingHints.VALUE_STROKE_PURE);

        document.render(this, (Graphics2D) g, new ViewBox(0, 0,

getWidth(), getHeight())); } } }

<path id="my_path1" d="M 50 100 Q 25 10 180 100 T 350 100 T 520 100 T

690 100" fill="transparent" /> <textPath href ="#my_path1"> πŸ₯³πŸ§πŸ°πŸŽπŸŽ‚πŸŽˆ. </textPath> <textPath href ="#my_path2"> πŸ₯³πŸ§πŸ°πŸŽπŸŽ‚πŸŽˆ </textPath>

Jannis Weis @.***> 于2025εΉ΄6月24ζ—₯ε‘¨δΊŒ 21:07ε†™ι“οΌš

weisJ left a comment (weisJ/jsvg#136) https://github.com/weisJ/jsvg/issues/136#issuecomment-3000426188

Could you please elaborate a bit more? What is the SVG source and what exactly is overlapping?

β€” Reply to this email directly, view it on GitHub https://github.com/weisJ/jsvg/issues/136#issuecomment-3000426188, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALBRNZJ2I4AECZOTZM3ZWZT3FFESVAVCNFSM6AAAAACAADC3GCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAMBQGQZDMMJYHA . You are receiving this because you authored the thread.Message ID: @.***>

rensx avatar Jun 24 '25 22:06 rensx

A simplified (IMO) example:

<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
  <style>
    svg {
      font-weight: bold;
      font-size: 16px;
      font-family: sans-serif;
    }
  </style>
  <defs>
    <path id="my_path1" d="M 50 100 Q 25 10 180 100 T 350 100 T 520 100 T 690 100"/>
    <path id="my_path2" d="M 50 100 Q 25 10 180 100 T 350 100" transform="translate(0,75)"/>
  </defs>
  <text>
    <textPath href="#my_path1" fill="green">A B C D E F</textPath>
    <textPath href="#my_path2" fill="red">A B C</textPath>
  </text>
</svg>
Batik JSVG
Batik JSVG

It seems the transform on the second path is not applied when used with <textPath>.

stanio avatar Jun 25 '25 03:06 stanio

In addition, jsvg didn't support color emoji. The only one(java) that supports color emoji I known is PDFlib.

Stanimir Stamenkov @.***> 于2025εΉ΄6月25ζ—₯周三 11:50ε†™ι“οΌš

stanio left a comment (weisJ/jsvg#136) https://github.com/weisJ/jsvg/issues/136#issuecomment-3002903425

A simplified (IMO) example:

A B C D E F A B C

Batik JSVG text-path-batik.png (view on web) https://github.com/user-attachments/assets/182bd985-4425-449a-94ee-259762e7af45 text-path.png (view on web) https://github.com/user-attachments/assets/3be2a3d3-6f9f-4b5c-814c-a0a2a68ad205

It seems the transform on the second path is not applied when used with <textPath>.

β€” Reply to this email directly, view it on GitHub https://github.com/weisJ/jsvg/issues/136#issuecomment-3002903425, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALBRNZNN6UM34A5PUYPVOKL3FIL7VAVCNFSM6AAAAACAADC3GCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAMBSHEYDGNBSGU . You are receiving this because you authored the thread.Message ID: @.***>

rensx avatar Jun 25 '25 07:06 rensx

Thank you for both for the examples, I know now what the problem is.

In addition, jsvg didn't support color emoji. The only one(java) that supports color emoji I known is PDFlib.

Could you elaborate on this? For limitations on emoji rendering see this comment.

weisJ avatar Jun 26 '25 19:06 weisJ

Fixing this is a bit more tricky than I anticipated. While investigating I found that also filter, mask, clip should be allowed on <textpath> elements. This requires some more complicated refactoring of the text rendering pipeline.

weisJ avatar Jul 16 '25 11:07 weisJ