Daggerfont

Show off your mod creations or just a work in progress.
User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Re: Daggerfont

Post by jayhova »

Okay, I bit the bullet and like a big boy. I followed the steps (CTRL F9 did not seem to work for me so extra steps) OOppps! Misread CTRL+9 as CTRL F9 and rendered the font. In the process, I discovered some problems (of course). Below I have included a composite I created to show the issues and how they can be corrected. The "Name:" line demonstrates how the font would render in vanilla DFU. The "Race:" line shows how the updated font should render. The rest of the screenshot is unretouched. Closer examination reveals how SDF fonts are handled differently than classic. Since the original fonts were 1 pixel wide, the spacing was also 1 pixel generally speaking. As a consequence of the need to render at a single pixel level drop shadows were offset 1 pixel to the right and 1 pixel down. Since each character is on average 4-5 pixels wide the drop shadow is offset by somewhere around 20% at a 45°angle. The SDF fonts, on the other hand, are expanded to fill nearly all of this approximately 20% space. The drop shadows are far less dramatic but still render under the following letter. While classic fonts follow a character|shadow|character pattern, there is one glaring exception. The "i" is spaced and extra pixel wide, creating a charater|shadow|gap|character pattern. The SDF font renderer handles this by doubling the width of the "i" character in addition to the extra 20% added to take up the space not used for a drop shadow.

Font screenshot composite.jpg
Font screenshot composite.jpg (581 KiB) Viewed 4986 times
Attachments
FONT0003-SDF.zip
(196.71 KiB) Downloaded 248 times
Daggerfont_tga.zip
(53.79 KiB) Downloaded 219 times
Last edited by jayhova on Sun Dec 16, 2018 11:29 am, edited 1 time in total.
Remember always 'What would Julian Do?'.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Daggerfont

Post by Interkarma »

I don't have any plans to make further changes to SDF font rendering at this time. My article covers off selecting a good font and why characters and laid out the way they are. Not all fonts are good candidates based on the compromises outlined in the article.

The shortcut key for switching between classic/SDF font rendering is Shift+F11. There is no Ctrl+F9 shortcut, which is why it doesn't do anything.

By the way, I think your font looks great, even with the glyph scaling compromises on my end. :)

User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Re: Daggerfont

Post by jayhova »

Interkarma wrote: Mon Dec 10, 2018 11:51 pm
The shortcut key for switching between classic/SDF font rendering is Shift+F11. There is no Ctrl+F9 shortcut, which is why it doesn't do anything.

"Once your project opens, go to the Unity Asset Store (Ctrl+9 shortcut) and search for the “SDF Toolkit Free”. Download and install this asset into your project."

I was referring to the instructions on the front page which I misread as ctrl f9.
Remember always 'What would Julian Do?'.

User avatar
Nystul
Posts: 1501
Joined: Mon Mar 23, 2015 8:31 am

Re: Daggerfont

Post by Nystul »

jayhova wrote: Mon Dec 10, 2018 11:34 pm Okay, I bit the bullet and like a big boy.
welcome to my world...

I also like your font!

User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Re: Daggerfont

Post by jayhova »

I'm scratching my head on what I could possibly do to force the font to display correctly. There seems to be an error in how the "i" is rendered since there is an extra space (all spacing being the equivalent of an original pixel in width) before the character. Perhaps I can shift it over one unit and see if that fixes things. It's frustrating because the fonts I created are proportionally correct but the SDF layout distorts them because it does not correctly reflect the aspect ratio of the original font. What seems to be happening is that the SDF rendered is not creating any spacing between characters. As far as I can tell the renderer has an area reserved for anti=aliasing the characters + maybe a 1-pixel buffer outside that. This means that the SDF characters are rendered without any normal spacing.

The explanation of how the renderer works is somewhat misleading. The characters do not get rendered at the same aspect as classic. They are rendered to fill the entire box including the leading and trailing spaces. Below I have included illustrations to show what I mean. I'm going to try and cheat the font to make it work in the SDF renderer.

