# Text on a free line (SVG)

**URL:** <https://discourse.processing.org/t/text-on-a-free-line-svg/40718>\
**Category:** Coding Questions\
**Created:** [January 26, 2023, 7:05am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718 "2023-01-26T07:05:48Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [January 26, 2023, 7:05am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/1 "2023-01-26T07:05:48Z")

</div>

Hi, I am almost a newbie on Processing.

I found this tutorial where it is also explained how to draw a text over a circle: [Strings and Drawing Text / Processing.org](https://processing.org/tutorials/text) .

My questions are:

- is it possible to draw a text on a line different from a circle (e.g. a spiral or a free line drawn by myself) and that the line is hidden after putting the text on?

- can the text be automatically adapted and sized on the length of the line in order that, if I put a text of 1000 characters (e.g.), this fits exactly?

Thanks in advance

Errel

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [January 26, 2023, 1:40pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/2 "2023-01-26T13:40:33Z")

</div>

Hi @humus,

Glad to see you back 😉

> [@humus](#):
>
> is it possible to draw a text on a line different from a circle (e.g. a spiral or a free line drawn by myself) and that the line is hidden after putting the text on?

When drawing a text along a path, the letter is always perpendicular to the [tangent](https://en.wikipedia.org/wiki/Tangent) on that curve. (for the circle case, it’s directed toward the center)

Then it depends how your curve/line is constructed, either with `beginShape` and `vertex()` or [`curveVertex()`](https://processing.org/reference/curveVertex_.html) (it might be difficult to sample points on it) or with bezier curves where you can find the tangent on a curve with [`bezierTangent()`](https://processing.org/reference/bezierTangent_.html) (check the second example in the docs).

> [@humus](#):
>
> can the text be automatically adapted and sized on the length of the line in order that, if I put a text of 1000 characters (e.g.), this fits exactly?

Yes, you need to divide the length of your curve by the number of characters to display, then adapt the font size so it matches the right step.

Let us know if you have more questions!

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [January 27, 2023, 3:34pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/3 "2023-01-27T15:34:19Z")

</div>

humus, is this what you’re looking to do?  
[http://www.generative-gestaltung.de/1/P\_2\_3\_3\_01](http://www.generative-gestaltung.de/1/P_2_3_3_01)

You can download the code for Processing 3.x. There may be a problem with variables in `size()`, so change those to whatever numbers you’d like.

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [February 3, 2023, 2:31pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/4 "2023-02-03T14:31:54Z")

</div>

Hi Perry, many thanks for your reply and sorry for the delay !

The code is really interesting! I tried to activate the section where to set a background image but it doesn’t work: why?  
Because I would like to use the background image as a guideline to draw by the text. In relation with this aspect, do you think that it should be possible the entire text to fit exactly the background guidelines not manually but automatically? And, with some code, the sketch recognize the number of characters of the text in order that the text was not repeated after ending?

Thanks  
Best regards  
Humus

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [February 3, 2023, 2:40pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/5 "2023-02-03T14:40:13Z")

</div>

Thanks Joseph, sorry for the delay. As I wrote to Perry, I would like to use a background path line, distribute automatically the text by optimizing it on that path (in size and distance from character to character) and, than, cancel the original path line in order that it only remains the text as the line path.  
Than, save this as a image.

Thanks  
Best regards  
Humus

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [February 3, 2023, 3:01pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/6 "2023-02-03T15:01:32Z")

</div>

Hi @humus,

> [@humus](#):
>
> As I wrote to Perry, I would like to use a background path line

This is a little bit confusing, can you elaborate on that? Can you post the image you want to use?

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [February 3, 2023, 5:31pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/7 "2023-02-03T17:31:37Z")

</div>

Hi Joseph, just as an example, here is an image. I simply would live to substitute the black line of the woman face with a text that follows the same path as the black line… thanks

 ![Screenshot_2023-02-03-18-24-16-42_92460851df6f172a4592fca41cc2d2e6](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/9/b/9b56c68fd180a307da309875aadf43ed85f25575.jpeg)

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [February 4, 2023, 10:56am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/8 "2023-02-04T10:56:56Z")

</div>

Hi @humus,

If it’s an SVG you can read it with Processing and extract the path lines. Then use them to display text.  
If it’s one continuous line it might help thought 😉

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [February 6, 2023, 10:07am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/9 "2023-02-06T10:07:56Z")

</div>

Ok thanks Joseph, I will try and I will come back (very very probably 😌)

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [February 6, 2023, 10:09am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/10 "2023-02-06T10:09:01Z")

</div>

But how to display the text instead of the line path?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [February 13, 2023, 5:50pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/11 "2023-02-13T17:50:56Z")

</div>

can you post the svg for this?

* * *

**Step 1:**

retrieve PVectors from a SVG and display **every** 22nd PVector as a letter “a”

I used a free shape [https://freesvg.org/tocantins-region-vector-map-drawing](https://freesvg.org/tocantins-region-vector-map-drawing)

It’s a bit tricky since it contains a child and a sub-child and only then the vertices

```auto

// https://processing.org/tutorials/pshape
// https://freesvg.org/tocantins-region-vector-map-drawing

PShape svg;

void setup() {
  size(940, 1360, P2D);
  svg = loadShape("map_of_Tocantins.svg");

  println(svg.getVertexCount());
  println(svg.getChildCount());

  PShape svg2 = svg.getChild(0); // id on svg file
  println(svg2.getChildCount());

  PShape svg3 = svg2.getChild(0); // id on svg file
  println(svg3.getVertexCount());

  for (int i = 0; i < svg3.getVertexCount(); i++) {
    PVector v = svg3.getVertex(i);
    v.x += random(-1, 1);
    v.y += random(-1, 1);
    // ellipse(v.x, v.y, 12, 12);
    if (i%22==0) {
      text ("a", v.x, v.y);
      // svg2.setVertex(i,v.x,v.y);
    }
  }
}

void draw() {
  // background(255);
  // shape(svg);
}
//

```

* * *

**Step 2**

unsuccessfully attempting to rotate the individual letter so that is perpendicular to the line

```auto

// https://processing.org/tutorials/pshape
// https://freesvg.org/tocantins-region-vector-map-drawing

PShape svg;
String myText="The sketch has been resized from 940?1360 to 940?1061 by the window manager.";

float prevX=-1100, prevY;

void setup() {
  size(940, 1060, P2D);
  svg = loadShape("map_of_Tocantins.svg");

  println(svg.getVertexCount());
  println(svg.getChildCount());

  PShape svg2 = svg.getChild(0); // id on svg file
  println(svg2.getChildCount());

  PShape svg3 = svg2.getChild(0); // id on svg file
  println(svg3.getVertexCount());

  translate(300, 0);
  int k=0;
  for (int i = 0; i < svg3.getVertexCount(); i++) {

    PVector v = svg3.getVertex(i);

    float angle=0 ;

    //v.x += random(-1, 1);
    //v.y += random(-1, 1);
    if (k==0)
      ellipse(v.x-19, v.y, 12, 12);
    if (i%22==0) {
      if (prevX!=-1100) {
        PVector prev = new PVector(prevX, prevY);
        angle = 20*PVector.angleBetween(v, prev);
        angle += TWO_PI / 4.0;
        print(angle, " ");
      }//if

      pushMatrix();
      translate( v.x, v.y);
      rotate(angle);
      text (myText.charAt(k%myText.length()), 0, 0);
      popMatrix();

      k++;
    }//if

    if (i%50==0) {
      prevX=v.x;
      prevY=v.y;
    }
  }//for
}//func

void draw() {
  // background(255);
  // shape(svg);
}
//

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [February 24, 2023, 5:26pm UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/12 "2023-02-24T17:26:23Z")

</div>

> [@Chrisir](#):
>
> unsuccessfully attempting to rotate the individual letter so that is perpendicular to the line

This approach works for the angles:

```auto
    float x = path.getVertexX(i); 
    float y = path.getVertexY(i); 
    PVector curr = new PVector(x, y);      
 
    x = path.getVertexX(i+1); 
    y = path.getVertexY(i+1); 
    PVector next = new PVector(x, y);       
    
    float angle = atan2(next.copy().sub(curr).y, // Need to copy() otherwise it modifies next
                        next.copy().sub(curr).x); // Same as above                 
    println(degrees(angle));

```

Using the sine wave example from the PShape tutorial to create vertices to use for text:

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/4/5/45a185b7136e7e764961d4043883218a65455d83.png)

The bottom two sine waves were spaced along the curve.

Applied to the map:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/f/cfa3e5e5e8524a0c5441831afa866369f66e0b7b.png)

`:)`

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [June 10, 2023, 8:42am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/13 "2023-06-10T08:42:05Z")

</div>

Hi Perry,

In this code, I can’t load an image in background: why?

Thanks

/\*  
// load an image in background  
PImage img = loadImage(selectInput(“select a background image”));  
image(img, 0, 0, width, height);  
\*/

---

<div class="post-metadata">

**Author:** ![humus](https://avatars.discourse-cdn.com/v4/letter/h/e36b37/32.png) [@humus](https://discourse.processing.org/u/humus)\
**Post date:** [June 10, 2023, 8:49am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/14 "2023-06-10T08:49:51Z")

</div>

Hi glv, thanks for your reply. So, finally, which is the complete code to do this? Thanks

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [June 11, 2023, 1:51am UTC](https://discourse.processing.org/t/text-on-a-free-line-svg/40718/15 "2023-06-11T01:51:20Z")

</div>

That block of code is commented out, but I assume that it’s not so in your `.pde` file. the `selectInput` requires a prompt string, which you have, but it also needs a callback function to handle the result, which you don’t have. If you feed `loadImage()` a file path from within `draw()`, you’ll get your image loaded.

> **[selectInput() / Reference](https://processing.org/reference/selectInput_.html)**
>
> Open a platform-specific file chooser dialog to select a file for input. After the selection is made, the selected File will be passed to the 'callback' function. If the dialog is closed or canceled, …
