import vanilla import merz from mojo.subscriber import Subscriber, WindowController, registerCurrentFontSubscriber class BlurringLens(Subscriber, WindowController): debug = True def build(self): self.w = vanilla.FloatingWindow((500, 200), "Blurred Glass", minSize=(500, 200)) self.glyphsView = merz.MerzView("auto", backgroundColor=(1, 1, 1, 1)) self.w.stack = vanilla.VerticalStackView( (0, 0, 0, 0), views=[dict(view=self.glyphsView)], edgeInsets=(10, 10, 10, 10) ) def started(self): self.w.open() def currentFontDidSetFont(self, info): font = info['font'] # chooses the first three non-empty glyphs # according to glyph order glyphs = [] for name in sorted(font.glyphOrder): glyph = font[name] if not len(glyph): continue glyphs.append(glyph) if len(glyphs) == 3: break self.font = font self.glyphs = glyphs self.setAdjunctObjectsToObserve(glyphs) self.adjunctGlyphDidChangeContours(None) def adjunctGlyphDidChangeContours(self, info): print("adjunct!") font = self.font glyphs = self.glyphs view = self.glyphsView container = view.getMerzContainer() container.clearSublayers() if font is None: print("NO FONT!") return pointSize = 150 scale = pointSize / font.info.unitsPerEm offset = 25 * (1.0 / scale) container.addSublayerScaleTransformation(scale) contents = [ (glyphs[0], "left", offset), (glyphs[1], "center", 0), (glyphs[2], "right", -offset) ] for glyph, xPosition, offset in contents: xMin, yMin, xMax, yMax = glyph.bounds width = xMax - xMin height = yMax - yMin glyphContainer = container.appendBaseSublayer( position=( dict( point=xPosition, offset=offset ), "center" ), size=(width, height) ) glyphLayer = glyphContainer.appendPathSublayer() glyphLayer.appendFilter( dict( name="glyphLayerFilter", filterType="gaussianBlur", radius=5) ) glyphPath = glyph.getRepresentation("merz.CGPath") glyphLayer.setPath(glyphPath) if __name__ == '__main__': registerCurrentFontSubscriber(BlurringLens)