Drawing with text to points

Hi!

I’m using font’s textToPoints method so later on I can manipulate the points the deform the text, but I have 3 issues. I’m absolutely not asking for complete code here, just ideas that I can try out.

  1. I sort of solved this but wondering if there’s an easier way to actually draw the text? I’m looping through the points and using vertex to make multiple shapes for each letter, but since the data itself isn’t divided by letters it’s not easy to detect when when to call endShape to begin the next outline. Right now I need to check the distance between the current and last point with some arbitrary threshold to consider if it belongs to the same outline or not. Is there a smarter way to go about this that I’m missing?

  2. Probably the biggest issue I’m running into is the inner shapes for letters like o, p, b, a. I can’t detect if a new shape is part of the same letter, so everything has the same white fill. How can I determine if it’s an inner shape to make it a black fill instead so that the letters can have holes? For the most part I got this working by comparing min/max values of the last outline, but it’s a bit finnicky.

  3. Related to the last point, if I get black shapes for the inner shapes when I export I actually want these to be alpha, and not black! Maybe pictures will help explain here.

Drawing the outer outline from an o gives me this shape with white fill:
alpha2

Then drawing the inner outline with a black fill gives me this:
alpha1

But when I export I want the black area to be alpha, not black.

1 Like

For #3, I found that I can actually use erase to cut holes into the letter’s main shape. I would still love to hear if there are any good approaches for any of my issues.

For #1, you can break the text into single characters before you use textToPoints() - that way, you will have each array representing a single character as below:

let font

function preload() {
    font = loadFont('your-font.otf')
}

function setup() {
    createCanvas(300, 300)
    background(220)

    textFont(font)
    textSize(256)
    const t = 'to'
    let x = 0
    let y = height * 3 / 4
    text(t, x, y)

    const pts = []
    for (let i = 0; i < t.length; i++) {
        const arr = font.textToPoints(t[i], x, y, 256)
        pts.push(arr)
        x += textWidth(t[i])
    }

    for (let i = 0; i < pts.length; i++) {
        beginShape()
        for (let j = 0; j < pts[i].length; j++) {
            const p = pts[i][j]
            vertex(p.x, p.y)
        }
        endShape()
    }

}

For #2, I don’t think there is a way to differentiate the main shape and the counter shape (a hole in a letter) with textToPoints() because it only returns you with an array with all the x, y coordinates. Last time I checked, p5 relied on opentype.js library to handle this type of operations so you might want to check that library (it is another really amazing library specialized in font/typography.)

For #3, if you can get separate arrays for the main shape and the counter, then you can simply use beginContour() and endContour() to cut out a hole.