freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft] Metrics for pre-rendered glyphs - am I doing this right?


From: Phil Endecott
Subject: [ft] Metrics for pre-rendered glyphs - am I doing this right?
Date: Sat, 27 Sep 2014 16:30:30 +0100

Dear List,

Thanks for helping with my earlier question.  I'm now going to 
describe what I'm doing to check if I've got it right - now that 
I don't have obvious off-by-one errors, it's hard to spot the 
more subtle mistakes even with a magnifier!

I have an OpenGL application in which I use FreeType to pre-render 
glyphs into a texture; when I want to draw text onto the display I 
use OpenGL to copy glyph rectangles from that texture to rectangles 
on the display.

In the simplest version, for each glyph I store the bitmap_left, 
bitmap_top and linearHoriAdvance values (all in 64ths of a pixel, 
though bitmap_left and bitmap_top are always whole numbers of pixels).  
Then drawing algorithm is (pseudo-code):

int x = x0, y = y0;  // in 64ths of a pixel
for each glyph {
  find the bitmap in the texture
  copy it to the screen with its bottom-left corner at
  ( round((x+bitmap_left)/64), round((y+bitmap_top-bitmap_height)/64) )
  x += linearHoriAdvance
  x += kerning  
}

Does that look reasonable?

For smaller font sizes, I am attempting to do sub-pixel horizontal 
positioning.  For each glyph, I store 2 or 4 (or more) bitmaps with 
different horizontal offsets.  I render these by calling 
FT_Set_Transform() first, and I then change the value that I store 
as the bitmap_left.  So if the actual bitmap_left is, say, 2 pixels, 
for the copy of the glyph that is offset by half a pixel I store a 
bitmap_left value of 1.5 (i.e. 96 in 64ths).

Then, when drawing, I consider each of the bitmaps for the glph and 
choose the best one:

int x = x0, y = y0;  // in 64ths of a pixel
for each glyph {
  find the bitmaps in the texture
  for each bitmap {
    ideal_x_pos = x + bitmap_left
    actual_x_pos = round to nearest multiple of 64 (ideal_x_pos)
    error = abs(actual_x_pos - ideal_x_pos)
  }
  select the bitmap with the smallest error
  copy it to the screen with its bottom-left corner at
  ( round((x+bitmap_left)/64), round((y+bitmap_top-bitmap_height)/64) )
  x += linearHoriAdvance
  x += kerning  
}

As I said, this seems to give reasonable results but I'm not convinced 
that I would notice a subtle error, even when looking at the screen 
through a magnifier.  So if anyone can spot any potential problems, 
please let me know!


Thanks,  Phil.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]