Font clarity in MonoGame?

I’m reproducing this box.
Font Clarity

When I did this originally in WPF the font is very crisp and clear. When I’ve redone it in MonoGame the font is blurry. The kearning (space between letters) seems off, too.This seems to be the case with all the fonts that I’m importing and using.

Anybody else ever encounter this problem and know the solution?

Edit: it looks like this is a known problem without a solution. It seems that it was reported 5 years ago but there’s still no fix. Anybody?

Fonts are often a pain and I’ve had some issues with fonts being blurry when I don’t want them to be (see here: SpriteFont rendering - Can't seem to disable smoothing), but I think that’s a different case that you’re experiencing entirely. That’s way more smoothing on your font than I would expect.

So I’ll ask the usual questions…

  • Are you scaling this text in any way or is this the default size?
  • What’s your SamplerState set to in the SpriteBatch that draws the text?
  • Is your font really small? Try a larger size just to see if the blur goes away.
  • Try using another font with all the same settings as the font you’re using, do you see the same issue?

You might want to take a browse through that thread I posted though. I had some success switching over my font rendering to using MonoGame.Extended’s BitmapFont. It allowed me to get the crisp, pixelated look I was striving for in the prototype I was working on.

First off, I really want to thank you for helping me through this. I have made the commitment that my new game (3 years late!) will ship with MonoGame; so come hell or high water, I’m going with MonoGame. Unfortunately, fonts play a really big role. These are licensed TrueType fonts from WaldenFonts. I don’t think they’re a problem (of course, I could be wrong).

I don’t know anything about scaling a font. Here’s the spritefont for this example:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">

    <!--
    Modify this string to change the font that will be imported.
    -->
    <FontName>Klabasto</FontName>

    <!--
    Size is a float value, measured in points. Modify this value to change
    the size of the font.
    -->
    <Size>14</Size>

    <!--
    Spacing is a float value, measured in pixels. Modify this value to change
    the amount of spacing in between characters.
    -->
    <Spacing>0</Spacing>

    <!--
    UseKerning controls the layout of the font. If this value is true, kerning information
    will be used when placing characters.
    -->
    <UseKerning>true</UseKerning>

    <!--
    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
    and "Bold, Italic", and are case sensitive.
    -->
    <Style>Regular</Style>

    <!--
    If you uncomment this line, the default character will be substituted if you draw
    or measure text that contains characters which were not included in the font.
    -->
    <!-- <DefaultCharacter>*</DefaultCharacter> -->

    <!--
    CharacterRegions control what letters are available in the font. Every
    character from Start to End will be built and made available for drawing. The
    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
    character set. The characters are ordered according to the Unicode standard.
    See the documentation for more information.
    -->
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#255;</End>
      </CharacterRegion>
    </CharacterRegions>
  </Asset>
</XnaContent>

And this is the call:

Vector2 width = UnitInfoNameFont.MeasureString(tString);
spriteBatch.DrawString(UnitInfoNameFont, tString, new Vector2(x + 108 - (width.X / 2), y - (width.Y / 2) + 28), Color.Black);

So, I’m not scaling or anything. The font appears fine elsewhere (a bit larger):
Klabasto

So, how would I make a really large font and scale it? That may be a solution if I knew how to do it.

By scaling, I meant drawing it elsewhere using any kind of scaling techniques. So like, a SpriteBatch.Begin call with a matrix that has a scale transform applied to it. Or drawing the font to a RenderTarget2D and then drawing it as a texture that is larger, or smaller, than it would otherwise appear to be.

Your DrawString call you posted above is pretty straightforward and there is no evidence of scaling there (because you can’t scale with that call :D); however…

This has be wondering how the font appears larger elsewhere. The .spritefont file you posted above has its size set to 14. To draw it larger, you would either need to scale it (somehow) or have another .spritefont file with a larger size set. I suspect the latter but I figure I should maybe confirm…

Oh! By “a bit larger” do you just mean you zoomed it in? Do you mean that this is the same font, same size, same everything, but just drawn in another place in your application? If that, check the position you’re drawing at. In fact, looking at the calculation you’re making for your position, it includes a division and a measure string. I suspect you’re landing on a non-integer value (confirm via breakpoint or output). Try sticking an int cast in front.

So…

Vector2 width = UnitInfoNameFont.MeasureString(tString);
spriteBatch.DrawString(
  UnitInfoNameFont, tString,
  new Vector2(
    (int)(x + 108 - (width.X / 2f)),
    (int)(y - (width.Y / 2f) + 28)
  ),
  Color.Black
);

See if that makes a difference?

Nope. Sorry. I use different Spritefonts for different size fonts, so size ‘22’ was set in a different spritefont that drew the word ‘SCENARIO’ in the above image.

I see! Ok cool, then that does suggest you might have something in common with the issue I was experiencing, where smaller fonts render with more smoothing than you might expect.

I would suggest breaking this out into a separate project to test, but render some test strings in both sizes of fonts with a regular MonoGame SpriteFont. Then do the same (or just render it right next to it) using MonoGame.Extended.BitmapFonts.BitmapFont and compare the results.

If you’re experiencing the same issue I was, you should see a marked improvement with BitmapFont. Here’s the doc…

I think I ran into this once when using certain fonts some years ago. Unfortunately, I don’t recall how I fixed it. Just to rule it out as a factor, I would try changing your content builder settings to not use compression. On both the top MGCB object level, and on the actual spritefonts (which are set to “Compressed” by default I believe, set them to “Color” instead).

One other tip would be put the actual .ttf file alongside your .spritefont file, and reference that file directly (i.e. “theExactFile.ttf”). By default MGCB will look at the font you’ve defined and ask Windows to pass back the installed font that matches that name, but you can be certain it is using the exact correct .ttf using this method (again, probably won’t change anything, but just to rule it out).

Improved a little with ‘Color’. But I only set Color in the MGCB. Where is the other place to set it?

The Color/Compressed TextureFormat setting is for the spritefont within the MGCB, but the MGCB also has settings that apply to everything (Platform/Profile/etc), which includes compression settings.

image

I’m really sorry… how do I get to this screen?

The screenshot is of the MonoGame Content Builder Editor. You can also edit the file directly with any text editor.

Sorry, more confusion. I have MGCB installed in Visual Studio 2020:

MGCB

All I can do is double-click on it which opens up:

Note, the spritefont is UnitInfoNameFont and is set to Color (not Compressed). And lastly, there’s the XML spritefont itself:

<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
  <Asset Type="Graphics:FontDescription">

    <!--
    Modify this string to change the font that will be imported.
    -->
    <FontName>Klabasto</FontName>

    <!--
    Size is a float value, measured in points. Modify this value to change
    the size of the font.
    -->
    <Size>14</Size>

    <!--
    Spacing is a float value, measured in pixels. Modify this value to change
    the amount of spacing in between characters.
    -->
    <Spacing>0</Spacing>

    <!--
    UseKerning controls the layout of the font. If this value is true, kerning information
    will be used when placing characters.
    -->
    <UseKerning>true</UseKerning>

    <!--
    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
    and "Bold, Italic", and are case sensitive.
    -->
    <Style>Regular</Style>

    <!--
    If you uncomment this line, the default character will be substituted if you draw
    or measure text that contains characters which were not included in the font.
    -->
    <!-- <DefaultCharacter>*</DefaultCharacter> -->

    <!--
    CharacterRegions control what letters are available in the font. Every
    character from Start to End will be built and made available for drawing. The
    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
    character set. The characters are ordered according to the Unicode standard.
    See the documentation for more information.
    -->
    <CharacterRegions>
      <CharacterRegion>
        <Start>&#32;</Start>
        <End>&#255;</End>
      </CharacterRegion>
    </CharacterRegions>
  </Asset>
</XnaContent>

That’s everything I got. How do I get to the screen you posted? From MGCB? I can’t find any way to get there.

Thanks for all the help!

Scroll to the top of this:

Yeah. Compress is set to false there, too. A little bit of improvement. But, then I had an idea. The same font, Klabasto, is used for ‘SCENARIO’ and it looks fine. In fact all the other fonts look good.

The solution is just make the smallest font BIGGER. Yeah, the ‘Unit Info Box’ will have to get bigger. So what. We know the bigger the font the better it looks. Let’s stay with what looks good.

BTW, that image, above, is screen shot of my game. I think I started it 2 or 3 weeks ago in MonoGame. (True, but a lot of other work was done earlier and I’m importing lots of libraries and data files.)

2 Likes

1 off the methods for Spritebatch.Drawstring has an overload for a float scale to scale the output.

Make your font bigger and use a float of 0.5f to scale it down and see if that makes a difference

Do you have an example of the overload for scale (float) for Spritbatch.Drawstring()?

In the meantime, I just decided to make the font BIGGER:
Much Better
Okay. I’ll make the box bigger, now. So what…

MonoGame rocks! Did you see how fast I put this together?

Im not at a computer at the moment but you could use this one

public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth)

All the overloads are here for drawstring

https://docs.monogame.net/api/Microsoft.Xna.Framework.Graphics.SpriteBatch.html

Edit
Oops that one has scale as a vector (in case you wanted to stretch it) there is one underneath it on that link that has a float for scale. Eg 0.5f

This ties into what I said above. Try using MonoGame.Extended.BitmapFonts.BitmapFont instead. It’s a super easy port. I think you might be able to have clean font rendering at the smaller font sizes you want.

I think you’ve encountered the same issue I had in my post (which is 3.5 years old) and the problem was with how MonoGame generated the sprites for the font.

Its worth a try to try make the font bigger and scale it down on the drawing.

Unrelated Ezra, i read your link to in your 3rd post regarding optimal point of attack and found it very interesting.

Thanks for all the help on this. I goosed this type up a little bit, wrote some code to break the line and center justify it and it looks fine:
Bigger type
(this is ‘18 pt’).

I’ve been working on General Staff for almost 5 years and I need to get it into beta this year. I’m going to keep pushing on. It’s pretty easy with MonoGame.

Quick question: how do I make a circle? Is there a circle drawing method, or did somebody make a library? Need to draw some big hollow circles (range for units).

Thanks for all the help!

  • Ezra
1 Like