What are the best practices for the hist feature (long s)?

I noticed in several typefaces with a hist feature s is simply substituted by the long s, and that's it. The problem here is that all instances of s will be replaced rather than all except for the final s of the word. I added a long list of substitutes, but I'm wondering if there is an easier way, and why is an advanced feature lacking in many typefaces?

Comments

  • Rules for using long s were not consistent, so it generally should not be substituted with an OpenType feature. The text should use the long s unicode character rather than relying on designers or software to change it.
  • John Hudson
    John Hudson Posts: 3,227
    What James said: the long s is a distinct orthographic character, not simply a variant of the common s, with varying conventions in different languages and periods. It's use is akin to that of the ß in German orthography, and can be reliably handled only at the text encoding level, not via glyph substitution.
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited January 2016
    So then what is the hist feature even for? It seems a very messy feature without the advanced substitution list. Mind you, my typeface functions very well with my method. I'm just wondering if there isn't a very simple feature to get the same function working. My hist feature looks like the following:

    feature hist { # Historical Forms
     script latn; # Latin
        sub s' a by longs;
        sub s' agrave by longs;
        sub s' aacute by longs;
        sub s' acircumflex by longs;
        sub s' atilde by longs;
        sub s' adieresis by longs;
        sub s' aring by longs;
        sub s' ae by longs;
        sub s' b by longs;
        sub s' c by longs;
        sub s' ccedilla by longs;
        sub s' d by longs;
        sub s' e by longs;
        sub s' egrave by longs;
        sub s' eacute by longs;
        sub s' ecircumflex by longs;
        sub s' edieresis by longs;
        sub s' f by longs;
        sub s' g by longs;
        sub s' h by longs;
        sub s' i by longs;
        sub s' igrave by longs;
        sub s' iacute by longs;
        sub s' icircumflex by longs;
        sub s' idieresis by longs;
        sub s' j by longs;
        sub s' k by longs;
        sub s' l by longs;
        sub s' m by longs;
        sub s' n by longs;
        sub s' ntilde by longs;
        sub s' o by longs;
        sub s' ograve by longs;
        sub s' oacute by longs;
        sub s' ocircumflex by longs;
        sub s' otilde by longs;
        sub s' odieresis by longs;
        sub s' oe by longs;
        sub s' p by longs;
        sub s' q by longs;
        sub s' r by longs;
        sub s' s by longs;
        sub s' t by longs;
        sub s' u by longs;
        sub s' ugrave by longs;
        sub s' uacute by longs;
        sub s' ucircumflex by longs;
        sub s' udieresis by longs;
        sub s' v by longs;
        sub s' w by longs;
        sub s' x by longs;
        sub s' y by longs;
        sub s' yacute by longs;
        sub s' ydieresis by longs;
        sub s' z by longs;
    } hist;

    And then I have more substitutions specified in a hlig feature. And of course I'm aware I could shorten my list by using classes, but that's not entirely what I'm getting at.
  • Nick Shinn
    Nick Shinn Posts: 2,216
    This conforms to English usage in the 17th & 18th century.
    Make it a Stylistic Set, as the Hist feature is not supported by layout applications.

    lookup hist1 {
        sub s by longs;
    } hist1;
    lookup hist2 {
        sub longs' f by s;
        sub longs longs' by s;
        sub f longs' by s;
        ignore sub longs' @lowercase;
        sub longs' by s;
    } hist2;
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited January 2016
    Thank you. This is very helpful.

    Two questions though. I need to create a class for @lowercase, correct? Just making sure it doesn't automatically refer to the lowercase characters.
    Also, what is the lookup feature for? Why divide it into two parts?
  • John Hudson
    John Hudson Posts: 3,227
    So then what is the hist feature even for?

    It's not for anything, which is why so few fonts implement it. Like quite a few of the OTL features that were registered in the early days, the {hist} feature was speculative. Adobe thought it would be something they would use, so wrote it up and included it in the specification. Later, it became clear that it wasn't really useful, for the reasons discussed here. When it is implemented, it's with the caveat that it only works for some specific conventions — as in Nick's example —, and that using the long s character is a more robust solution. In effect, it is a way to create a pastiche of an older orthography while retaining modern spelling at the character level, with more or less accuracy depending on the orthography being pastiched.

    Some of the early, speculative OTL features turned out to not only not be useful but were actually harmful, because they misrepresented underlying characters e.g. the diphthong feature that represented ae/oe as æ/œ. Such features were deprecated from the standard, but the merely useless ones remain.



  • While I agree with James and John, there are exceptions when glyph substitution can make sense. Georg Salden’s Deutschkurrent as digitally engineered by Ludwig Übele is a font that will almost exclusively be used for German text, with spelling as it was standard around the middle of the 20th century. Deutschkurrent automatically uses the correct form of s/ſ in this orthographic context. It works in the vast majority of relevant cases. Ludwig achieved this by analyzing a large amount of German words, breaking them up into syllables and reducing the cases to a reasonable number. Note that he used contextual alternates, not historical forms. It’s pretty impressive.
  • I recall a related discussion on Typophile a number of years ago, where this cosmetic solution, which preserves the Unicode code point of the s, came up:

    feature hist {
       
        sub s by s.long;
        sub s.long' f by s;
        sub s.long s.long' by s;
        sub f s.long' by s;
        ignore sub s.long' @LETTERS_LC;
        sub s.long' by s;
       
    } hist;
  • Kent Lew
    Kent Lew Posts: 944
    Also, what is the lookup feature for? Why divide it into two parts?
    The "lookup" syntax is not the same as a feature. It is a way to declare a specific set of rules to be compiled as a single lookup. Nick has split those sets of rules into two so that the first one gets completely processed before the second set.

    The names "hist1" and "hist2" are arbitrary names for the two lookups, for convenience and subsequent reference.

    Having declared these lookups, they would then need to be registered to a feature (or features), such as a Stylistic Set, as Nick suggests, in order to be deployable.

    In this case, though, explicitly declaring two separate lookups is not strictly necessary. Since the first rule is a different lookup type than the subsequent rules, they will get compiled into separate lookups anyway by the Adobe compiler. Which is why Frank’s example, which is essentially the same collection of rules, will compile basically the same as Nick’s, into two lookups.

  • I can't compile my font anymore. When I hit compile using Nick's feature, it jumps to the lookup hist2 line. When I use Frank's feature, it jumps to the sub s.long' by s line. Does anyone know what's going on?
  • Nick Shinn
    Nick Shinn Posts: 2,216

      sub s by longs;
        sub longs' f by s;
        sub longs longs' by s;
        sub f longs' by s;
        ignore sub longs' @lowercase;
        sub longs' by s;

    Try this

  • Thank you. This is pretty timely for me, and very helpful. The font I'm working on now has a long s and the archaic Blackletter A. 
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    I noticed the problem; I didn't have the lowercase class defined yet.

    Do I need to specify all lowercase letters except for f and long s in this class?

    Edit: I created a lowercase OT class, but this prevents me from exporting OTF. Does anyone know what might be going on?

    Frank, could you elaborate on the upside of preserving the Unicode point of s? Is this solution recommended? Does it have any drawbacks?
  • Hi Martin, IIRC the discusion on Typophile was on the glyph storage in PDFs.
  • Kent Lew
    Kent Lew Posts: 944
    Edit: I created a lowercase OT class, but this prevents me from exporting OTF. Does anyone know what might be going on?
    Is FontLab providing you with an error message? Hard to say without some kind of feedback.

    You could also try compiling the OT features in FL to see what error message comes up. Sometimes that message has more information than the failure-to-generate message.
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    That's the problem; I get no error message. It just jumps to a line which I think it must be identifying as wrong, but it shouldn't. Yesterday the problem was with the historical forms feature, so I switched back to my method. I think the lookup syntax or the OT class caused problems somehow. With my method it works fine, but it's a much less elegant solution.

    Now the problem seems to be in the pseudo-randomize feature. In case of Phinney's method it jumps to one of the 'lookup rotate;' lines, and with the other method it jumps to 'sub @con1 @con0' by @con2;'.

    I removed the lookup syntaxes in Phinney's method, which doesn't solve the problem. Removing the whole calt feature does. The only thing both methods have in common is that they reference OT classes. When I remove both the lookup syntaxes and the references to the OT classes, I can compile again.

    When, with the other method, I remove everything in the calt class except for:
    sub @DEFAULT @DEFAULT' by @ALT1;
    sub @ALT1 @DEFAULT' by @ALT2;
    then when I compile, the calt feature seems proper but I still can't compile; when I do, it jumps to ss01 to the second line:
    feature ss01 { # Stylistic Set 1
     script latn; # Latin
            sub c t by ct;
    } ss01;

    When I remove the ss01 feature, it jumps to the second line of ss02, and so on. This keeps on happening until I remove the OT classes in the calt feature as well. As I said, when I completely remove the pseudo-randomize features, my font compiles again.

    Since the only similarity between the two method seems to be the use of OT classes, I'm wondering if perhaps I did something wrong with defining the classes. In case of both the hist and calt features, the problems started when I introduced OT classes. What puzzles me however is that it seems I got both methods working at one point.
  • Frank, could you elaborate on the upside of preserving the Unicode point of s? Is this solution recommended? Does it have any drawbacks?
    Hi Martin, I briefly tried to reproduce some problems with PDFs that I recalled reported back then, but I couldn’t. So, forget the s.long and use Nick’s example.
  • Hi Martin, I briefly tried to reproduce some problems with PDFs that I recalled reported back then, but I couldn’t. So, forget the s.long and use Nick’s example.
    Thanks for letting me know.
  • Kent Lew
    Kent Lew Posts: 944
    Much of the behavior you describe sounds like mismatched classes. Two classes that are part of a Type 1 sub need to have the same number of members.

    Also, is your "ct" ligature really named ct? Proper naming would be c_t, and if that’s what you named it, then your ss01 code is referencing a non-existent glyph and that could be why it’s not compiling.
  • Martin Silvertant
    Martin Silvertant Posts: 166
    edited February 2016
    I might have to try implementing Nick's method again, because I also got the pseudo-randomize calt feature to work again, which also had to do with some class issues.

    As for the ligature naming, I used c_t before but noticed it has /fi and /fl encoded and /ct seemed to work just fine so I kept it that way for consistency. Is there any harm in not using the underscore?
  • Kent Lew
    Kent Lew Posts: 944
    /fi and /fl are legacy glyph names from Postscript. Not necessarily exemplars for good glyph names.

    The underscore is an industry-wide convention. See the Adobe Glyph List specification, in particular Section 6, Assigning Glyph Names in New Fonts.

    But this is guidance, not a technical requirement. Your font will still compile and perform.

    “Is there any harm?” Well, there are some remotely possible ramifications of not following the convention. Nothing life-or-death. You can decide whether it’s worth it to you.
  • The underscore is an industry-wide convention.
    I know it is. I just don't understand the implications of deviation in naming ligatures. Is there a context where things go wrong if you don't adhere to the convention?
  • Kent Lew
    Kent Lew Posts: 944
    In some PDF-generation workflows, character representation is separated from encoding. To re-create the proper encoding when deriving a text stream — e.g. copy-and-paste — the glyph names are interpreted according to the rules outlined in the Adobe Glyph List specification.

    If the underscore convention is not observed, then when the text is moved to an environment where that specific 'ct' ligature is not present, then the underlying text probably won’t revert to 'c' and 't'.