redrawing the font's contours + adding coordinates for manipulating
-
Hello, I'd like to ask for some advice on how to achieve adding coordinates to the letters I'm drawing by reading coordinates of the font's contours (basically what the code below does).
What I'd like to add is:
- I’d like to write a function that would take coordinates placed for instance in the left bottom part of the letter. for example something like this
# for x, y in segment: # if x < glyphWidth/2 && y <glyphHeight/2
- add point with handles in between y0 and glyphHeight/2 and y1 and glyphHeight/2 after that move the y0 and y1 to random position within the left bottom part of the letter
(as showed on the picture)
newPage(4000,1200) fill(255,255,255) # UI Variable([ dict(name="widthOfTheStroke", ui="Slider", args=dict( value=10, minValue=1, maxValue=300)), dict(name="ovalSize", ui="Slider", args=dict( value=0, minValue=0, maxValue=600)), dict(name="closeEach", ui="CheckBox"), dict(name="rounded", ui="CheckBox", args=dict(value=True)), dict(name="aText", ui="EditText", args=dict(text='P')) ], globals()) # setting up the font letter = BezierPath() letter.text(aText, font='source/AkzidenzGrotesk-Regular.otf', fontSize=1200, offset=(100, 100)) fill(0.1) stroke(0.1) strokeWidth(widthOfTheStroke) path = BezierPath() # function for drawing each letter based on the its coordinates (.otf file) # reading coordinates based on the received coordinates of each contour for contour in letter.contours: # move to the position of the starting point of the path path.moveTo(contour[0][0]) # loop through each coordinate – they come as an array of either one coordinate (just a point) or three coordinates (point with handlers for curves) for segment in contour: # ––––––––––––––––––––––––––––––––––––––––––– # # if the segment is with the handles draw curve # ––––––––––––––––––––––––––––––––––––––––––– # if len(segment) == 3: if rounded == 1: path.curveTo(segment[0], segment[1], segment[2]) if closeEach == 1: path.closePath() # decide whether to draw them as curver with three values or just as points for x, y in segment: if rounded == 0: path.curveTo((x,y)) # ––––––––––––––––––––––––––––––––––––––––––– # # if the segment is just a point draw a line to # ––––––––––––––––––––––––––––––––––––––––––– # if len(segment) == 1: for x, y in segment: path.lineTo((x,y)) print() # this optional # here im closing path for every new point if closeEach == 1: path.closePath() # in case you want to show each of the coordinate returned from looping through contours for x, y in segment: with savedState(): stroke(None) fill(0.3) oval(x-ovalSize/2,y-ovalSize/2, ovalSize,ovalSize) print(["contour is closed", "contour is open"][contour.open]) drawPath(path)
Thank you for taking look at this and for any feedback,
Szymon
-
he Szymon!
a bezierPath object is not made to be editable. One way could be jumpt to a glyph object.
or do a detour by cutting the path in four quarters and draw them seperatly
# create a bezierPath path = BezierPath() # add text to the path with a font and fontSize path.text("P", font="Helvetica-Bold", fontSize=778) # move the page a bit translate(100, 100) # get the bounds of the path minx, miny, maxx, maxy = path.bounds() # calculate the width, height of the bounds # we only need half the width, height w = (maxx-minx) * .5 h = (maxy-miny) * .5 # create a bezierPath and add a quarter bottomLeft = BezierPath() bottomLeft.rect(minx, miny, w, h) # create a bezierPath and add a quarter bottomRight = BezierPath() bottomRight.rect(minx + w, miny, w, h) # create a bezierPath and add a quarter topLeft = BezierPath() topLeft.rect(minx, miny + h, w, h) # create a bezierPath and add a quarter topRight = BezierPath() topRight.rect(minx + w, miny + h, w, h) # only keep the path when both of the them are filled bottomLeft = bottomLeft & path bottomRight = bottomRight & path topLeft = topLeft & path topRight = topRight & path # start drawing with savedState(): translate(w, h) skew(-30, 0) translate(-w, -h) fill(1, 0, 0) drawPath(bottomLeft) fill(1, 1, 0) drawPath(bottomRight) fill(0, 1, 0) drawPath(topLeft) fill(0, 1, 1) drawPath(topRight)