This example shows how to draw a merz symbol over each point in the current layer matching another point in a reference layer. The tool uses a set intersection to compare the coordinates between layers. A defcon representation factory takes care of generating the sets avoiding redundant work thanks to its caching system.

from defcon import Glyph, registerRepresentationFactory, unregisterRepresentationFactory
from mojo.subscriber import Subscriber, registerGlyphEditorSubscriber


REFERENCE_LAYER = "background"


def coordinatesFactory(glyph):
    """
    Make a set with points coordinates

    """
    coordinates = set()
    for eachContour in glyph:
        for eachPt in eachContour:
            coordinates.add((eachPt.x, eachPt.y))
    return coordinates


class MatchingPoints(Subscriber):

    debug = True

    # --- base methods --- #
    def build(self):
        glyphEditor = self.getGlyphEditor()
        self.container = glyphEditor.extensionContainer(
            identifier="com.developer.matchingPoints",
            location="foreground",
            clear=True,
        )
        self.matchingPointsLayer = self.container.appendBaseSublayer()

    def started(self):
        registerRepresentationFactory(Glyph, "coordinatesRepresentation", coordinatesFactory)
        self.drawPoints()

    def destroy(self):
        unregisterRepresentationFactory(Glyph, "coordinatesRepresentation")
        self.container.clearSublayers()

    # --- drawing routine --- #
    def drawPoints(self):
        self.matchingPointsLayer.clearSublayers()

        glyph = self.getGlyphEditor().getGlyph().asFontParts()
        foregroundCoordinates = glyph.getRepresentation("coordinatesRepresentation")

        font = glyph.font
        if REFERENCE_LAYER in font.layerOrder and glyph.name in font.getLayer(REFERENCE_LAYER):
            backgroundGlyph = glyph.font.getLayer(REFERENCE_LAYER)[glyph.name]
            backgroundCoordinates = backgroundGlyph.getRepresentation("coordinatesRepresentation")

            for eachMatchingPt in foregroundCoordinates.intersection(backgroundCoordinates):
                symbolLayer = self.matchingPointsLayer.appendSymbolSublayer(position=eachMatchingPt)
                symbolLayer.setImageSettings(dict(name="oval", size=(20, 20), fillColor=(1, 0, 0, 0.4)))

    # --- subscriber callbacks --- #
    glyphEditorGlyphDidChangeContoursDelay = 0
    def glyphEditorGlyphDidChangeContours(self, info):
        self.drawPoints()

    def glyphEditorDidSetGlyph(self, info):
        self.drawPoints()


if __name__ == "__main__":
    registerGlyphEditorSubscriber(MatchingPoints)

Merz reuses symbols that have the same settings. There is an internal cache system that stores images based on their settings. You can have 1000 symbols in different locations and it will only create 1 image for all of those as long as the image settings are the same.

Last edited on 01/09/2021