I'm not a coder so I, of course, have no clue what it would take programming wise to fix this. However, if someone at some point wanted to it seems you could add a variable that could control the character spacing. Alternately you could pad the normal classic character spacing with actual rendered spacing. Probably the simplest solution would be a "force classic aspect ratio on SDF fonts" setting. It would be nice to get rid of the "i" problem. If you absolutely had to, you could always take the extra space and render it at the end of the word.

(the error in how the "i" is placed is faithfully reproduced in DFU from classic)

SDF font spacing 1.jpg
SDF font spacing 1.jpg (43.08 KiB) Viewed 4931 times
SDF font spacing 1.jpg
SDF font spacing 1.jpg (43.08 KiB) Viewed 4931 times
Attachments
SDF font spacing 2.jpg
SDF font spacing 2.jpg (62.67 KiB) Viewed 4931 times
Remember always 'What would Julian Do?'.

User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Re: Daggerfont

Post by jayhova »

So, as a proof of concept, I created a font that cheats the system. Essentially what i did was take my old font and add a small dot after the character spacing so the SDF renderer would be forced to render the intervening space and not expand the font to fill the box. Below I have attached a screenshot of how this turned out. I have not done the numbers yet so you can see how they look and the difference. Once I have a complete cheated character set I will post it.

looks like I accidentally fixed how the "i" is rendered by adding space in front of the glyph.

Font screenshot POC.jpg
Font screenshot POC.jpg (658.47 KiB) Viewed 4922 times
Remember always 'What would Julian Do?'.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Daggerfont

Post by Interkarma »

What I can do down the road is make the "filling" behaviour optional. And ideally, font creators can provide an XML or JSON configuration to define atlas rects, etc. This will make it possible to use a wider range of tools to generate the SDF atlas. I'm sure it's possible to add more flexibility while still adhering to classic's basic layout requirements.

I don't plan on making any refinements in the near future though, so any workarounds you can achieve on your end will do the trick for now. Great work! :)

User avatar
Ferital
Posts: 282
Joined: Thu Apr 05, 2018 8:01 am

Re: Daggerfont

Post by Ferital »

Your font looks great jayhova, it really feels like the classic one!

User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Good news and bad news

Post by jayhova »

I have been poking at this for a while and I have managed to get the character widths to come out pretty close to right. As a side effect I have corrected positioning problems with some of the characters, in particular, the "i". While doing this I have made some interesting observations. Horizontal position within the 64x64 cell is ignored. A character can be all the way to the right-hand side of the cell and the renderer will treat it the same as if it were on the left. The renderer starts at the first pixel on the left and renders until there are no more pixels in the cell. In the case of the "i", I put a small dot on the right side, created some space, placed the character, created more space, and placed another dot. The dots on the left and right-hand sides define a sort of horizontal bounding for the character. For the majority of characters, it is only necessary to place this bounding marker on the right in order to force the renderer to render empty space between the character and the marker.

In short, all characters are stretched or compressed horizontally to fit the width of the original characters plus the spacing around them. This has some unusual side effects for characters originally 1 pixel wide. Since the spacing between characters is also 1 pixel a character like a period, which is virtually the same in all character sets, is doubled in width and made to be more like a small dash "_" shaped like a rugby ball.

While each character is compressed or stretched horizontally on an individual basis to match character placement in the original game, this is not the case in the vertical. The entire character set is compressed so that the tallest character does not exceed the height of the maximum character height in classic Daggerfall. This, again, creates unexpected side effects. CapHeight and winAscent in classic Daggerfall were equivalent. This means that no character was taller than a capital letter. In modern fonts, this is almost never the case. In these fonts, the winAscent or maximum possible character height is about the same as the winDescent (the lowest possible point on a character) is below the baseline. This allows for the placement of accent marks above capital letters. As a result of this, SDF fonts are squished to allow characters that are likely never to be rendered, to be rendered at a height determined by the height of the capital letters in Classic. The upshot of this is that just about any modern font will be shortened by 10-20%.

As it happens this is what has happened to my font because I included international capital characters. This currently leaves three choices: Deal with the fact that an SDF font with ascendents above CapHeight will be shortened, Edit fonts to remove any marks above the CapHeight, Squish any characters with ascenders down to CapHeight.

