Sorting glyphs by "density"



  • Hello, lately I have been thinking about using a typeface to generate some images using glyphs as "pixels" depending on whether they have less or more black. I guess the process to do so is to use a grayscale image and assign one glyph or another for each pixel depending on how light or how dark it is.

    Do you have any idea how to generate this and group glyphs, for instance, in 4 groups from lightest to darkest?

    Thanks!



  • hello @RicardGarcia,

    there are probably different ways to define the ‘density’ of a glyph. in this example, it is defined as the ratio between the glyph area and the total glyph box area:

    from fontTools.pens.areaPen import AreaPen
    
    CHARS = 'abcdefghijklmnopqrstuvwxyz$%&@'
    FONTNAME = 'Menlo-Bold'
    FONTSIZE = 1000
    
    # set font properties
    fontSize(FONTSIZE)
    font(FONTNAME)
    lineHeight(FONTSIZE)
    
    # measure glyph densities and collect values in a dict
    densities = {}
    
    for char in CHARS:
    
        # get total area for glyph
        w, h = textSize(char)
    
        # get area of 'black' surface
        B = BezierPath()
        B.text(char, (0, 0), font=FONTNAME, fontSize=FONTSIZE)
        pen = AreaPen()
        B.drawToPen(pen)
        area = abs(pen.value)
    
        # calculate density as percentage of black
        density = area / (w * h)
    
        # store density value in dict
        densities[char] = density
    

    you could also calculate density by rasterizing the glyph and counting the black pixels…

    hope this helps!



  • Thanks @gferreira!

    I didn't know that there were already functions that could calculate the area of a vector. It's nice to know that I could also calculate the amount of pixels each character takes but for now I'm totally fine with your suggestion using the "density" of a BezierPath().

    I can use this useful piece of code to design what I have in mind so thanks a lot!


  • admin

    There may be useful code here:
    https://github.com/LettError/coverage


Log in to reply