Oblique glyphs not completely shown: clipped at xAdvance
BillyDonahue opened this issue · comments
For oblique glyphs, the xAdvance can be to the left of the right side of the glyph's bitmap bounding box. I'm including a test example which is just the SOLIDUS glyph from the FreeMonoBoldOblique24pt7b font. Clicking on the "+xAdv" input element of the Customizer page will reveal more of the glyph bitmap. But then the xAdv is being incorrectly set.
(I have my own diagnostic scripts for annotating the GFXfonts which I'm using to draw the bitmaps inline in the headers, as shown).
const uint8_t FreeMonoBoldOblique24pt7bBitmaps[] PROGMEM = {
0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x00,
0x00,0x01,0xF0,0x00,0x00,0x3E,0x00,0x00,
0x03,0xE0,0x00,0x00,0x7C,0x00,0x00,0x0F,
0x80,0x00,0x00,0xF8,0x00,0x00,0x1F,0x00,
0x00,0x03,0xE0,0x00,0x00,0x3E,0x00,0x00,
0x07,0xC0,0x00,0x00,0xF8,0x00,0x00,0x1F,
0x80,0x00,0x01,0xF0,0x00,0x00,0x3E,0x00,
0x00,0x07,0xE0,0x00,0x00,0x7C,0x00,0x00,
0x0F,0x80,0x00,0x01,0xF8,0x00,0x00,0x1F,
0x00,0x00,0x03,0xE0,0x00,0x00,0x7C,0x00,
0x00,0x07,0xC0,0x00,0x00,0xF8,0x00,0x00,
0x1F,0x00,0x00,0x01,0xF0,0x00,0x00,0x3E,
0x00,0x00,0x07,0xC0,0x00,0x00,0xFC,0x00,
0x00,0x0F,0x80,0x00,0x01,0xF0,0x00,0x00,
0x3F,0x00,0x00,0x03,0xE0,0x00,0x00,0x7C,
0x00,0x00,0x07,0xC0,0x00,0x00,0xF8,0x00,
0x00,0x07,0x00,0x00,0x00, // 0x2F '/' (28 x 38) @(3,-32) +28
// [ .........................**.]
// [ ........................****]
// [ .......................*****]
// [ ......................*****.]
// [ ......................*****.]
// [ .....................*****..]
// [ ....................*****...]
// [ ....................*****...]
// [ ...................*****....]
// [ ..................*****.....]
// [ ..................*****.....]
// [ .................*****......]
// [ ................*****.......]
// [ ...............******.......]
// [ ...............*****........]
// [ ..............*****.........]
// [ .............******.........]
// [ .............*****..........]
// [ ............*****...........]
// [ ...........******...........]
// [ ...........*****............]
// [ ..........*****.............]
// [ .........*****..............]
// [ .........*****..............]
// [ ........*****...............]
// [ .......*****................]
// [ .......*****................]
// [ ......*****.................]
// [ .....*****..................]
// [ ....******..................]
// [ ....*****...................]
// [ ...*****....................]
// [0 ..******.................>..]
// [ ..*****.....................]
// [ .*****......................]
// [ .*****......................]
// [ *****.......................]
// [ .***........................]
};
const GFXglyph FreeMonoBoldOblique24pt7bGlyphs[] PROGMEM = {
{0, 28, 38, 28, 3, -32} // 0x2F '/':SOLIDUS
};
const GFXfont FreeMonoBoldOblique24pt7b PROGMEM = {
(uint8_t *)FreeMonoBoldOblique24pt7bBitmaps,
(GFXglyph *)FreeMonoBoldOblique24pt7bGlyphs,
0x2F, 0x2F, 47
};
It seems that the GFXGlyph definition is not right then, it should be :
const GFXglyph FreeMonoBoldOblique24pt7bGlyphs[] PROGMEM = {
{0, 28, 38, 31, 3, -32} // 0x2F '/':SOLIDUS
};
No ?
Or should we add the xOff
automatically to the adv
param (so as to make 31 ?). Is it what your diagnostic tool does ? I'm curious ... :)
No, the glyph definition is correct.
The fields are {bo,w,h,xa,xo,yo}.
{0, 28, 38, 28, 3, -32}
not
{0, 28, 38, 31, 3, -32}
It's an oblique font, so all the glyphs are slanted to the right, and adjacent glyphs can have overlapping bounding boxes. Because this glyph's xAdvance doesn't escape its bounding box, the following glyph will be tucked a little under this one. Some glyphs even have negative xOffset, so they can draw to the left of the origin and reach into their predecessor's box. It's all supposed to be anticipated by the font designer. They shouldn't overwrite each other's pixels as long as all the clustered chars are from the same consistent font.
My diagnostic tool calculates a rectangle that encloses the bitmap's edges, the origin, and the (xAdvance,0) point.
I can just show it to you. This thing will read a font header and spit it back out as another valid font header, but with comments containing all the glyph drawings and metadata comments, and with the glyph bitmap bytes separated out.
The annotated fonts look like this:
https://github.com/BillyDonahue/Adafruit-GFX-Library/tree/34adb94739acc1a4f74c885be9a899562bfbca05/fontconvert/Fonts.annotated.orig
Ok, if I understand correctly, I should replace xadvance
in this line :
https://github.com/tchapi/Adafruit-GFX-Font-Customiser/blob/master/index.html#L128
with xadvance + xoffset
— wdyt ?
I don't think that's right. (My JS sux, sorry)
you need the union of 2 boxes, so it's more like:
var box_l = Math.min(0, xo);
var box_t = Math.min(0, yo);
var box_r = Math.max(xa, xo+w);
var box_b = Math.max(ya, yo+h);
for (var px_y = box_t; px_y <= box_b; ++px_y) {
var grid_y = i - box_t;
for (var px_x = box_l; px_x <= box_r ; ++px_x) {
var grid_x = px_x - box_l;
// paint grid cell (grid_x, grid_y) as logical pixel (px_x, px_y)
}
}
Hmm. Except for the min/max calculations that I had missed, I think your loop is somehow equivalent to mine. I've created a branch with new modifications including yours: https://github.com/tchapi/Adafruit-GFX-Font-Customiser/tree/feature/xoffset
The forward / backward overlapping pixels are red-ish so it's easy to spot them. I'm always displaying xadvance + xoffset
pixels for the characters.
As for the other issue, if you can have a look, that'd be great !
Thanks again !
The bounds are still not right, I think.
Here try this:
https://billydonahue.github.io/Adafruit-GFX-Font-Customiser/
And feed it this test file:
https://billydonahue.github.io/Adafruit-GFX-Font-Customiser/test/BangOblique24pt7b.h
src is on branch:
https://github.com/BillyDonahue/Adafruit-GFX-Font-Customiser/tree/mark_points_fix_bounds
The red paint is cool. One problem I had with it though, is that you can't see the xadvance point unless you cross it. So I also added a little marker on the origin and the xadvance point (which will be the next character's origin.
Ok, good, I get it. It was close. Thanks so much !
Very good idea to add the two limits, I'll just change it to lines instead of cell borders, so as to keep the table cell widths consistent.
Is it ok for you if I put your name and Github profile link in the readme file, under "Contributors" ?