|
From: | David Bevan |
Subject: | Re: [Devel] Getting accurate advances |
Date: | Mon, 17 Nov 2003 09:23:50 +0000 |
User-agent: | Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20030208 Netscape/7.02 |
Werner LEMBERG wrote:
So I tried linearHoriAdvance which was better but, despite what the tutorial says, still not accurate enough - because it is calculated using x_ppem (ftobjs.c line 554) which has been rounded to the nearest pixel (x_scale is similarly rounded). The cumulative error can be several mm with a text string of 15cm or so.This is definitely a bug.Perhaps the tutorial could be changed so that it doesn't claim that linearHoriAdvance is accurate to 1/65536th of a pixel - or, better, linearHoriAdvance could be calculated accurately (I can't see how to do this without storing an additional unrounded value in a new field).The necessary data is already available in metrics->x_scale, with sufficient accuracy I think. We have to say slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, metrics->x_scale, 64 ); instead of slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, (FT_Long)metrics->x_ppem << 16, EM ); in function FT_Load_Glyph. Please test. If this works as expected I'll apply the change to the CVS.
As I mentioned in my first paragraph, metrics->x_scale is also rounded - in fact it's simply 2048 * metrics->x_ppem with font I'm using, so the rsults are the same as using metrics->x_ppem.
The relevant code is from line 2019 in ftobjs.c: dim_x = ( ( char_width * horz_resolution + (36+32*72) ) / 72 ) & -64; metrics->x_ppem = (FT_UShort)( dim_x >> 6 ); metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );Note that the rounding occurs in the calculation for dim_x. Changing this to:
dim_x = ( char_width * horz_resolution + 36 ) / 72; metrics->x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 ); metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );produces the correct advances when used with your suggested change - *but* this changes the x_scale value used throughout all resizing, rendering, hinting, etc. Is this change correct or dangerous? Has the x_scale value always been wrong or does it need to be rounded for some reason? Since I don't know the answer to these questions, I am very reluctant to recommend the above change. (A parallel change would also be necessary for y_scale and linearVertAdvance).
Thanks. David %^> -- ________________________________________________________ David Bevan, Emtex Ltd. Emtex House, Station Road, Kings Langley, Herts. WD4 8LH England Tel: +44 (0)1923 270882 E-mail: address@hidden Web: www.emtex.com
[Prev in Thread] | Current Thread | [Next in Thread] |