Font Glyphs: Small caps?

  1. last week

    Hello all,

    Please let me preface this by stating that I understand there are some considerations when discussing specific fonts. For the sake of the conversation, let's assume that any necessary fonts will be available and installed.

    Can anyone suggest a non-plugin method of accessing special font glyphs? In my case, I would specifically like to draw small caps characters on a graphics object.

    I was hoping that I could simply check each character to determine if it's lowercase, and if so, replace it using TextEncoding.Chr for its small caps glyph. But the more I read about Unicode , the less this approach makes sense.

    Another approach (described here for VB.NET ) is to "cheat" by using all capital letters and reducing the font size. But this is not a great approach. The font I'm using includes small caps characters and I would like to use them.

    I'm primarily on a Mac, but bonus points if there's a cross platform approach that doesn't involve a plugin!

    I don't claim to be an expert in the OpenType format, but in my work in publishing I've learned that small caps are implemented as a contextual alternate in OpenType fonts. Looking at the way Garamond Premier Pro is laid out, it is using the Private Use Area of the Unicode space to hold the glyphs for the different OpenType contextual alternates such as small caps. In OpenType, there are tables that describe how the substitution of glyphs should be done in different circumstances. To be able to do this reliably in multiple fonts you would need to understand how to interface with the substitution tables since the location can (and probably does) change, especially in fonts from different foundries.

    Fortunately, it appears that the small capitals for the 26 unaccented Latin characters (including "X") are available at Unicode locations 7F61 through 7F7A in Garamond Premier Pro. If that's all you need, you can use @Michel B's formula, in a way similar to this:

    Dim textToDisplay As String = "DISPLAY THIS"
    Dim unicodeText As String
    Dim c As String
    
    For i As Integer = 1 To Len(textToDisplay)
      c = MID(textToDisplay, i, 1)
      If ASC(c) >= ASC("A") And ASC(c) <= ASC("Z") Then
        unicodeText = unicodeText + CHR(ASC(c) - ASC("A") + &hF761)
      Else
        unicodeText = unicodeText + c
      End If
    Next
  2. Tanner L

    is not verified Nov 5 Pre-Release Testers Toronto, Canada

    If the strings are static, you can just type in the UTF8 string that you want to display. I.E.

    g.DrawString("Tʜɪs ɪs ᴀ ᴛᴇsᴛ", 0, 0, 76)

    Or are you looking for dynamic conversion to Small Caps?

  3. @Tanner L If the strings are static, you can just type in the UTF8 string that you want to display. I.E.

    g.DrawString("Tʜɪs ɪs ᴀ ᴛᴇsᴛ", 0, 0, 76)

    Or are you looking for dynamic conversion to Small Caps?

    Tanner- thanks very much for your response! I'm really wanting a dynamic conversion. But perhaps I could create an array of pairs, with the lower case letter and its small caps UTF8 equivalent, and then do a case-sensitive replace all. I'm wondering if there's a better/more robust/more efficient way.

  4. Edited last week

    Ah, update: that won't work anyways, even with static strings.

    Technically, it's showing small caps characters, but not from the specified font.

    -image-

    Interestingly, the "x" character doesn't even work- it simply shows the original "x." I suspect this has to do with the "x" missing from the unicode alphabet, as described here , but I don't know.

  5. Tanner L

    is not verified Nov 5 Pre-Release Testers Toronto, Canada

    GraffitiSuite offers an HTML Label control for desktop. You could ask @Anthony C if it supports small caps via CSS.

  6. @Tanner L GraffitiSuite offers an HTML Label control for desktop. You could ask @Anthony C if it supports small caps via CSS.

    Actually, this isn't a bad idea. I'm ultimately trying to draw this into a graphics object so I can print it, but HTML might be an avenue to explore if I can't figure out how to do this otherwise.

  7. Julian S

    Nov 6 Pre-Release Testers, Xojo Pro UK

    Do you have a link to the font download/website?

  8. 7 days ago

    @Julian S Do you have a link to the font download/website?

    The one I'm using is Garamond Premier Pro , but there are certainly plenty of fonts that have small caps variants.

  9. Michel B

    Nov 6 Pre-Release Testers, Xojo Pro RubberViews.com
    Edited 7 days ago

    Small caps should actually be entire fonts. There are differences between uppercase letters made small, and true small caps. But fact is, such fonts are usually available from big foundries and cost an arm and a leg.

    https://en.wikipedia.org/wiki/Small_caps

    The HTML solution is actually rather easy to implement with HTMLViewer. Put the below in a constant and use HTMLViewer.Loadpage() to display.

    <html>
    <head>
    <meta content="text/html; charset=ISO-8859-1"
    http-equiv="content-type">
    <title></title>
    </head>
    <body style="font-variant: small-caps;">
    A Quick Brown Fox jumps over the Lazy Dog
    </body>
    </html>

    @Matthew P The font I'm using includes small caps characters and I would like to use them.

    You need to figure where the font maker has placed the small caps. With some luck, it conforms to the chart at
    https://www.fileformat.info/info/unicode/category/Ll/list.htm

    Then it is fairly easy to use chr(ASC+n) to display in small caps.

  10. @Michel B You need to figure where the font maker has placed the small caps. With some luck, it conforms to the chart at https://www.fileformat.info/info/unicode/category/Ll/list.htm

    Then it is fairly easy to use chr(ASC+n) to display in small caps.

    Thanks very much for your input, Michel. From searching around on the forums for a solution to this, I got the impression that you've had some experience working with fonts, so I was hoping you might weigh in. I completely agree that it would be nice if there were fonts specifically designated as "small caps" fonts.

    Your suggestion is exactly what I was hoping to do, though it hasn't worked as well as I had hoped. For one, the small caps glyphs don't seem to be placed next to each other in the font... They don't seem to conform to the chart you included above (which doesn't include a small caps "x", by the way!). And if I were to go through the entire alphabet and create a map of where all of the small caps glyphs are located, I'm afraid it might not work if I changed to a different font.

  11. Julian S

    Nov 6 Pre-Release Testers, Xojo Pro UK

    It looks like the table is quite spread apart for SMALL CAPITAL, considering that some of the letters are will be missing (X and Q) are you able to switch font for one that just replaces the lowercase set for a small font, like the one on the bottom of this list GaramondRepriseOldStyleSSiSmallCaps.ttf https://www.wfonts.com/font/garamond-reprise-oldstyle-ssi ?

  12. Ed P

    Nov 6 Pre-Release Testers Answer Tampa, FL, USA

    I don't claim to be an expert in the OpenType format, but in my work in publishing I've learned that small caps are implemented as a contextual alternate in OpenType fonts. Looking at the way Garamond Premier Pro is laid out, it is using the Private Use Area of the Unicode space to hold the glyphs for the different OpenType contextual alternates such as small caps. In OpenType, there are tables that describe how the substitution of glyphs should be done in different circumstances. To be able to do this reliably in multiple fonts you would need to understand how to interface with the substitution tables since the location can (and probably does) change, especially in fonts from different foundries.

    Fortunately, it appears that the small capitals for the 26 unaccented Latin characters (including "X") are available at Unicode locations 7F61 through 7F7A in Garamond Premier Pro. If that's all you need, you can use @Michel B's formula, in a way similar to this:

    Dim textToDisplay As String = "DISPLAY THIS"
    Dim unicodeText As String
    Dim c As String
    
    For i As Integer = 1 To Len(textToDisplay)
      c = MID(textToDisplay, i, 1)
      If ASC(c) >= ASC("A") And ASC(c) <= ASC("Z") Then
        unicodeText = unicodeText + CHR(ASC(c) - ASC("A") + &hF761)
      Else
        unicodeText = unicodeText + c
      End If
    Next
  13. 6 days ago

    Michel B

    Nov 6 Pre-Release Testers, Xojo Pro RubberViews.com
    Edited 6 days ago

    @Matthew P I'm afraid it might not work if I changed to a different font.

    I assume you would embed your font into the app, so you make sure it is always present.

    Make sure you have the proper license to do so, though.

    I looked at google fonts, but unfortunately, small caps are not part of the free thousands of fonts.

  14. Edited 6 days ago

    Ed, this is exactly what I was looking for. In fact, if you make one minor modification, the small caps work as expected (that is, leaving uppercase letters as is and only converting the lowercase letters):

    If ASC(c) >= ASC("a") And ASC(c) <= ASC("z") Then
         unicodeText = unicodeText + CHR(ASC(c) - ASC("a") + &hF761 )

    -image-

    So, my final question is: how did you know where those glyphs were?

    @Michel B I assume you would embed your font into the app, so you make sure it is always present.

    This is such a small little tool that those of us who would use it already have and use the font, but if I were to ever distribute the tool publicly I would certainly embed with proper licensing!

    Thank you both very, very much!

  15. Ed P

    Nov 7 Pre-Release Testers Tampa, FL, USA

    Ah, you're right, the small caps would normally be applied to the lowercase letters, not the uppercase. Your modification fixes my oversight.

    As to how I found them...I have a utility on my Mac called PopChar, which offers a menu bar addition to look at the glyphs within a font among other things. It will break things down by Unicode group, so when I didn't see a group called "Small Caps" or similar, I went hunting. The private area had 1395 entries, so that seemed the likely candidate. From there, it was a case of scanning through the entries to find what we needed to make this work.

or Sign Up to reply!