mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 05:40:59 +00:00
win32u: Choose a smaller ppem to avoid exceeding the requested font height.
When height > 0, CreateFontA/W() should not return a font face exceeding the requested height. For instance, Tahoma has 2049 units of ascent, 423 units of descent and its units per EM square is 2048. When requesting a font 20 pixels in height, ppem = units_per_EM * requested_height / (ascent + descent) = 2048 * 20 / (2049 + 423) = 16.57 ~= 17. When getting the resulting height back from the ppem, resulting_height = (ascent + descent) * ppem / units_per_EM = (2049.0 + 423) * 17 / 2048 = 20.52 ~=21. So it ends up getting a larger font than requested and violates the spec. Fix Nancy Drew: Legend of the Crystal Skull crash at start. Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
This commit is contained in:
parent
821b36e00b
commit
58b477d158
|
@ -4124,7 +4124,6 @@ static void test_GetTextMetrics(void)
|
|||
old_hf = SelectObject(hdc, hf);
|
||||
ret = GetTextMetricsA(hdc, &tm);
|
||||
ok(ret, "GetTextMetricsA failed, error %lu\n", GetLastError());
|
||||
todo_wine
|
||||
ok(tm.tmHeight <= 20, "Got unexpected tmHeight %ld\n", tm.tmHeight);
|
||||
SelectObject(hdc, old_hf);
|
||||
DeleteObject(hf);
|
||||
|
|
|
@ -1927,10 +1927,18 @@ static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
|
|||
|
||||
if(height > 0) {
|
||||
USHORT windescent = get_fixed_windescent(pOS2->usWinDescent);
|
||||
LONG units;
|
||||
|
||||
if(pOS2->usWinAscent + windescent == 0)
|
||||
ppem = pFT_MulDiv(ft_face->units_per_EM, height, pHori->Ascender - pHori->Descender);
|
||||
units = pHori->Ascender - pHori->Descender;
|
||||
else
|
||||
ppem = pFT_MulDiv(ft_face->units_per_EM, height, pOS2->usWinAscent + windescent);
|
||||
units = pOS2->usWinAscent + windescent;
|
||||
ppem = pFT_MulDiv(ft_face->units_per_EM, height, units);
|
||||
|
||||
/* If rounding ends up getting a font exceeding height, choose a smaller ppem */
|
||||
if(ppem > 1 && pFT_MulDiv(units, ppem, ft_face->units_per_EM) > height)
|
||||
--ppem;
|
||||
|
||||
if(ppem > MAX_PPEM) {
|
||||
WARN("Ignoring too large height %d, ppem %d\n", height, ppem);
|
||||
ppem = 1;
|
||||
|
|
Loading…
Reference in a new issue