I *need* non-antialiased text


#1

To render to a small monochrome LCD, I absolutely need text that is small and readable. I don’t expect Jules to act on the multitude of gripes from his users on this issue, but can anyone suggest a way to get around the antialiasing of glyphs that won’t require too much work? Does the current version of Juce support bitmap based fonts?


#2

use small fonts and try at different fractional heights to get the correct results. i use Silkscreen or Proggytiny and they display with no antialias at all (at fractional sizes tho). Experiment with the font page in the juce demo.


#3

Hmph… yes some fonts look better than others, but they all antialias even at fractional sizes, which is unacceptable for a 1-bit display. Please tell me which font/size combo exhibits zero antialiasing.


#4

Amiga Topaz at 11pt is what I used in Vex, I think. It takes some tinkering with the look and feel to get all the widgets to respect it, but you can make it work.

Edit:
Make that 9pt. I just noticed that the source is online here:
http://svn.jacklab.net/listing.php?repname=eXT2&path=%2Fvstplugins%2Fvex%2Fsrc%2F&rev=0&sc=0

If you look at myLookAndFeel.h/cpp and topaz.h/cpp in the vex tree, you’ll get the idea.

Edit 2:
And if you look at this screeny:

You can see the comboBoxes in Vex’s arp. The knob labels are a part of the background though.


#5

the optimal font-heigth for silkscreen is 8.405f


#6

and don’t use Justification::centred, otherwise even with the hand tuned magical font size you will have all your glyphs half-way between pixels


#7

Multiple sizes are required. I guess I have to come up with a bitmap font renderer :shock:


#8

yep. you culd use the good bmfont made by Andreas to stick fonts togheter. It uses a single bitmap and a char2index map for know where the letter you search is inside the bitmap, easy and effective (cause it reduces the overall bitmap size this way)…


#9

Looks cool, I’ll use that if I try to generalize the bitmap font support in juce (and hopefully jules might consider integrating it). Although I don’t know when that will be. I think he should consider it anyway, it’s not hard to do and will make a lot of people happy…

For a quick solution I just printed each ascii symbol starting at 32 to the osx terminal, set a few sizes, took a few screenshots, made some ‘filmstrip’ pngs, and hacked in a few lines of code to juce_GlyphArrangement.cpp. It’s pretty liberating not to have to look as those furry little letters finally!


#10

Hi Rock. i’m currently tackling the same problem - selecting proper fonts for GUI-widgets. i looked at your sourcecode and in the files topaz.h/cpp and i see this “Autogenerated binary data file” comment. well and good - but how do i generate these files? i thought it would be in the jucer’s resources page (i tried adding ttf files as resources), but it does not seem to support that


#11

ah solved - it’s the binary builder. …oh how i love command-line applications - not. :lol: would be really handy and make sense to have that in the jucer


#12

Hi guys,

I am also dealing with the same problem now (need for nonantialiased text) and I’m trying to use the same solution as with Topaz font, but I can’t understand - what should be encoded in binary file? I’ve tried to encode ttf file with binarybuilder and it doesn’t work (although it works with topaz sources). From the sources I see, that it needs some typeface stream, but what this stream is actually?


#13

It’s the typeface stuff that must be stored (which is itself built from the ttf).
Here is what I used to use for that (the ttf file need to be installed on the mac/win computer you use to build the typeface file):

[code]#include
#include
#include <juce.h>

#define NPERLINE 32

int main (int argc, char* argv[]) {
initialiseJuce_NonGUI();
String fontname;

if (argc <= 1) fontname = T(“Silkscreen”);
else fontname = String::fromUTF8((uint8*)argv[1]);

Font fn(fontname, 9.0, Font::plain);
Typeface *tf = fn.getTypeface();
if (!tf) {
std::cerr << “font not found”;
return 1;
}
std::cerr << "name: " << tf->getName().toUTF8() << “\n”;
std::cerr << "ascent: " << tf->getAscent() << “\n”;
for (int i=0; i < 32768; ++i)
tf->getGlyph(i);

{
MemoryOutputStream memout;
tf->serialise(memout);
memout.flush();

printf("/* generated from font %s */\n", fontname.toUTF8());
printf("const unsigned char %s[] = \n", (argc > 2 ? argv[2] : "__DATA__"));
bool finished = false;
unsigned pos = 0;
while (true) {
  int n = NPERLINE; if (pos + n > memout.getDataSize()) n = memout.getDataSize() - pos;
  printf("\t\"");
  for (unsigned i=0; i < n; ++i) {
    printf("\\x%02x", (unsigned char)(memout.getData()[pos++]));
  }
  printf("\"");
  if (pos == memout.getDataSize()) break;
  printf("\n");
}
printf(";\n");

}

shutdownJuce_NonGUI();
return 0;
}
[/code]


#14

Thanks for the code.

I noticed that nonantialiasing happens only with certain sizes and with certain fonts. Can anybody advise what this issue depends on? Do I need to use specially prepared fonts which have pixel-based sizes inside or something like that?


#15

Oh, seems like it’s not actual anymore - I’ve found some cool pixel font for my needs. Thanks.


#16

[quote=“aquarium”]Thanks for the code.

I noticed that nonantialiasing happens only with certain sizes and with certain fonts. Can anybody advise what this issue depends on? Do I need to use specially prepared fonts which have pixel-based sizes inside or something like that?[/quote]

when using pixel fonts you first need to find the size at which it will work correctly (sometime with points/pixel conversion you end up with odd sizes lik 10.01 for an 8px font)

you also need to stay away from Justification::centred and be careful with widgets that might resize the text’s width or height like Label, TextButton…etc


#17

[quote=“asomers”]
For a quick solution I just printed each ascii symbol starting at 32 to the osx terminal, set a few sizes, took a few screenshots, made some ‘filmstrip’ pngs, and hacked in a few lines of code to juce_GlyphArrangement.cpp. It’s pretty liberating not to have to look as those furry little letters finally![/quote]

Sorry to dig up an old thread, but I think it might be helpful if someone comes along with this issue again (im sure it will happen!).

I realized that my last post was the above rather hacky and inflexible solution. As it went, I needed something much more general, so I patched the GlyphArrangement class to use FreeType when antialiasing is unwanted. Freetype allows you produce monochrome bitmap text (using any font) and provides all the necessary metrics info to hook into the normal flow of Juce’s glyph layout stuff. So if this is something you need, a day’s hacking will get the job done! :twisted:


#18

Really interesting, can you post some code?


#19

As long as we’re hopping on an old thread, I would also love to be able to use unaliased text for small font sizes.

I’ve got an app that uses a custom font for non-text symbols, a font that has a bitmap representation at a fixed, small size (12-15 pt). When rendered in juce, the text is all grey…


#20

I really can’t for legal reasons. I’ll be glad to post small snippets and answer questions though if you try this and run into a problem.

The basic idea is to instantiate freetype in the GlyphArrangement class and use it in the draw routine as it loops through the glyph list, bypassing the glyph’s own draw method. The tutorial for freetype explains how to have freetype render a 1-bit bitmap for your desired glyph.

walking through the 1-bit buffer was actually kind of tricky. You have to do it and just call g.setPixel for as many rows and colums as the ft bitmap has. The origin will be obtained from juce’s notion of glyph placement.

As an optimization, I cache a mapping of font->font size->glyph->bitmap as new glyphs are encountered.

I would LOVE to spend the time to neatly integrate this into Juce and post my versions of the file, but time does not permit. My reason for bringing this issue up in the first place was to inform you all that Freetype seems to be the path of least resistance.