Group-Spacing



  • The online documentation of RoboFont tells me, that I can use Groups for “spacing, kerning and organizing character sets”. Cool, but I can’t find a way to use Groups in Space Center. Is there a possibility to do spacing by groups?

    Thanks, A.


  • admin

    There is no embedded possibility to do spacing by groups.

    This is an easy example:

    font = CurrentFont()
    
    for groupName in font.groups.keys():
        
        # maybe test this before
        # in this example the group name is "left_O"
        leftRight, keyGlyph = groupName.split("_")
        
        # check if the key glyph is in the font
        if keyGlyph not in font:
            continue
        keyGlyph = font[keyGlyph]
        
        # get all the glyphs from the group
        glyphs = font.groups[groupName]
        
        # loop over all the glyphs
        for destGlyph in glyphs:
            # check if the destination glyph is in the font
            if destGlyph not in font:
                continue
            # get the destination glyph 
            destGlyph = font[destGlyph]
            
            # based on the left or right copy the margins from the key glyph
            if leftRight == "left":
                destGlyph.leftMargin = keyGlyph.leftMargin
            
            elif leftRight == "right":
                destGlyph.rightMargin = keyGlyph.rightMargin
    

    if you have groups like:



  • Great, thank you.



  • First post, newbie, hi!

    (Please forgive me (but tell me) if this is a stupid beginner's question and/or in the wrong place)

    Allow me to piggyback – I've been playing around with something in this direction and noticed something I wanted to ask about: shifting components upon respacing of base glyphs.

    Say I have a base glyph O and a destination glyph Odieresis, which is made up of an "O" component and a "dieresis" component. Upon changing the left sidebearing of the base glyph (O), doing an update() on the Odieresis glyph shifts the O component within it to match the new sidebearing of the O, resulting in a correct left sidebearing but a misplaced diacritic (and unchanged width, etc.)

    Is this the intended behaviour? Is there already a «predefined» way to avoid components «moving» with their base glyphs?

    Thanks, N


  • admin

    He Nina

    welcome 🙂

    If both the component and the base glyph are transformed, the component will be transformed twice: once with by the moving the component and once cause the component is being moved.

    you can ignore it by checking if a glyph as components:

    # loop over all the glyphs
    for destGlyph in glyphs:
        # check if the destination glyph is in the font
        if destGlyph not in font:
            continue
        # get the destination glyph
        destGlyph = font[destGlyph]
    
        if destGlyph.components:
            # do nothing if the glyph has components
            continue
    

    next issue pops up when there is a mix of contours and components
    the best solution is to decompose the glyph or to handle contours separately if you want to keep the components.

    ## solution #1
    glyph = CurrentGlyph()
    glyph.decompose()
    
    ## solution #2
    glyph = CurrentGlyph()
    
    # define a leftMargin, in this cause it should be 10
    leftMargin = 20
    
    # the difference between the existing left margin of the glyph
    # and the desired left margin is the move value on the x-axis
    move = leftMargin - glyph.leftMargin
    
    # loop over all contours and move only the contours
    for contour in glyph:
        contour.move((move, 0))
    

    good luck



  • OK, thank you, Frederik. Hmm, that sort of confirms what I suspected. I was hoping there was a way to generally «unlink» the leftMargin of the component from that of the base glyph; because even when this routine is set to ignore/bypass components (as in your first code example), the fact that if I change the leftMargin of the "O", inside an "Odieresis" the "O" part (but not the "dieresis" part) will by default be moved along, means the relative placement of diacritics and other components is lost when spacing of the base glyph is changed. True? I'm probably completely failing to express this clearly (sorry!) but I'll try to build upon your «solution #2» in my script to try to move the other components along, or something. 🙂 Thanks again.


  • admin

    That is a very good observation 🙂 if your "dieresis" isn't in the list of glyphs in the for loop, the "dieresis" will idd not be moved.

    Here is an extended example:

    font = CurrentFont()
    glyphNames = font.selection
    
    leftMargin = 40
    
    for glyphName in glyphNames:
        glyph = font[glyphName]
        # the difference between the existing left margin of the glyph
        # and the desired left margin is the move value on the x-axis
        move = leftMargin - glyph.leftMargin
    
        # loop over all contours and move only the contours
        for contour in glyph:
            contour.move((move, 0))
        
        # loop over all components in the glyph
        for component in glyph.components:
            # check if the component is in the big glyphNames list
            if component.baseGlyph in glyphNames:
                # if so the component will be moved by moving the base glyph contours
                # and continue in the for loop
                continue
            # otherwise move the component
            component.move((move, 0))
    

    have fun!



  • That helps! Thanks. 🙂



Looks like your connection to RoboFont ● Forum was lost, please wait while we try to reconnect.