In a perfect world, the mean maximum height of capital letters A-Z of an SDF font (discounting small bits that may venture into the ascendent region) should match the CapHeight in Classic. Ascendant characters should be allowed to render above the CapHeight/winAscent defined in classic as this is unlikely to cause any real problems. Line spacing in Daggerfall in more than sufficient to prevent problems.

For those of you who would like to try out the font I have created, I am including it below. For those of you who would like to know more about the technical aspects of fonts and the terminology I have been using, I am including this link. Note that I have been using the term "character" rather than the more proper term "glyph" to avoid confusion. At some point in the near future, I will upload a font (possibly two) without ascenders above the CapHeight line.

To install the font copy it to ..\DaggerFall Unity\DaggerfallUnity_Data\StreamingAssets\Fonts. You may wish to rename the existing FONT0003-SDF.png to FONT0003-SDF.old or back it up elsewhere, so you can switch back. Happy Fonting.

Edit: One of the problems I ran into while trying to make the Daggerfont size correctly was that no matter what I did it would never render at the full height. My theory is that the SDF bounding box is exactly the same size as the original classic font. Since the SDF Fonts render with antialiased edges there is a sort of halo around each character. This is why there appears to be spacing between characters. Image
You can see that the SDF font overruns the spacing area but is still about 4 pixels away from the next character. The fact that characters are not touching is a benefit of a limitation in rendering. Because of this characters are rendered about 4-6 pixels smaller than Classic. Because the baseline is corrected for, all the 4-6 pixels of space is at the top, making SDF fonts a bit shorter. As you can see in the example, the descender on the "p" touches the bounding box but the CapHeight is well above where any characters render.


FONT0003-SDF.zip
(150.08 KiB) Downloaded 251 times
Remember always 'What would Julian Do?'.

User avatar
jayhova
Posts: 923
Joined: Wed Jul 19, 2017 7:54 pm
Contact:

Re: Daggerfont

Post by jayhova »

I haven't talked about this in a while so I will revisit it. While fixing the width of individual characters is probably quite a bugbear.
Spoiler!
Image
It's probably significantly easier to fix the problems with character height. This should be as simple as stretching out the bounding box height to correct for the shortened letters. As this will happen with all character sets there is no need for a json file or any hinting defining the aspect ratio of the character.

A brief overview of SDF fonts and their limitations
As previously stated, having looked at how SDF fonts display in DFU it seems obvious that the bounding box of the characters is slightly bigger than the characters themselves. This is most likely due to the fact that the anti-aliasing occurs in this space. SDF fonts are not like true type or open type fonts in that they are not vectored. They are bit-mapped in such a way that there is a fuzzy area around the font that can be interpreted as a boundary. Because they have no hard edges they have to have padding inside the bounding box. This padding must be great enough so that in the worst case there is enough room to place the lightest possible pixel away from the body of the character when anti-aliasing the edges and maybe a tad more.

The side effects of this are that characters in an SDF font set are distorted to fill the bounding box. Also the characters are shrunk to fit the bounding box. The shrinking means you can to some extent disregard the spacing between characters because the padding means there will always be some space between characters even if the bounding boxes are right next to each other. The issue here is that it will likely not be the right amount of space. This will vary quite dramatically between characters. For the sake of discussion I will express units of measure in pixels as this was how classic did things and modern DFU attempts to emulate that to some extent and certainly attempts to emulate the original spacing. Let's take a character and assume it is 8 pixels wide. The character in classic would then have a box 10 pixels wide by some fixed number high. We get 10 pixels because on either side of that character we have a 1 pixel space. Really in classic this are 3 separate things [space] [character] [space] but 10 total. With SDF fonts the character is stuck in this space and is adjusted to fit width-wise. As it happens this is no too bad. The character stretches from 8 to 10 pixels wide (about a 20% distortion) and then is shrunk to fit in the box, say about 1 pixel for a total of 9 pixels wide. The real problem is that when you take a character that is 1 pixel wide and do the same operation on it, that character can be distorted dramatically because in order to fit the bounding box, the character has to be stretched to fit a box 3 times its width. This means that periods and similar things turn into rugby ball shapes.
Remember always 'What would Julian Do?'.

Post Reply