How to customize preview of space center?



  • Hi, I have made this tool that generates contours for glyphs' "outer" countershapes. How does xHeight cut work currently in space center? Would it be possible to build a tool on top of it that doesn't display glyphs' "inner" counter shapes? I have problems to do the spacing right, and I think this tool helped me a bit to understand it. But each time I change the spacing I need to generate new layer with those contours. Thanks for advise!
    Screenshot 2020-05-11 at 19.47.03.png


  • admin

    hello @jansindl3r,

    this looks like a very useful tool.

    here is an example which uses representations to create and cache shapes – this is recommended for performance.

    from vanilla import FloatingWindow, CheckBox
    from defconAppKit.windows.baseWindow import BaseWindowController
    from mojo.events import addObserver, removeObserver
    from mojo.UI import CurrentSpaceCenter
    from defcon import Glyph, registerRepresentationFactory, unregisterRepresentationFactory
    import mojo.drawingTools as ctx
    from fontTools.pens.cocoaPen import CocoaPen
    from random import random
    
    def CounterShapeFactory(glyph):
        pen = CocoaPen(glyph.layer)
        # just a rect -- draw your counter shapes here
        pen.moveTo((0, 0))
        pen.lineTo((glyph.width, 0))    
        pen.lineTo((glyph.width, glyph.font.info.xHeight))
        pen.lineTo((0, glyph.font.info.xHeight))
        pen.closePath()
        return pen.path
    
    class CounterShapeViewer(BaseWindowController):
    
        def __init__(self):
            self.w = FloatingWindow((123, 40))
            self.w.preview = CheckBox((10, 10, -10, 20), 'preview', value=True, callback=self.updatePreviewCallback)
            self.setUpBaseWindowBehavior()
            registerRepresentationFactory(Glyph, "CounterShapePreview", CounterShapeFactory)
            addObserver(self, "drawCounterShape", "spaceCenterDraw")
            self.w.open()
    
        def windowCloseCallback(self, sender):
            super().windowCloseCallback(sender)
            removeObserver(self, "spaceCenterDraw")
            unregisterRepresentationFactory(Glyph, "CounterShapePreview")
    
        def updatePreviewCallback(self, sender):
            S = CurrentSpaceCenter()
            if not S:
                return
            S.updateGlyphLineView()
    
        def drawCounterShape(self, notification):
            S = CurrentSpaceCenter()
            if not S or not self.w.preview.get():
                return
            glyph = notification['glyph']   
            counterShape = glyph.getRepresentation("CounterShapePreview")
            ctx.save()
            ctx.fill(random(), random(), random(), 0.3)
            ctx.drawPath(counterShape)
            ctx.restore()
    
    CounterShapeViewer()
    

    give it a try… cheers!



  • @gferreira thanks a lot for you help, it works pretty smooth! But how do you remove the original contour that contains the whole shape? I can't figure it out :(


  • admin

    @jansindl3r I don’t know if it’s possible not to draw the glyph shape. but you can “erase” it by drawing the glyph on top of itself with the background color – see an example here.


  • admin

    euh, something simple:

    # draw the background color of the existing glyph
    
    from mojo.UI import getDefault
    
    r, g, b, a = getDefault("spaceCenterBackgroundColor")
    
    bounds = glyph.bound
    if bounds:
        x, y, maxx, maxy = bounds
        w = maxx - x
        h = maxy - y
        ctx.fill(r, g, b, a)
        offset = 10
        ctx.rect(x-offset, y-offset, w+offset*2, h+offset*2)
    

  • admin

    or wrap changing fill and stroke inside spaceCenterDrawBackgroundLineView spaceCenterDrawLineView notifications.

    A multiline view has a _fill and _stroke attribute you can temporarily overwrite.

    good luck