BezierPath: Contours and Segments



  • I've been playing around with this lately and have a question.

    Following the sample code from DrawBot website, if we take a look at the segments:

    path = BezierPath()
    path.text("J", font="Helvetica", fontSize=200)
    
    for contour in path.contours:
        for segment in contour:
            print(segment)
    

    Every iteration we get a list item with either 1 or 3 tuple items with x and y point coordinates:

    [(85.64453125, 42.7734375)]
    [(85.64453125, 30.664001953125002), (83.8541845703125, 21.2565439453125), (80.2734375, 14.55078125)]
    [(73.632779296875, 2.3111367187500003), (61.002697265625, -3.80859375), (42.3828125, -3.80859375)]
    [(31.6405712890625, -3.80859375), (22.460975585937497, -0.8952114257812498), (14.84375, 4.931640625)]
    [(7.226524414062499, 10.75849267578125), (3.41796875, 21.126227539062498), (3.41796875, 36.03515625)]
    [(3.41796875, 46.2890625)]
    [(21.6796875, 46.2890625)]
    [(21.6796875, 36.03515625)]
    [(21.6796875, 28.2226171875), (23.42120654296875, 22.347024902343747), (26.904296875, 18.408203125)]
    [(30.38738720703125, 14.46938134765625), (35.8072548828125, 12.5), (43.1640625, 12.5)]
    [(53.5156767578125, 12.5), (60.286442382812496, 16.0481416015625), (63.4765625, 23.14453125)]
    [(65.429697265625, 27.5065322265625), (66.40625, 35.742126953125), (66.40625, 47.8515625)]
    [(66.40625, 143.45703125)]
    [(85.64453125, 143.45703125)]
    
    

    I would expect to get lists of 2 (for straight segments) and 4 (for curves). This is what I get in the GlyphsApp at least.

    Are these more like drawing instructions? So the first one would be moveTo() then depending on what is in front of it would be either lineTo() or curveTo()? But then if the last list is a single tuple you have go back to the first item with lineTo() or just do closePath()?


  • admin

    a segment always represent a line with a single point and a bezier curve with 3 points (2 off curves and one oncurve) this is the behaviour in RoboFab ever since...

    A contour object has an attribute contour.open which is a bool indicating a contour should use closePath or endPath for open paths.



  • Thanks for the explanation @frederik. It was just a little confusing seeing this output for the first time. It's also weird that the points are suggesting clockwise movement even though the path in the font is counterclockwise.

    P.S. I already managed to manipulate the list to my needs.


  • admin

    A contour object has a contour.clockwise which is a boolean indicating what the direction is. Hope this helps you out.



  • I was comparing a different fonts apparently, my bad.The paths are indeed going the right way.