Sorting contours

RoboFont Forums Help / General Sorting contours

This topic contains 4 replies, has 2 voices, and was last updated by  Roberto Arista 5 years, 5 months ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #6143

    Roberto Arista
    Participant

    Dear Frederik, Dear Robofont users,
    I need to order some contours inside a glyph.
    This sorting operation is not related to interpolation, so the glyph.autoContourOrder() method doesn’t come in help. Let’s say that I want to sort contours according to length, at the moment this would be my procedure:
    – collect the contours in a list
    – perform the length measurement
    – sort the list according to the results
    – clear the “original” contours
    – draw the sorted contours in the emptied glyph according to the order of the list that stores them

    This procedure works, but I was wondering if maybe there’s a method to achieve this goal without deleting the contours, just sorting in place. Like changing the “index” attribute to contour object. I tried to access this attribute, but this is the reply that I receive: “AttributeError: ‘RobofabWrapperContour’ object has no attribute ‘index’”

    Any tips?

    Appendix to the problem: after this sorting operation, I need to automatically select one of this contours. I tried the select(state = True) RPoint method or to change to selected RContour attribute, but they do not seem to work. Any advice to solve this?

    Thanks

    #6144

    frederik
    Keymaster

    the best thing todo is to draw the glyph into a pen store and process the data and draw it back into the glyph

    this should work :)

    enjoy

    from robofab.pens.pointPen import AbstractPointPen
    
    class SortingPen(AbstractPointPen):
        
        def __init__(self):
            self._contours = []
            
        def beginPath(self):
            self._contours.append([])
                           
        def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
            self._contours[-1].append((pt, segmentType, smooth, name, kwargs))
        
        def endPath(self):
            pass
    
        def addComponent(self, baseGlyph, transformation):
            pass   
                
        def drawPoints(self, pen):
            # sort by the len of oncurves and offcurvers for each contour
            sortable = []
            for contour in self._contours:
                oncurves = 0
                offcurves = 0
                for pt, segmentType, smooth, name, kwargs in contour:
                    if segmentType is None:
                        offcurves += 1
                    else:
                        oncurves += 1
                sortable.append((oncurves, offcurves, contour))
            sortable.sort()
    
            for oncurvers, offcurvers, contour in sortable:
                pen.beginPath()
                for pt, segmentType, smooth, name, kwargs in contour:
                    pen.addPoint(pt, 
                                smooth=smooth, 
                                segmentType=segmentType, 
                                name=name, 
                                **kwargs)
                pen.endPath()
            
         
    
    # get the current glyph
    g = CurrentGlyph()
    # get the pen
    sorting = SortingPen()
    # draw into that pen
    g.drawPoints(sorting)
    # clear the contours
    g.clearContours()
    # draw back into the glyph
    sorting.drawPoints(g.getPointPen())
    
    #6145

    Roberto Arista
    Participant

    Thanks, I’ll try today.
    And what about the selection problem?
    Any advice?

    What I found in the robofab documentation, doesn’t seem to work in Robofont.
    Or maybe I misunderstood the intended use of those methods/attributes.

    #6147

    frederik
    Keymaster

    use:

    g = CurrentGlyph()
    
    contour = g[1]
    contour.selected = True
    g.update()
    
    #6148

    Roberto Arista
    Participant

    Perfect, it works.
    Thanks!

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.