How can I randomize letters in a typeface?

I'm wondering if there aren't any methods to make a typeface toggle between a few variants of each letter as you type. I've been looking into the possibilities and realized true randomize features as seen in Beowolf are no longer possible, and it seems like the only way to go is adding contextual alternate features. Is this true? Are there no easier ways?

Mind you, unlike Beowolf, I don't need to randomize the design of the letters. I really just want my typeface to toggle between a few variants of each letter, and a feature to prevent double instances of one variant.

Comments

  • It's actually the method I was referring to, but put more concisely than the other articles I've read. I read about this method in the development process of Liza Pro and read about it in one of Nick Shinn's articles, but haven't found an article describing it in so much detail yet. This is a huge help already.

    It's not a proper randomized cycling feature however. So this is actually what I'm getting at. I can code this contextual alternates feature, but it will still always start with the same standard glyph. It would be great to truly have the cycling randomize. I suppose it's not possible however. The randomized typefaces I found (including Chapter11, Outcast Pro and Populaire) seem to be utilizing the method you linked to.


  • Interesting you should ask this. About a month ago there is a long thread on the opentype mailing list about the postscript random operator in CFF opentype.

    Anyway, the authoritative answer as I remember was that while the operator exists in the spec and theoretically you could use it to implement glyph variations with it in CFF opentype, the major rendering engine - we mean Freetype :) inclusive - does not implement it, so it has not the desired effect on most platforms.

    I suggest that a equivalent feature might exist in SVG. But I don't remember anybody mentioning a truetype-based approach other than the contextual clues mentioned, which is not truly random.
  • Hin-Tak, that was about the random operator in the CFF renderer, for randomising the process of drawing letterforms; that's different to what Martin is inquiring about, which is random substitution of different glyphs. 

    Martin, I believe you can indeed create the kind of effect you want, using 'backtrack' sequences; so it will still always start with the same standard glyph, but then that initial glyph will change because of the characters that follow it. 

    Also, curiously Behdad has recently proposed that OpenType Layout code can indeed be Turing Complete, c.f. https://github.com/behdad/harfbuzz/issues/139#issuecomment-151991107 . You may also find http://ansuz.sooke.bc.ca/entry/131 a good read :)
  • Hin-Tak Leung
    Hin-Tak Leung Posts: 363
    edited January 2016
    Hmm, I thought the Turing complete thing was a joke :)

    Random substitution of glyphs can be implemented by using the random operator in drawing letter forms - if that operator works , which it does not...

  • Random substitution of glyphs can be implemented by using the random operator in drawing letter forms - if that operator works , which it does not...
    If I want to substitute the a glyph with another glyph randomly selected from the set of 8 a.ss01 to a.ss08, how do I do that with the random operator?

  • If I want to substitute the a glyph with another glyph randomly selected from the set of 8 a.ss01 to a.ss08, how do I do that with the random operator?
    You put all 8 glyphs' content inside one glyph and switch between the subparts using conditionals...
  • Martin, I believe you can indeed create the kind of effect you want, using 'backtrack' sequences; so it will still always start with the same standard glyph, but then that initial glyph will change because of the characters that follow it.
    Could you tell me how to implement such a feature or link me to a source?
  • Ramiro Espinoza
    Ramiro Espinoza Posts: 839
    edited February 2016
    I remember an useful article by Thomas Phinney on this subject with some code examples: https://forums.adobe.com/thread/395648
  • Chris Lozos
    Chris Lozos Posts: 1,458
    Hard to believe that was 10 years ago, Ramiro ;-)
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    Repeatedly calling a single lookup allows us to keep on jumping ahead another eight characters for each lookup, making for more compact code (both written and compiled).

    Could someone explain this? Does it start at a different place of the cycle each time as you type? I now have the method Georg Seifert linked to implemented, which works beautifully. I'm just wondering how to add a backtrack feature so the first letter isn't always the same variant. Phinney's method doesn't differentiate between vowels and consonants. I suppose if it changes the starting position of the cycles, it wouldn't need such differentiation, or does it?

    I'm wondering which method is ultimately going to create a more randomized effect.

  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    Okay, I tried to implement a third cycle but I can't seem to make it work. Perhaps I should try Phinney's method instead, as I have 4 variants per letter so I need more than two cycles. Or could someone tell me how to add a third cycle, and to make letters with more letters in between cycle as well? For example, when I type ABRAXAS, I would expect all three As to be different. At this point they're all the same.

    If Phinney's method does start at a different point in the cycle each time, that would be optimal. I'm adding more letters now while I await response to elaborate on which method I should implement, and why Thomas repeats the lookup rotate function 13 times; how many times would I need for my 4 variants?
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    I tried Phinney's method, and in case of one repeating letter it just cycles through the variants like the other method. As far as I can remember the only difference between the two (besides Phinney's method being a lot easier to implement) is that with the other method, the first letter changes to the second variant depending on whether a consonant or vowel follows it. I'm not entirely sure about this though; I can't check because I closed FontLab, opened the font again and suddenly I can't compile to use the features in the OT panel anymore.

    I saved the typeface with the other method and with Phinney's method, closed them, opened them again and now neither compiles while they both did a moment ago. In both cases, when I remove everything in the calt feature that refers to the classes, I can compile again. Does anyone know what's going on?

    Also, how do I define the default class? Can I just add A B C D E etc. a b c d e etc.? Because in the other article I read all classes have to be the same size and order. I'm wondering if I need to create a second class for the lowercase.
  • Nick Shinn
    Nick Shinn Posts: 2,216
    edited February 2016
    feature calt { 
    
    lookup calt_one {
    sub @one @one' @one by @two;
    sub @two @one' @one by @three;
    sub @three @one' @one by @four;
    } calt_one;
    
    lookup calt_two {
    sub @four @one @two' by @three;
    sub @three @three' by @two;
    sub @two @four @one' by @three;
    sub @four @three @two' by @one;
    sub @three @one @three' by @four;
    sub @four @four' by @two;
    } calt_two;
    
    lookup calt_three {
    sub @one' @two @three @four [E M V e m v one space] by @three;
    sub @two' @three @four [E M V e m v one space] @three by @one;
    sub @three' @four [E M V e m v one space] @three @two by @four;
    sub @four' [E M V e m v one space] @three @two @four by @two;
    } calt_three;
    
    lookup calt_four {
    sub @one' @two @three @four [T U B t u b two space.alt2] by @four;
    sub @two' @three @four [T U B t u b two space.alt2] @three by @three;
    sub @three' @four [T U B t u b two space.alt2] @three @two by @two;
    sub @four' [T U B t u b two space.alt2] @three @two @four by @four;
    } calt_four;
    
    lookup calt_five {
    sub @one' @two @three @four [P A C p a c three nine space.alt3] by @two;
    sub @two' @three @four [P A C p a c three nine space.alt3] @three by @four;
    sub @three' @four [P A C p a c three nine space.alt3] @three @two by @one;
    sub @four' [P A C p a c three nine space.alt3] @three @two @four by @three;
    } calt_five;
    
    lookup calt_six {
    sub @one' @two @three @four [L I Q Y l i q y four eight] by @three;
    sub @two' @three @four [L I Q Y l i q y four eight] @three by @two;
    sub @three' @four [L I Q Y l i q y four eight] @three @two by @one;
    sub @four' [L I Q Y l i q y four eight] @three @two @four by @four;
    } calt_six;
    
    lookup calt_seven {
    sub @one' @two @three @four [D O G Z d o g z five] by @four;
    sub @two' @three @four [D O G Z d o g z five] @three by @one;
    sub @three' @four [D O G Z d o g z five] @three @two by @three;
    sub @four' [D O G Z d o g z five] @three @two @four by @two;
    } calt_seven;
    
    lookup calt_eight {
    sub @one' @two @three @four [F R J N f r j n six seven] by @one;
    sub @two' @three @four [F R J N f r j n six seven] @three by @four;
    sub @three' @four [F R J N f r j n six seven] @three @two by @three;
    sub @four' [F R J N f r j n six seven] @three @two @four by @two;
    } calt_eight;
    
    sub @two @two' by @one;
    sub @one @one' by @two;
    
    } calt;
    This is what I did for Duffy Script, which has four sets of alternates—for every character in the font. I have only the vaguest recollection how or why I arrived at this, but it seemed to work fairly well. A lot of trial and error!


  • Kent Lew
    Kent Lew Posts: 944
    Martin, you’re never going to achieve true randomness. All you can do is introduce enough different cycles with different patterns to try to get the interaction to mimic randomness. It’s a lot of work.

    If you want a more realistic randomness, you have to work at the layout level, not the font level. I once wrote a small proof-of-concept script for InDesign to randomize a setting of Cyrus Highsmith’s Icebox Magnet by accessing the selection of stylistic alternates via under-the-hood properties. (I don’t think FB ever decided to offer it.)

    But for the font itself, the best we could do was one of these pseudo-random cycles of calt substitutions.

  • Just to summarize/clarify things mentioned throughout this thread, here are some different kinds of “random” discussed above:

    1) The Beowolf font in PostScript type 3 format used the random operator in PS code to make random variations in the node positions. No two instances of a glyph would ever appear the same (well, there would be some absurdly large number of possibly variations, anyway). Outside of sending a font file directly to a PostScript interpreter (such as a PS printer or Acrobat Distiller), not much supports Type 3, and even those cases are not very interesting most of the time.

    2) There is a random operator in the CFF format, and hence by extension possible in OpenType CFF fonts, which could be used in much the same way. However, no important infrastructure supports it.

    3) There is an OpenType layout feature "rand" which in theory would select at random from two or more pre-built alternate glyphs. It is not well supported. (Some web browsers may support it, though?)

    4) One can achieve some degree of pseudo-random behavior by rotating through a number of available alternate glyphs. This is what I suggested and coded as an example, when LettError wanted to do an OT version of Beowolf. (I am sure their OpenType coding skills have long since outpaced my own, btw, this was early days.) Code samples of this and some other odd effects: https://forums.adobe.com/thread/395648 (thanks to @Ramiro Espinoza for bringing it up)

    5) As described by @""Kent Lew" , depending on how the font is built and the environment it is operating in, one can sometimes script or otherwise drive a layout engine to achieve more random glyph choices from a given font.

    There is probably something else I am not thinking of, but that might be all.  :)
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    Okay, I got both methods working! In case of Phinney's method, the default class was bigger than the other classes; I had all capitals defined in the main class but only A B C D defined in the other class.
    I also forgot to remove the extra alt classes, as I'm only using 4 variants. Now that is fixed, FontLab no longer jumps to the lookup rotate syntax.

    In case of the other method, I must have messed up the feature somewhere, as I can't explain what went wrong there. It's fixed in any case.

    So I have both methods working again. The result of both methods is exactly the same though. I think I rather use Phinney's method as it's a lot more elegant. However, I don't quite understand what the lookup rotate syntax does and if it's even working. Is it supposed to change the starting point of the cycle?

    Also, if I want to add lowercase as well with variants, how do I specify this? In the same classes, as long as they all contain the same amount of glyphs?

    Where can I find a backtrack feature to have a few more specific letters randomize on top of Phinney's method? If I type ABRAXAS for example, I would like all As to be different. Right now only the third one changes. I believe Nick Shinn's method may do this, correct?
  • Hey, Martin!

    I wrote an article about the subject and also made some tools to streamline this. Have a look: http://learn.scannerlicker.net/2015/06/12/making-a-font-maximal-part-iii/

    Hope it helps! Cheers!